* src/SDCCglobl.h: ensure that PATH_MAX >= 2048 to guarantee
[fw/sdcc] / src / pic16 / genarith.c
1 /*-------------------------------------------------------------------------
2
3  genarith.c - source file for code generation - arithmetic 
4   
5   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
7   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
8   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
9   PIC16 port   -  Martin Dubuc m.dubuc@rogers.com (2002)
10   
11   This program is free software; you can redistribute it and/or modify it
12   under the terms of the GNU General Public License as published by the
13   Free Software Foundation; either version 2, or (at your option) any
14   later version.
15   
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20   
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24   
25   In other words, you are welcome to use, share and improve this program.
26   You are forbidden to forbid anyone else to use, share and improve
27   what you give them.   Help stamp out software-hoarding!
28   
29   Notes:
30   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
31                 Made everything static
32 -------------------------------------------------------------------------*/
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include "SDCCglobl.h"
39 #include "newalloc.h"
40
41 #if defined(_MSC_VER) && (_MSC_VER < 1300)
42 #define __FUNCTION__            __FILE__
43 #endif
44
45 #include "common.h"
46 #include "SDCCpeeph.h"
47 #include "ralloc.h"
48 #include "pcode.h"
49 #include "gen.h"
50
51 #if 1
52 #define pic16_emitcode  DEBUGpic16_emitcode
53 #endif
54
55 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
56 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
57 void pic16_emitpcomment(char *, ...);
58 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
59 const char *pic16_AopType(short type)
60 {
61   switch(type) {
62   case AOP_LIT:         return "AOP_LIT";
63   case AOP_REG:         return "AOP_REG";
64   case AOP_DIR:         return "AOP_DIR";
65   case AOP_DPTR:        return "AOP_DPTR";
66   case AOP_DPTR2:       return "AOP_DPTR2";
67   case AOP_FSR0:        return "AOP_FSR0";
68   case AOP_FSR2:        return "AOP_FSR2";
69   case AOP_R0:          return "AOP_R0";
70   case AOP_R1:          return "AOP_R1";
71   case AOP_STK:         return "AOP_STK";
72   case AOP_IMMD:        return "AOP_IMMD";
73   case AOP_STR:         return "AOP_STR";
74   case AOP_CRY:         return "AOP_CRY";
75   case AOP_ACC:         return "AOP_ACC";
76   case AOP_PCODE:       return "AOP_PCODE";
77   case AOP_STA:         return "AOP_STA";
78   }
79
80   return "BAD TYPE";
81 }
82
83 const char *pic16_pCodeOpType(pCodeOp *pcop)
84 {
85
86   if(pcop) {
87
88     switch(pcop->type) {
89
90     case PO_NONE:               return "PO_NONE";
91     case PO_W:                  return  "PO_W";
92     case PO_WREG:               return  "PO_WREG";
93     case PO_STATUS:             return  "PO_STATUS";
94     case PO_BSR:                return  "PO_BSR";
95     case PO_FSR0:               return  "PO_FSR0";
96     case PO_INDF0:              return  "PO_INDF0";
97     case PO_INTCON:             return  "PO_INTCON";
98     case PO_GPR_REGISTER:       return  "PO_GPR_REGISTER";
99     case PO_GPR_BIT:            return  "PO_GPR_BIT";
100     case PO_GPR_TEMP:           return  "PO_GPR_TEMP";
101     case PO_SFR_REGISTER:       return  "PO_SFR_REGISTER";
102     case PO_PCL:                return  "PO_PCL";
103     case PO_PCLATH:             return  "PO_PCLATH";
104     case PO_PCLATU:             return  "PO_PCLATU";
105     case PO_PRODL:              return  "PO_PRODL";
106     case PO_PRODH:              return  "PO_PRODH";
107     case PO_LITERAL:            return  "PO_LITERAL";
108     case PO_REL_ADDR:           return "PO_REL_ADDR";
109     case PO_IMMEDIATE:          return  "PO_IMMEDIATE";
110     case PO_DIR:                return  "PO_DIR";
111     case PO_CRY:                return  "PO_CRY";
112     case PO_BIT:                return  "PO_BIT";
113     case PO_STR:                return  "PO_STR";
114     case PO_LABEL:              return  "PO_LABEL";
115     case PO_WILD:               return  "PO_WILD";
116     }
117   }
118
119   return "BAD PO_TYPE";
120 }
121
122 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
123 {
124
125   if(pcop && (pcop->type == PO_GPR_BIT)) {
126
127     switch(PCORB(pcop)->subtype) {
128
129     case PO_NONE:               return "PO_NONE";
130     case PO_W:                  return  "PO_W";
131     case PO_WREG:               return  "PO_WREG";
132     case PO_STATUS:             return  "PO_STATUS";
133     case PO_BSR:                return  "PO_BSR";
134     case PO_FSR0:               return  "PO_FSR0";
135     case PO_INDF0:              return  "PO_INDF0";
136     case PO_INTCON:             return  "PO_INTCON";
137     case PO_GPR_REGISTER:       return  "PO_GPR_REGISTER";
138     case PO_GPR_BIT:            return  "PO_GPR_BIT";
139     case PO_GPR_TEMP:           return  "PO_GPR_TEMP";
140     case PO_SFR_REGISTER:       return  "PO_SFR_REGISTER";
141     case PO_PCL:                return  "PO_PCL";
142     case PO_PCLATH:             return  "PO_PCLATH";
143     case PO_PCLATU:             return  "PO_PCLATU";
144     case PO_PRODL:              return  "PO_PRODL";
145     case PO_PRODH:              return  "PO_PRODH";
146     case PO_LITERAL:            return  "PO_LITERAL";
147     case PO_REL_ADDR:           return "PO_REL_ADDR";
148     case PO_IMMEDIATE:          return  "PO_IMMEDIATE";
149     case PO_DIR:                return  "PO_DIR";
150     case PO_CRY:                return  "PO_CRY";
151     case PO_BIT:                return  "PO_BIT";
152     case PO_STR:                return  "PO_STR";
153     case PO_LABEL:              return  "PO_LABEL";
154     case PO_WILD:               return  "PO_WILD";
155     }
156   }
157
158   return "BAD PO_TYPE";
159 }
160
161 /*-----------------------------------------------------------------*/
162 /* pic16_genPlusIncr :- does addition with increment if possible         */
163 /*-----------------------------------------------------------------*/
164 bool pic16_genPlusIncr (iCode *ic)
165 {
166   unsigned int icount ;
167   unsigned int size = pic16_getDataSize(IC_RESULT(ic));
168
169     FENTRY;
170
171     DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
172                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
173                          pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
174                          pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
175
176     /* will try to generate an increment */
177     /* if the right side is not a literal 
178        we cannot */
179     if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
180         return FALSE ;
181     
182     DEBUGpic16_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
183     /* if the literal value of the right hand side
184        is greater than 2 then it is faster to add */
185     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
186         return FALSE ;
187     
188     /* if increment 16 bits in register */
189     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
190         (icount == 1)) {
191
192       int offset = MSB16;
193
194       pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
195       //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
196
197       while(--size) {
198         emitSKPNC;
199         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
200         //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
201       }
202
203       return TRUE;
204     }
205     
206     DEBUGpic16_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
207     /* if left is in accumulator  - probably a bit operation*/                          // VR - why this is a bit operation?!
208     if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
209         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
210       
211       pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
212       pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
213                AOP(IC_RESULT(ic))->aopu.aop_dir,
214                AOP(IC_RESULT(ic))->aopu.aop_dir);
215       if(icount)
216         pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
217       //pic16_emitcode("xorlw","1");
218       else
219         pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
220       //pic16_emitcode("andlw","1");
221
222       emitSKPZ;
223       pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
224       pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
225                AOP(IC_RESULT(ic))->aopu.aop_dir,
226                AOP(IC_RESULT(ic))->aopu.aop_dir);
227
228       return TRUE;
229     }
230
231
232     /* if the sizes are greater than 1 then we cannot */
233     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
234         AOP_SIZE(IC_LEFT(ic)) > 1   )
235         return FALSE ;
236     
237     /* If we are incrementing the same register by two: */
238
239     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
240         
241       while (icount--) 
242         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
243       //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
244         
245       return TRUE ;
246     }
247     
248     DEBUGpic16_emitcode ("; ","couldn't increment ");
249
250     return FALSE ;
251 }
252
253 /*-----------------------------------------------------------------*/
254 /* pic16_outBitAcc - output a bit in acc                                 */
255 /*-----------------------------------------------------------------*/
256 void pic16_outBitAcc(operand *result)
257 {
258     symbol *tlbl = newiTempLabel(NULL);
259     /* if the result is a bit */
260     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
261
262     assert(0); // not implemented for PIC16?
263
264     if (AOP_TYPE(result) == AOP_CRY){
265         pic16_aopPut(AOP(result),"a",0);
266     }
267     else {
268         pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
269         pic16_emitcode("mov","a,#01");
270         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
271         pic16_outAcc(result);
272     }
273 }
274
275 /*-----------------------------------------------------------------*/
276 /* pic16_genPlusBits - generates code for addition of two bits           */
277 /*-----------------------------------------------------------------*/
278 void pic16_genPlusBits (iCode *ic)
279 {
280   FENTRY;
281
282   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
283                        pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
284                        pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
285                        pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
286   /*
287     The following block of code will add two bits. 
288     Note that it'll even work if the destination is
289     the carry (C in the status register).
290     It won't work if the 'Z' bit is a source or destination.
291   */
292
293   /* If the result is stored in the accumulator (w) */
294   //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
295   switch(AOP_TYPE(IC_RESULT(ic))) {
296   case AOP_ACC:
297     pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
298     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
299     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
300     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
301     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
302
303     pic16_emitcode("clrw","");
304     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
305                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
306                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
307     pic16_emitcode("xorlw","1");
308     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
309                    AOP(IC_LEFT(ic))->aopu.aop_dir,
310                    AOP(IC_LEFT(ic))->aopu.aop_dir);
311     pic16_emitcode("xorlw","1");
312     break;
313   case AOP_REG:
314     pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
315     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
316     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
317     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
318     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
320     break;
321   default:
322     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
323     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
324     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
325     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
327     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
328
329     pic16_emitcode("movlw","(1 << (%s & 7))",
330                    AOP(IC_RESULT(ic))->aopu.aop_dir,
331                    AOP(IC_RESULT(ic))->aopu.aop_dir);
332     pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
333                    AOP(IC_RESULT(ic))->aopu.aop_dir,
334                    AOP(IC_RESULT(ic))->aopu.aop_dir);
335     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
336                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
337                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
338     pic16_emitcode("xorwf","(%s >>3),f",
339                    AOP(IC_RESULT(ic))->aopu.aop_dir);
340     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
341                    AOP(IC_LEFT(ic))->aopu.aop_dir,
342                    AOP(IC_LEFT(ic))->aopu.aop_dir);
343     pic16_emitcode("xorwf","(%s>>3),f",
344                    AOP(IC_RESULT(ic))->aopu.aop_dir);
345     break;
346   }
347
348 }
349
350 #if 0
351 /* This is the original version of this code.
352  *
353  * This is being kept around for reference, 
354  * because I am not entirely sure I got it right...
355  */
356 static void adjustArithmeticResult(iCode *ic)
357 {
358     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
359         AOP_SIZE(IC_LEFT(ic)) == 3   &&
360         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
361         pic16_aopPut(AOP(IC_RESULT(ic)),
362                pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
363                2);
364
365     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
366         AOP_SIZE(IC_RIGHT(ic)) == 3   &&
367         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
368         pic16_aopPut(AOP(IC_RESULT(ic)),
369                pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
370                2);
371     
372     if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
373         AOP_SIZE(IC_LEFT(ic)) < 3    &&
374         AOP_SIZE(IC_RIGHT(ic)) < 3   &&
375         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
376         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
377         char buffer[5];
378         sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
379         pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
380     }
381 }
382 //#else
383 /* This is the pure and virtuous version of this code.
384  * I'm pretty certain it's right, but not enough to toss the old 
385  * code just yet...
386  */
387 static void adjustArithmeticResult(iCode *ic)
388 {
389     if (opIsGptr(IC_RESULT(ic)) &&
390         opIsGptr(IC_LEFT(ic))   &&
391         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
392     {
393         pic16_aopPut(AOP(IC_RESULT(ic)),
394                pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
395                GPTRSIZE - 1);
396     }
397
398     if (opIsGptr(IC_RESULT(ic)) &&
399         opIsGptr(IC_RIGHT(ic))   &&
400         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
401     {
402         pic16_aopPut(AOP(IC_RESULT(ic)),
403                pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
404                GPTRSIZE - 1);
405     }
406
407     if (opIsGptr(IC_RESULT(ic))            &&
408         AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
409         AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
410          !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
411          !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
412          char buffer[5];
413          sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
414          pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
415      }
416 }
417 #endif
418
419 /*-----------------------------------------------------------------*/
420 /* genAddlit - generates code for addition                         */
421 /*-----------------------------------------------------------------*/
422 static void genAddLit2byte (operand *result, int offr, int lit)
423 {
424   FENTRY;
425   
426   switch(lit & 0xff) {
427   case 0:
428     break;
429   case 1:
430     pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
431     break;
432   case 0xff:
433     pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
434     break;
435   default:
436     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
437     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
438   }
439
440 }
441
442 static void emitMOVWF(operand *reg, int offset)
443 {
444   if(!reg)
445     return;
446
447   if (AOP_TYPE(reg) == AOP_ACC) {
448     DEBUGpic16_emitcode ("; ***","%s  %d ignoring mov into W",__FUNCTION__,__LINE__);
449     return;
450   }
451
452   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
453
454 }
455
456 static void genAddLit (iCode *ic, int lit)
457 {
458
459   int size,same;
460   int lo;
461
462   operand *result;
463   operand *left;
464
465     FENTRY;
466
467
468   left = IC_LEFT(ic);
469   result = IC_RESULT(ic);
470   same = pic16_sameRegs(AOP(left), AOP(result));
471   size = pic16_getDataSize(result);
472
473   if(same) {
474
475     /* Handle special cases first */
476     if(size == 1) 
477       genAddLit2byte (result, 0, lit);
478      
479     else if(size == 2) {
480       int hi = 0xff & (lit >> 8);
481       lo = lit & 0xff;
482
483       switch(hi) {
484       case 0: 
485
486         /* lit = 0x00LL */
487         DEBUGpic16_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
488         switch(lo) {
489         case 0:
490           break;
491         case 1:
492           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
493           emitSKPNZ;
494           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
495           break;
496         case 0xff:
497           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
498           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
499           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
500
501           break;
502         default:
503           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
504           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
505           emitSKPNC;
506           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
507
508
509         }
510         break;
511
512       case 1:
513         /* lit = 0x01LL */
514         DEBUGpic16_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
515         switch(lo) {
516         case 0:  /* 0x0100 */
517           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
518           break;
519         case 1:  /* 0x0101  */
520           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
522           emitSKPNZ;
523           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
524           break;
525         case 0xff: /* 0x01ff */
526           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
527           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
528           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
529           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
530           break;
531         default: /* 0x01LL */
532           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
533           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
534           emitSKPNC;
535           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
537         }         
538         break;
539
540       case 0xff:
541         DEBUGpic16_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
542         /* lit = 0xffLL */
543         switch(lo) {
544         case 0:  /* 0xff00 */
545           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
546           break;
547         case 1:  /*0xff01 */
548           pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
549           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
550           break;
551 /*      case 0xff: * 0xffff *
552           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
553           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
554           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
555           break;
556 */
557         default:
558           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
559           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
560           emitSKPC;
561           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
562           
563         }
564
565         break;
566         
567       default:
568         DEBUGpic16_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
569
570         /* lit = 0xHHLL */
571         switch(lo) {
572         case 0:  /* 0xHH00 */
573           genAddLit2byte (result, MSB16, hi);
574           break;
575         case 1:  /* 0xHH01 */
576           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
577           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
578           pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
579           break;
580 /*      case 0xff: * 0xHHff *
581           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
582           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
583           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
584           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
585           break;
586 */      default:  /* 0xHHLL */
587           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
588           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
589           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
590           pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
591           break;
592         }
593
594       }
595     } else {
596       int carry_info = 0;
597       int offset = 0;
598       /* size > 2 */
599       DEBUGpic16_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
600
601       while(size--) {
602         lo = BYTEofLONG(lit,0);
603
604         if(carry_info) {
605           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
606           pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
607         }else {
608           /* no carry info from previous step */
609           /* this means this is the first time to add */
610           switch(lo) {
611           case 0:
612             break;
613           case 1:
614             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
615             carry_info=1;
616             break;
617           default:
618             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
619             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
620             if(lit <0x100) 
621               carry_info = 3;  /* Were adding only one byte and propogating the carry */
622             else
623               carry_info = 2;
624             break;
625           }
626         }
627         offset++;
628         lit >>= 8;
629       }
630     
631 /*
632       lo = BYTEofLONG(lit,0);
633
634       if(lit < 0x100) {
635         if(lo) {
636           if(lo == 1) {
637             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
638             emitSKPNZ;
639           } else {
640             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
641             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
642             emitSKPNC;
643           }
644           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
645           emitSKPNZ;
646           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
647           emitSKPNZ;
648           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
649
650         } 
651       } 
652     }
653
654 */
655     }
656   } else {
657     int offset = 1;
658     DEBUGpic16_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
659
660     if(size == 1) {
661
662       if(AOP_TYPE(left) == AOP_ACC) {
663         /* left addend is already in accumulator */
664         switch(lit & 0xff) {
665         case 0:
666           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
667           emitMOVWF(result,0);
668           break;
669         default:
670           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
671           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
672           emitMOVWF(result,0);
673         }
674       } else {
675         /* left addend is in a register */
676         switch(lit & 0xff) {
677         case 0:
678           pic16_mov2w(AOP(left),0);
679           emitMOVWF(result, 0);
680           break;
681         case 1:
682           pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
683           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
684           emitMOVWF(result,0);
685           break;
686         case 0xff:
687           pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
688           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
689           emitMOVWF(result,0);
690           break;
691         default:
692           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
693           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
694           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
695           emitMOVWF(result,0);
696         }
697       }
698
699     } else {
700       int clear_carry=0;
701
702       /* left is not the accumulator */
703       if(lit & 0xff) {
704         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
705         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
706       } else {
707         pic16_mov2w(AOP(left),0);
708         /* We don't know the state of the carry bit at this point */
709         clear_carry = 1;
710       }
711       //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
712       emitMOVWF(result,0);
713       while(--size) {
714       
715         lit >>= 8;
716         if(lit & 0xff) {
717           if(clear_carry) {
718             /* The ls byte of the lit must've been zero - that 
719                means we don't have to deal with carry */
720
721             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
722             pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(left),offset));
723             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
724
725             clear_carry = 0;
726
727           } else {
728             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
729             pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
730             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
731           }
732
733         } else {
734           pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
735           pic16_mov2w(AOP(left),offset);
736           pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
737         }
738         offset++;
739       }
740     }
741   }
742 }
743
744 /*-----------------------------------------------------------------*/
745 /* pic16_genPlus - generates code for addition                     */
746 /*-----------------------------------------------------------------*/
747 void pic16_genPlus (iCode *ic)
748 {
749   int i, size, offset = 0;
750   operand *result, *left, *right;
751
752     FENTRY;
753     
754     /* special cases :- */
755         result = IC_RESULT(ic);
756         left = IC_LEFT(ic);
757         right = IC_RIGHT(ic);
758         pic16_aopOp (left,ic,FALSE);
759         pic16_aopOp (right,ic,FALSE);
760         pic16_aopOp (result,ic,TRUE);
761         DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
762         // pic16_DumpOp("(left)",left);
763
764         /* if literal, literal on the right or
765         if left requires ACC or right is already
766         in ACC */
767
768         if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
769                 operand *t = right;
770                 right = IC_RIGHT(ic) = left;
771                 left = IC_LEFT(ic) = t;
772         }
773
774         /* if both left & right are in bit space */
775         if (AOP_TYPE(left) == AOP_CRY &&
776                 AOP_TYPE(right) == AOP_CRY) {
777                 pic16_genPlusBits (ic);
778                 goto release ;
779         }
780
781         /* if left in bit space & right literal */
782         if (AOP_TYPE(left) == AOP_CRY &&
783                 AOP_TYPE(right) == AOP_LIT) {
784                 /* if result in bit space */
785                 if(AOP_TYPE(result) == AOP_CRY){
786                         if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
787                                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
788                                 if (!pic16_sameRegs(AOP(left), AOP(result)) )
789                                         pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
790                                 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
791                         }
792                 } else {
793                         unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
794                         size = pic16_getDataSize(result);
795                         while (size--) {
796                                 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
797                                 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
798                                 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
799                                 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));  
800                                 //pic16_emitcode("addc","a,#00  ;%d",__LINE__);
801                                 //pic16_aopPut(AOP(result),"a",offset++);
802                         }
803                 }
804         goto release ;
805         } // left == CRY
806
807         /* if I can do an increment instead
808         of add then GOOD for ME */
809         if (pic16_genPlusIncr (ic) == TRUE)
810                 goto release;   
811
812         size = pic16_getDataSize(result);
813
814         if(AOP(right)->type == AOP_LIT) {
815                 /* Add a literal to something else */
816                 //bool know_W=0;
817                 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
818                 //unsigned l1=0;
819
820                 //offset = 0;
821                 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
822
823                 genAddLit (ic,  lit);
824                 goto release;
825
826         } else if(AOP_TYPE(right) == AOP_CRY) {
827
828                 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
829                 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
830                 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
831
832                 /* here we are adding a bit to a char or int */
833                 if(size == 1) {
834                         if (pic16_sameRegs(AOP(left), AOP(result)) ) {
835
836                                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
837                                 pic16_emitpcode(POC_INCF ,  pic16_popGet(AOP(result),0));
838
839                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
840                                                 AOP(right)->aopu.aop_dir,
841                                                 AOP(right)->aopu.aop_dir);
842                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
843                         } else { // not same
844
845                                 if(AOP_TYPE(left) == AOP_ACC) {
846                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
847                                         pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
848
849                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
850                                         AOP(right)->aopu.aop_dir,
851                                         AOP(right)->aopu.aop_dir);
852                                         pic16_emitcode(" xorlw","1");
853                                 } else {
854                                         pic16_mov2w(AOP(left),0);
855                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
856                                         pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
857
858                                         pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
859                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
860                                         AOP(right)->aopu.aop_dir,
861                                         AOP(right)->aopu.aop_dir);
862                                         pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
863                                 }
864           
865                                 if(AOP_TYPE(result) != AOP_ACC) {
866             
867                                         if(AOP_TYPE(result) == AOP_CRY) {
868                                                 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
869                                                 pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(result),0));
870                                                 emitSKPZ;
871                                                 pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(result),0));
872                                         } else {
873                                                 pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(result),0));
874                                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
875                                         }
876                                 }
877                         }
878
879                 } else {
880                         int offset = 1;
881                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
882                         if (pic16_sameRegs(AOP(left), AOP(result)) ) {
883                                 emitCLRZ;
884                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
885                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),0));
886
887                                 pic16_emitcode("clrz","");
888
889                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
890                                                 AOP(right)->aopu.aop_dir,
891                                                 AOP(right)->aopu.aop_dir);
892                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
893
894                         } else {
895                                 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
896                                 pic16_mov2w(AOP(left),0);
897                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
898                                 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
899                                 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
900                                 emitMOVWF(right,0);
901
902                                 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
903                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
904                                                 AOP(right)->aopu.aop_dir,
905                                                 AOP(right)->aopu.aop_dir);
906                                 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
907                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
908
909                         }
910
911                         while(--size){
912                                 emitSKPZ;
913                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),offset++));
914                                 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
915                         }
916
917                 }
918       
919         } else {
920                 // add bytes
921
922                 // Note: the following is an example of WISC code, eg.
923                 // it's supposed to run on a Weird Instruction Set Computer :o)
924
925                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
926
927                 if ( AOP_TYPE(left) == AOP_ACC) {
928                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
929                         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
930                         if ( AOP_TYPE(result) != AOP_ACC)
931                                 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
932                         goto release; // we're done, since WREG is 1 byte
933                 }
934
935
936                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
937
938                 size = min( AOP_SIZE(result), AOP_SIZE(right) );
939                 size = min( size, AOP_SIZE(left) );
940                 offset = 0;
941
942                 if(pic16_debug_verbose) {
943 //                      fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
944 //                              AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
945 //                      fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
946                 }
947
948
949
950                 if ((AOP_TYPE(left) == AOP_PCODE) && (
951                                 (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
952 //                              (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
953                                 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
954                 {
955                         // add to literal operand
956
957                         // add first bytes
958                         for(i=0; i<size; i++) {
959                                 if (AOP_TYPE(right) == AOP_ACC) {
960                                         pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
961                                 } else {
962                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
963                                         if(i) { // add with carry
964                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
965                                         } else { // add without
966                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
967                                         }
968                                 }
969                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
970                         }
971                         
972                         DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
973
974                         // add leftover bytes
975                         if (SPEC_USIGN(getSpec(operandType(right)))) {
976                                 // right is unsigned
977                                 for(i=size; i< AOP_SIZE(result); i++) {
978                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
979                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
980                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
981                                 }
982
983                         } else {
984                                 // right is signed, oh dear ...
985                                 for(i=size; i< AOP_SIZE(result); i++) {
986                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
987                                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
988                                         pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
989                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
990                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
991                                 }
992
993                         }
994                         goto release;
995
996                 } else {
997                         // add regs
998
999                         // add first bytes
1000                         for(i=0; i<size; i++) {
1001                                 if (AOP_TYPE(right) != AOP_ACC)
1002                                   pic16_mov2w(AOP(right),i);
1003                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1004                                 {
1005                                         if(i) { // add with carry
1006                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1007                                         } else { // add without
1008                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1009                                         }
1010                                 } else { // not same
1011                                         if(i) { // add with carry
1012                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1013                                         } else { // add without
1014                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1015                                         }
1016                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1017                                 }
1018                         }
1019
1020                         // add leftover bytes
1021                         // either left or right is too short
1022                         for (i=size; i < AOP_SIZE(result); i++) {
1023                           fprintf (stderr, "%s:%d: new code...\n", __FUNCTION__, __LINE__);
1024                           pic16_emitcode ("; ", "new arithmetics... test me...");
1025                           // get right operand into WREG
1026                           if (i < AOP_SIZE(right)) {
1027                             pic16_mov2w (AOP(right), i);
1028                           } else {
1029                             pic16_emitcode ("; =##", "right too short");
1030                             // right is too short
1031                             pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1032                             if (!SPEC_USIGN(getSpec(operandType(right)))) {
1033                               pic16_emitcode ("; =##", "right signed");
1034                               // right operand is signed
1035                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1036                               pic16_emitpcode(POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1037                             }
1038                           }
1039
1040                           // get left+WREG+CARRY into result
1041                           if (i < AOP_SIZE(left)) {
1042                             if (pic16_sameRegs (AOP(left), AOP(result))) {
1043                               pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1044                             } else {
1045                               pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1046                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1047                             }
1048                           } else {
1049                             pic16_emitcode ("; =##", "left too short");
1050                             // left is too short
1051                             pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1052                             if (!SPEC_USIGN(getSpec(operandType(left)))) {
1053                               pic16_emitcode ("; =##", "left signed");
1054                               // left operand is signed
1055                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1056                               pic16_emitpcode(POC_COMF, pic16_popGet (AOP(result), i));
1057                             }
1058                             pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1059                           }
1060                         } // for i
1061                         goto release;
1062                         
1063 #if 0
1064                         // add leftover bytes
1065                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1066                                 // right is unsigned
1067                                 for(i=size; i< AOP_SIZE(result); i++) {
1068                                         if (pic16_sameRegs(AOP(left), AOP(result)))
1069                                         {
1070                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1071                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1072                                         } else { // not same
1073                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1074                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1075                                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1076                                         }
1077                                 }
1078                         } else {
1079                                 // right is signed
1080                                 for(i=size; i< AOP_SIZE(result); i++) {
1081                                         if(size < AOP_SIZE(left)) {
1082                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1083                                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1084                                                 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1085                                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1086                                                 {
1087                                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1088                                                 } else { // not same
1089                                                         pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1090                                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1091                                                 }
1092                                         } else {
1093                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1094                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1095                                         }
1096                                 }
1097                         }
1098                         goto release;
1099 #endif
1100                 }
1101
1102         }
1103
1104         assert( 0 );
1105         // TODO:        anything from here to before "release:" is probably obsolete and should be removed
1106         //              when the regression tests are stable
1107
1108         if (AOP_SIZE(result) > AOP_SIZE(right)) {
1109                 int sign =  !(SPEC_USIGN(getSpec(operandType(left))) |
1110                                 SPEC_USIGN(getSpec(operandType(right))) );
1111
1112
1113                 /* Need to extend result to higher bytes */
1114                 size = AOP_SIZE(result) - AOP_SIZE(right) - 1;
1115
1116                 /* First grab the carry from the lower bytes */
1117                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1118                 pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offset));
1119
1120
1121                 if(sign) {
1122                         /* Now this is really horrid. Gotta check the sign of the addends and propogate
1123                         * to the result */
1124
1125                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1126                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offset));
1127                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1128                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offset));
1129
1130                         /* if chars or ints or being signed extended to longs: */
1131                         if(size) {
1132                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1133                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1134                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1135                         }
1136                 }
1137
1138                 offset++;
1139                 while(size--) {
1140       
1141                         if(sign)
1142                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1143                         else
1144                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
1145
1146                         offset++;
1147                 }
1148         }
1149
1150
1151         //adjustArithmeticResult(ic);
1152
1153         release:
1154         pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1155         pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1156         pic16_freeAsmop(result,NULL,ic,TRUE);
1157 }
1158
1159 /*-----------------------------------------------------------------*/
1160 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1161 /*-----------------------------------------------------------------*/
1162 bool pic16_genMinusDec (iCode *ic)
1163 {
1164     unsigned int icount ;
1165     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1166
1167     FENTRY;
1168     /* will try to generate an increment */
1169     /* if the right side is not a literal 
1170     we cannot */
1171     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1172         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1173         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1174         return FALSE ;
1175
1176     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1177
1178     /* if the literal value of the right hand side
1179     is greater than 4 then it is not worth it */
1180     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1181         return FALSE ;
1182
1183     /* if decrement 16 bits in register */
1184     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1185         (size > 1) &&
1186         (icount == 1)) {
1187
1188       if(size == 2) { 
1189         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1190         emitSKPC;
1191         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1192
1193         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1194         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1195         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1196       } else {
1197         /* size is 3 or 4 */
1198         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1199         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_wreg));
1200         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1201         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1202
1203         pic16_emitcode("movlw","0xff");
1204         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1205
1206         //emitSKPNC;
1207         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1208         //emitSKPNC;
1209         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1210
1211         if(size > 3) {
1212           pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1213
1214           pic16_emitcode("skpnc","");
1215           //emitSKPNC;
1216           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1217         }
1218
1219       }
1220
1221       return TRUE;
1222
1223     }
1224
1225     /* if the sizes are greater than 1 then we cannot */
1226     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1227         AOP_SIZE(IC_LEFT(ic)) > 1   )
1228         return FALSE ;
1229
1230     /* we can if the aops of the left & result match or
1231     if they are in registers and the registers are the
1232     same */
1233     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1234
1235       while (icount--) 
1236         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1237
1238         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1239
1240         return TRUE ;
1241     }
1242
1243     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1244                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1245                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1246     if(size==1) {
1247
1248       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1249       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1250
1251       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1252       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1253
1254       return TRUE;
1255     }
1256
1257     return FALSE ;
1258 }
1259
1260 /*-----------------------------------------------------------------*/
1261 /* pic16_addSign - propogate sign bit to higher bytes                    */
1262 /*-----------------------------------------------------------------*/
1263 void pic16_addSign(operand *result, int offset, int sign)
1264 {
1265   int size = (pic16_getDataSize(result) - offset);
1266   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1267
1268   if(size > 0){
1269     if(sign && offset) {
1270
1271       if(size == 1) {
1272         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1273         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1274         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1275       } else {
1276
1277         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1278         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1279         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1280         while(size--)
1281           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1282
1283       }
1284     } else
1285       while(size--)
1286         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1287   }
1288 }
1289
1290 /*-----------------------------------------------------------------*/
1291 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1292 /*-----------------------------------------------------------------*/
1293 void pic16_genMinusBits (iCode *ic)
1294 {
1295     symbol *lbl = newiTempLabel(NULL);
1296
1297     FENTRY;
1298     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1299         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1300         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1301         pic16_emitcode("cpl","c");
1302         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1303         pic16_outBitC(IC_RESULT(ic));
1304     }
1305     else{
1306         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1307         pic16_emitcode("subb","a,acc");
1308         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1309         pic16_emitcode("inc","a");
1310         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1311         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1312         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1313     }
1314 }
1315
1316 /*-----------------------------------------------------------------*/
1317 /* pic16_genMinus - generates code for subtraction                       */
1318 /*-----------------------------------------------------------------*/
1319 void pic16_genMinus (iCode *ic)
1320 {
1321   int size, offset = 0, same=0;
1322   unsigned long lit = 0L;
1323
1324     FENTRY;
1325   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1326   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1327   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1328
1329   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1330       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1331     operand *t = IC_RIGHT(ic);
1332     IC_RIGHT(ic) = IC_LEFT(ic);
1333     IC_LEFT(ic) = t;
1334   }
1335
1336   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1337                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1338                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1339                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1340
1341   /* special cases :- */
1342   /* if both left & right are in bit space */
1343   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1344       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1345     pic16_genPlusBits (ic);
1346     goto release ;
1347   }
1348
1349   /* if I can do an decrement instead
1350      of subtract then GOOD for ME */
1351 //  if (pic16_genMinusDec (ic) == TRUE)
1352 //    goto release;   
1353
1354   size = pic16_getDataSize(IC_RESULT(ic));   
1355   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1356
1357   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1358     /* Add a literal to something else */
1359
1360     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1361     lit = - (long)lit;
1362
1363     genAddLit ( ic,  lit);
1364     
1365 #if 0
1366     /* add the first byte: */
1367     pic16_emitcode("movlw","0x%x", lit & 0xff);
1368     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1369     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1370     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1371
1372
1373     offset = 1;
1374     size--;
1375
1376     while(size-- > 0) {
1377
1378       lit >>= 8;
1379
1380       if(lit & 0xff) {
1381
1382         if((lit & 0xff) == 0xff) {
1383           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1384           emitSKPC;
1385           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1386         } else {
1387           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1388           emitSKPNC;
1389           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1390           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1391         }
1392
1393       } else {
1394         /* do the rlf known zero trick here */
1395         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1396         emitSKPNC;
1397         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1398       }
1399       offset++;
1400     }
1401 #endif
1402   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1403     // bit subtraction
1404
1405     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1406     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1407     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1408
1409     /* here we are subtracting a bit from a char or int */
1410     if(size == 1) {
1411       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1412
1413         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1414         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1415
1416         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1417                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1418                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1419         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1420       } else {
1421
1422         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1423           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1424           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1425         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1426               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1427
1428           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1429
1430           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1431             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1432               if(lit & 1) {
1433                 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1434                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435               }
1436             }else{
1437               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1438               if(lit & 1) 
1439                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1440               else
1441                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1442               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1443             }
1444             goto release;
1445           } else {
1446             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1447             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1448             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1449             //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1450
1451           }
1452
1453         } else {
1454           pic16_mov2w(AOP(IC_LEFT(ic)),0);
1455           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1456           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1457         }
1458           
1459         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1460             
1461           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1462
1463         } else  {
1464           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1465 /*
1466           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1467           emitSKPZ;
1468           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1469 */
1470         }
1471
1472       }
1473
1474     }
1475   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1476               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1477               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1478
1479     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1480     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1481                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1482                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1483                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1484
1485
1486     if( (size == 1) && ((lit & 0xff) == 0) ) {
1487       /* res = 0 - right */
1488       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1489         pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1490       } else { 
1491         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1492         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1493         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1494       }
1495       goto release;
1496     }
1497
1498     pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1499     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1500     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1501
1502
1503     offset = 0;
1504     while(--size) {
1505       lit >>= 8;
1506       offset++;
1507       if(same) {
1508         // here we have x = lit - x   for sizeof(x)>1
1509         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1510         pic16_emitpcode(POC_SUBFWB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1511       } else {
1512         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1513         pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1514         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1515       }
1516     }
1517   
1518
1519   } else {
1520
1521     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1522                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1523                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1524                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1525
1526     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1527       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1528       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1529       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1530       if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1531         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1532     } else {
1533
1534         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1535         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1536           pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1537
1538         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1539           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1540         else {
1541           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1542               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1543             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1544           } else {
1545             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1546           }
1547           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1548             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1549               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1550               emitSKPZ;
1551               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1552             }else
1553               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1554           }
1555         }
1556     }
1557
1558     /*
1559       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1560
1561       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1562       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1563       } else {
1564       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1565       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1566       }
1567     */
1568     offset = 1;
1569     size--;
1570
1571     while(size--){
1572       if (offset < AOP_SIZE(IC_RIGHT(ic)))
1573         pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1574       else {
1575         pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1576         if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1577           // signed -- sign extend the right operand
1578           pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1579           pic16_emitpcode (POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1580         }
1581       }
1582       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1583         pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1584       } else {
1585         if (offset < AOP_SIZE(IC_LEFT(ic))) {
1586           pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1587           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1588         } else {
1589           // zero extend the left operand
1590           pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1591           if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1592             // signed -- sign extend the left operand
1593             pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1594             pic16_emitpcode (POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1595           }
1596           pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1597         }
1598       } 
1599       offset++;
1600     }
1601
1602   }
1603
1604
1605   //    adjustArithmeticResult(ic);
1606         
1607  release:
1608   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1609   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1610   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1611 }
1612
1613
1614 /*-----------------------------------------------------------------*
1615  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1616  * 
1617  * 
1618  *-----------------------------------------------------------------*/
1619 void pic16_genUMult8XLit_8 (operand *left,
1620                              operand *right,
1621                              operand *result)
1622 {
1623   unsigned int lit;
1624   int same;
1625   int size = AOP_SIZE(result);
1626   int i;
1627
1628     FENTRY;
1629         DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1630
1631         if (AOP_TYPE(right) != AOP_LIT){
1632                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1633                 exit(1);
1634         }
1635
1636         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1637         lit &= 0xff;
1638         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1639         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1640         
1641         same = pic16_sameRegs(AOP(left), AOP(result));
1642         if(same) {
1643                 switch(lit) {
1644                         case 0:
1645                                 while (size--) {
1646                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1647                                 } // while
1648                                 return;
1649                         case 2:
1650                                 // its faster to left shift
1651                                 for (i=1; i < size; i++) {
1652                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1653                                 } // for
1654                                 emitCLRC;
1655                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1656                                 if (size > 1)
1657                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1658                                 return;
1659
1660                         default:
1661                                 if(AOP_TYPE(left) != AOP_ACC)
1662                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1663                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1664                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1665                                         pic16_popGet(AOP(result), 0)));
1666                                 if (size > 1) {
1667                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1668                                                                             pic16_popGet(AOP(result), 1)));
1669                                   for (i=2; i < size; i++) {
1670                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1671                                   } // for
1672                                 } // if
1673                                 return;
1674                 }
1675         } else {
1676                 // operands different
1677                 switch(lit) {
1678                         case 0:
1679                                 while (size--) {
1680                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1681                                 } // while
1682                                 return;
1683                         case 2:
1684                                 for (i=1; i < size; i++) {
1685                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1686                                 } // for
1687                                 emitCLRC;
1688                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1689                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1690                                 if (size > 1)
1691                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1692                                 return;
1693                         default:
1694                                 if(AOP_TYPE(left) != AOP_ACC)
1695                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1696                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1697                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1698                                         pic16_popGet(AOP(result), 0)));
1699
1700                                 if (size > 1) {
1701                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1702                                                                             pic16_popGet(AOP(result), 1)));
1703                                   for (i=2; i < size; i++) {
1704                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1705                                   } // for
1706                                 } // if
1707                                 return;
1708                 }
1709         }
1710 }
1711
1712 /*-----------------------------------------------------------------------*
1713  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1714  *-----------------------------------------------------------------------*/
1715 void pic16_genUMult16XLit_16 (operand *left,
1716                              operand *right,
1717                              operand *result)
1718 {
1719   pCodeOp *pct1, *pct2, *pct3, *pct4;
1720   unsigned int lit;
1721   int same;
1722
1723
1724     FENTRY;
1725     
1726         if (AOP_TYPE(right) != AOP_LIT){
1727                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1728                 exit(1);
1729         }
1730
1731         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1732         lit &= 0xffff;
1733
1734         same = pic16_sameRegs(AOP(left), AOP(result));
1735         if(same) {
1736                 switch(lit) {
1737                         case 0:
1738                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1739                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1740                                 return;
1741                         case 2:
1742                                 // its faster to left shift
1743                                 emitCLRC;
1744                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1745                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1746                                 return;
1747
1748                         default: {
1749                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1750
1751                                 pct1 = pic16_popGetTempReg(1);
1752                                 pct2 = pic16_popGetTempReg(1);
1753                                 pct3 = pic16_popGetTempReg(1);
1754                                 pct4 = pic16_popGetTempReg(1);
1755
1756                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1757                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1758                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1759                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1760                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1761                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1762                                         
1763                                 /* WREG still holds the low literal */
1764                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1765                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1766                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1767                                         
1768                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1769                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1770                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1771                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1772                                         
1773                                 /* load result */
1774                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1775                                         pct1, pic16_popGet(AOP(result), 0)));
1776                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1777                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1778                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1779                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1780
1781                                 pic16_popReleaseTempReg(pct4,1);
1782                                 pic16_popReleaseTempReg(pct3,1);
1783                                 pic16_popReleaseTempReg(pct2,1);
1784                                 pic16_popReleaseTempReg(pct1,1);
1785                         }; return;
1786                 }
1787         } else {
1788                 // operands different
1789                 switch(lit) {
1790                         case 0:
1791                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1792                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1793                                 return;
1794                         case 2:
1795                                 emitCLRC;
1796                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1797                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1798                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1799                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1800                                 return;
1801                         default: {
1802                                         
1803                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1804                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1805                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1806                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1807                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1808                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1809                                         
1810                                 /* WREG still holds the low literal */
1811                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1812                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1813                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1814                                         
1815                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1816                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1817                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1818                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1819
1820                         }; return;
1821                 }
1822         }
1823 }
1824
1825
1826 /*-----------------------------------------------------------------*
1827  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1828  * 
1829  * 
1830  *-----------------------------------------------------------------*/
1831 void pic16_genUMult8X8_8 (operand *left,
1832                            operand *right,
1833                            operand *result)
1834
1835 {
1836   FENTRY;
1837   
1838
1839         if (AOP_TYPE(right) == AOP_LIT) {
1840                 pic16_genUMult8XLit_8(left,right,result);
1841           return;
1842         }
1843
1844         /* cases:
1845                 A = A x B       B = A x B
1846                 A = B x C
1847                 W = A x B
1848                 W = W x B       W = B x W
1849         */
1850         /* if result == right then exchange left and right */
1851         if(pic16_sameRegs(AOP(result), AOP(right))) {
1852           operand *tmp;
1853                 tmp = left;
1854                 left = right;
1855                 right = tmp;
1856         }
1857                 
1858         if(AOP_TYPE(left) != AOP_ACC) {
1859                 // left is not WREG
1860                 if(AOP_TYPE(right) != AOP_ACC) {
1861                         pic16_mov2w(AOP(left), 0);
1862                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1863                 } else {
1864                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1865                 }
1866         } else {
1867                 // left is WREG, right cannot be WREG (or can?!)
1868                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1869         }
1870         
1871         /* result is in PRODL:PRODH */
1872         if(AOP_TYPE(result) != AOP_ACC) {
1873                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1874                         pic16_popGet(AOP(result), 0)));
1875
1876
1877                 if(AOP_SIZE(result)>1) {
1878                   int i;
1879
1880                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1881                         pic16_popGet(AOP(result), 1)));
1882                         
1883                         for(i=2;i<AOP_SIZE(result);i++)
1884                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1885                 }
1886         } else {
1887                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1888         }
1889 }
1890
1891 /*------------------------------------------------------------------*
1892  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1893  *------------------------------------------------------------------*/
1894 void pic16_genUMult16X16_16 (operand *left,
1895                            operand *right,
1896                            operand *result)
1897
1898 {
1899   pCodeOp *pct1, *pct2, *pct3, *pct4;
1900
1901     FENTRY;
1902
1903
1904         if (AOP_TYPE(right) == AOP_LIT) {
1905                 pic16_genUMult8XLit_8(left,right,result);
1906           return;
1907         }
1908
1909         /* cases:
1910                 A = A x B       B = A x B
1911                 A = B x C
1912         */
1913         /* if result == right then exchange left and right */
1914         if(pic16_sameRegs(AOP(result), AOP(right))) {
1915           operand *tmp;
1916                 tmp = left;
1917                 left = right;
1918                 right = tmp;
1919         }
1920
1921
1922         if(pic16_sameRegs(AOP(result), AOP(left))) {
1923
1924                 pct1 = pic16_popGetTempReg(1);
1925                 pct2 = pic16_popGetTempReg(1);
1926                 pct3 = pic16_popGetTempReg(1);
1927                 pct4 = pic16_popGetTempReg(1);
1928
1929                 pic16_mov2w(AOP(left), 0);
1930                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1931                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1932                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1933                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1934                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1935                                         
1936                 /* WREG still holds the lower left */
1937                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1938                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1939                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1940                 
1941                 pic16_mov2w(AOP(left), 1);
1942                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1943                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1944                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1945                                         
1946                 /* load result */
1947                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1948                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1949                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1950                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1951                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1952                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1953
1954                 pic16_popReleaseTempReg( pct4, 1 );
1955                 pic16_popReleaseTempReg( pct3, 1 );
1956                 pic16_popReleaseTempReg( pct2, 1 );
1957                 pic16_popReleaseTempReg( pct1, 1 );
1958
1959         } else {
1960
1961                 pic16_mov2w(AOP(left), 0);
1962                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1963                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1964                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1965                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1966                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1967
1968                 /* WREG still holds the lower left */
1969                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1970                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1971                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1972                 
1973                 pic16_mov2w(AOP(left), 1);
1974                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1975                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1976                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1977         }       
1978 }
1979
1980
1981 void pic16_genSMult16X16_16(operand *left,
1982                         operand *right,
1983                         operand *result)
1984 {
1985
1986 }
1987
1988 #if 0
1989 /*-----------------------------------------------------------------*
1990  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1991  *
1992  *  this routine will call the unsigned multiply routine and then
1993  * post-fix the sign bit.
1994  *-----------------------------------------------------------------*/
1995 void pic16_genSMult8X8_8 (operand *left,
1996                            operand *right,
1997                            operand *result,
1998                            pCodeOpReg *result_hi)
1999 {
2000         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2001
2002
2003   if(!result_hi) {
2004     result_hi = PCOR(pic16_popGet(AOP(result),1));
2005   }
2006
2007
2008   pic16_genUMult8X8_8(left,right,result);
2009
2010   
2011 #if 0
2012   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2013   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2014   pic16_mov2w(AOP(left),0);
2015   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2016   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2017 #endif
2018 }
2019 #endif
2020
2021 /*-----------------------------------------------------------------*
2022  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2023  *-----------------------------------------------------------------*/
2024 void pic16_genMult8X8_8 (operand *left,
2025                          operand *right,
2026                          operand *result)
2027 {
2028   FENTRY;
2029   
2030   if(AOP_TYPE(right) == AOP_LIT)
2031     pic16_genUMult8XLit_8(left,right,result);
2032   else
2033     pic16_genUMult8X8_8(left,right,result);
2034 }
2035
2036
2037 /*-----------------------------------------------------------------*
2038  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2039  *-----------------------------------------------------------------*/
2040 void pic16_genMult16X16_16 (operand *left,
2041                          operand *right,
2042                          operand *result)
2043 {
2044   FENTRY;
2045   
2046   if (AOP_TYPE(right) == AOP_LIT)
2047     pic16_genUMult16XLit_16(left,right,result);
2048   else
2049     pic16_genUMult16X16_16(left,right,result);
2050 }
2051
2052
2053
2054
2055 /*-----------------------------------------------------------------------*
2056  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2057  *-----------------------------------------------------------------------*/
2058 void pic16_genUMult32XLit_32 (operand *left,
2059                              operand *right,
2060                              operand *result)
2061 {
2062   pCodeOp *pct1, *pct2, *pct3, *pct4;
2063   unsigned int lit;
2064   int same;
2065
2066
2067     FENTRY;
2068     
2069         if (AOP_TYPE(right) != AOP_LIT){
2070                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2071                 exit(1);
2072         }
2073
2074         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2075         lit &= 0xffff;
2076
2077         same = pic16_sameRegs(AOP(left), AOP(result));
2078         if(same) {
2079                 switch(lit) {
2080                         case 0:
2081                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2082                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2083                                 return;
2084                         case 2:
2085                                 // its faster to left shift
2086                                 emitCLRC;
2087                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2088                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2089                                 return;
2090
2091                         default: {
2092                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2093
2094                                 pct1 = pic16_popGetTempReg(1);
2095                                 pct2 = pic16_popGetTempReg(1);
2096                                 pct3 = pic16_popGetTempReg(1);
2097                                 pct4 = pic16_popGetTempReg(1);
2098
2099                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2100                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2101                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2102                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2103                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2104                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2105                                         
2106                                 /* WREG still holds the low literal */
2107                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2108                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2109                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2110                                         
2111                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2112                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2113                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2114                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2115                                         
2116                                 /* load result */
2117                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2118                                         pct1, pic16_popGet(AOP(result), 0)));
2119                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2120                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2121                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2122                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2123
2124                                 pic16_popReleaseTempReg( pct4, 1 );
2125                                 pic16_popReleaseTempReg( pct3, 1 );
2126                                 pic16_popReleaseTempReg( pct2, 1 );
2127                                 pic16_popReleaseTempReg( pct1, 1 );
2128                         }; return;
2129                 }
2130         } else {
2131                 // operands different
2132                 switch(lit) {
2133                         case 0:
2134                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2135                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2136                                 return;
2137                         case 2:
2138                                 emitCLRC;
2139                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2140                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2141                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2142                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2143                                 return;
2144                         default: {
2145                                         
2146                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2147                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2148                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2149                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2150                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2151                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2152                                         
2153                                 /* WREG still holds the low literal */
2154                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2155                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2156                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2157                                         
2158                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2159                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2160                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2161                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2162
2163                         }; return;
2164                 }
2165         }
2166 }
2167
2168
2169 /*------------------------------------------------------------------*
2170  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2171  *------------------------------------------------------------------*/
2172 void pic16_genUMult32X32_32 (operand *left,
2173                            operand *right,
2174                            operand *result)
2175
2176 {
2177   pCodeOp *pct1, *pct2, *pct3, *pct4;
2178
2179     FENTRY;
2180     
2181         if (AOP_TYPE(right) == AOP_LIT) {
2182                 pic16_genUMult8XLit_8(left,right,result);
2183           return;
2184         }
2185
2186         /* cases:
2187                 A = A x B       B = A x B
2188                 A = B x C
2189         */
2190         /* if result == right then exchange left and right */
2191         if(pic16_sameRegs(AOP(result), AOP(right))) {
2192           operand *tmp;
2193                 tmp = left;
2194                 left = right;
2195                 right = tmp;
2196         }
2197
2198
2199         if(pic16_sameRegs(AOP(result), AOP(left))) {
2200
2201                 pct1 = pic16_popGetTempReg(1);
2202                 pct2 = pic16_popGetTempReg(1);
2203                 pct3 = pic16_popGetTempReg(1);
2204                 pct4 = pic16_popGetTempReg(1);
2205
2206                 pic16_mov2w(AOP(left), 0);
2207                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2208                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2209                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2210                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2211                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2212                                         
2213                 /* WREG still holds the lower left */
2214                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2215                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2216                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2217                 
2218                 pic16_mov2w(AOP(left), 1);
2219                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2220                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2221                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2222                                         
2223                 /* load result */
2224                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2225                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2226                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2227                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2228                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2229                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2230
2231                 pic16_popReleaseTempReg( pct4, 1 );
2232                 pic16_popReleaseTempReg( pct3, 1 );
2233                 pic16_popReleaseTempReg( pct2, 1 );
2234                 pic16_popReleaseTempReg( pct1, 1 );
2235
2236         } else {
2237
2238                 pic16_mov2w(AOP(left), 0);
2239                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2240                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2241                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2242                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2243                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2244
2245                 /* WREG still holds the lower left */
2246                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2247                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2248                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2249                 
2250                 pic16_mov2w(AOP(left), 1);
2251                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2252                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2253                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2254         }       
2255 }
2256
2257
2258 /*-----------------------------------------------------------------*
2259  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2260  *-----------------------------------------------------------------*/
2261 void pic16_genMult32X32_32 (operand *left,
2262                          operand *right,
2263                          operand *result)
2264 {
2265   FENTRY;
2266   
2267   if (AOP_TYPE(right) == AOP_LIT)
2268     pic16_genUMult32XLit_32(left,right,result);
2269   else
2270     pic16_genUMult32X32_32(left,right,result);
2271 }
2272
2273
2274
2275
2276
2277
2278
2279 #if 0
2280 /*-----------------------------------------------------------------*/
2281 /* constMult - generates code for multiplication by a constant     */
2282 /*-----------------------------------------------------------------*/
2283 void genMultConst(unsigned C)
2284 {
2285
2286   unsigned lit;
2287   unsigned sr3; // Shift right 3
2288   unsigned mask;
2289
2290   int size = 1;
2291
2292   /*
2293     Convert a string of 3 binary 1's in the lit into
2294     0111 = 1000 - 1;
2295   */
2296
2297   mask = 7 << ( (size*8) - 3);
2298   lit = C;
2299   sr3 = 0;
2300
2301   while(mask < (1<<size*8)) {
2302
2303     if( (mask & lit) == lit) {
2304       unsigned lsb;
2305
2306       /* We found 3 (or more) consecutive 1's */
2307
2308       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2309
2310       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2311
2312       lit ^= consecutive_bits;
2313
2314       mask <<= 3;
2315
2316       sr3 |= (consecutive + lsb);
2317
2318     }
2319
2320     mask >>= 1;
2321
2322   }
2323
2324 }
2325
2326 #endif