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