* src/pic16/device.h (pic16_options_t): added field use_crt,
[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         assert( 0 );
1089         // TODO:        anything from here to before "release:" is probably obsolete and should be removed
1090         //              when the regression tests are stable
1091
1092         if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1093                 int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1094                                 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1095
1096
1097                 /* Need to extend result to higher bytes */
1098                 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1099
1100                 /* First grab the carry from the lower bytes */
1101                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1102                 pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1103
1104
1105                 if(sign) {
1106                         /* Now this is really horrid. Gotta check the sign of the addends and propogate
1107                         * to the result */
1108
1109                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1110                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1111                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1112                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1113
1114                         /* if chars or ints or being signed extended to longs: */
1115                         if(size) {
1116                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1117                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1118                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1119                         }
1120                 }
1121
1122                 offset++;
1123                 while(size--) {
1124       
1125                         if(sign)
1126                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1127                         else
1128                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1129
1130                         offset++;
1131                 }
1132         }
1133
1134
1135         //adjustArithmeticResult(ic);
1136
1137         release:
1138         pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1139         pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1140         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1141 }
1142
1143 /*-----------------------------------------------------------------*/
1144 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1145 /*-----------------------------------------------------------------*/
1146 bool pic16_genMinusDec (iCode *ic)
1147 {
1148     unsigned int icount ;
1149     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1150
1151     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1152     /* will try to generate an increment */
1153     /* if the right side is not a literal 
1154     we cannot */
1155     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1156         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1157         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1158         return FALSE ;
1159
1160     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1161
1162     /* if the literal value of the right hand side
1163     is greater than 4 then it is not worth it */
1164     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1165         return FALSE ;
1166
1167     /* if decrement 16 bits in register */
1168     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1169         (size > 1) &&
1170         (icount == 1)) {
1171
1172       if(size == 2) { 
1173         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1174         pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1175         pic16_emitpcode(POC_INCF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1176         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1177
1178         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1179         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1180         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1181       } else {
1182         /* size is 3 or 4 */
1183         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1184         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1185         emitSKPNC;
1186         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1187         emitSKPNC;
1188         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1189
1190         pic16_emitcode("movlw","0xff");
1191         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1192
1193         emitSKPNC;
1194         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1195         emitSKPNC;
1196         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1197
1198         if(size > 3) {
1199           emitSKPNC;
1200           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1201
1202           pic16_emitcode("skpnc","");
1203           emitSKPNC;
1204           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1205         }
1206
1207       }
1208
1209       return TRUE;
1210
1211     }
1212
1213     /* if the sizes are greater than 1 then we cannot */
1214     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1215         AOP_SIZE(IC_LEFT(ic)) > 1   )
1216         return FALSE ;
1217
1218     /* we can if the aops of the left & result match or
1219     if they are in registers and the registers are the
1220     same */
1221     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1222
1223       while (icount--) 
1224         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1225
1226         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1227
1228         return TRUE ;
1229     }
1230
1231     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1232                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1233                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1234     if(size==1) {
1235
1236       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1237       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1238
1239       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1240       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1241
1242       return TRUE;
1243     }
1244
1245     return FALSE ;
1246 }
1247
1248 /*-----------------------------------------------------------------*/
1249 /* pic16_addSign - propogate sign bit to higher bytes                    */
1250 /*-----------------------------------------------------------------*/
1251 void pic16_addSign(operand *result, int offset, int sign)
1252 {
1253   int size = (pic16_getDataSize(result) - offset);
1254   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1255
1256   if(size > 0){
1257     if(sign && offset) {
1258
1259       if(size == 1) {
1260         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1261         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1262         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1263       } else {
1264
1265         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1266         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1267         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1268         while(size--)
1269           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1270
1271       }
1272     } else
1273       while(size--)
1274         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1275   }
1276 }
1277
1278 /*-----------------------------------------------------------------*/
1279 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1280 /*-----------------------------------------------------------------*/
1281 void pic16_genMinusBits (iCode *ic)
1282 {
1283     symbol *lbl = newiTempLabel(NULL);
1284     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1285     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1286         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1287         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1288         pic16_emitcode("cpl","c");
1289         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1290         pic16_outBitC(IC_RESULT(ic));
1291     }
1292     else{
1293         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1294         pic16_emitcode("subb","a,acc");
1295         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1296         pic16_emitcode("inc","a");
1297         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1298         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1299         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1300     }
1301 }
1302
1303 /*-----------------------------------------------------------------*/
1304 /* pic16_genMinus - generates code for subtraction                       */
1305 /*-----------------------------------------------------------------*/
1306 void pic16_genMinus (iCode *ic)
1307 {
1308   int size, offset = 0, same=0;
1309   unsigned long lit = 0L;
1310
1311   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1312   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1313   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1314   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1315
1316   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1317       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1318     operand *t = IC_RIGHT(ic);
1319     IC_RIGHT(ic) = IC_LEFT(ic);
1320     IC_LEFT(ic) = t;
1321   }
1322
1323   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1324                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1325                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1326                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1327
1328   /* special cases :- */
1329   /* if both left & right are in bit space */
1330   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1331       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1332     pic16_genPlusBits (ic);
1333     goto release ;
1334   }
1335
1336   /* if I can do an decrement instead
1337      of subtract then GOOD for ME */
1338 //  if (pic16_genMinusDec (ic) == TRUE)
1339 //    goto release;   
1340
1341   size = pic16_getDataSize(IC_RESULT(ic));   
1342   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1343
1344   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1345     /* Add a literal to something else */
1346
1347     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1348     lit = - (long)lit;
1349
1350     genAddLit ( ic,  lit);
1351     
1352 #if 0
1353     /* add the first byte: */
1354     pic16_emitcode("movlw","0x%x", lit & 0xff);
1355     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1356     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1357     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1358
1359
1360     offset = 1;
1361     size--;
1362
1363     while(size-- > 0) {
1364
1365       lit >>= 8;
1366
1367       if(lit & 0xff) {
1368
1369         if((lit & 0xff) == 0xff) {
1370           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1371           emitSKPC;
1372           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1373         } else {
1374           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1375           emitSKPNC;
1376           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1377           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1378         }
1379
1380       } else {
1381         /* do the rlf known zero trick here */
1382         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1383         emitSKPNC;
1384         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1385       }
1386       offset++;
1387     }
1388 #endif
1389   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1390     // bit subtraction
1391
1392     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1393     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1394     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1395
1396     /* here we are subtracting a bit from a char or int */
1397     if(size == 1) {
1398       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1399
1400         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1401         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1402
1403         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1404                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1405                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1406         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1407       } else {
1408
1409         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1410           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1412         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1413               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1414
1415           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1416
1417           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1418             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1419               if(lit & 1) {
1420                 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1421                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1422               }
1423             }else{
1424               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1425               if(lit & 1) 
1426                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1427               else
1428                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1429               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1430             }
1431             goto release;
1432           } else {
1433             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1434             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1436             pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1437
1438           }
1439
1440         } else {
1441           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1442           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1443           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1444         }
1445           
1446         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1447             
1448           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1449
1450         } else  {
1451           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1452 /*
1453           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1454           emitSKPZ;
1455           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1456 */
1457         }
1458
1459       }
1460
1461     }
1462   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1463               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1464               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1465
1466     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1467     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1468                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1469                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1470                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1471
1472
1473     if( (size == 1) && ((lit & 0xff) == 0) ) {
1474       /* res = 0 - right */
1475       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1476         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1477         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1478       } else { 
1479         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1480         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1481         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1482       }
1483       goto release;
1484     }
1485
1486     pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1487     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1488     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1489
1490
1491     offset = 1;
1492     while(--size) {
1493       lit >>= 8;
1494
1495       if(size == 1) {
1496         /* This is the last byte in a multibyte subtraction 
1497          * There are a couple of tricks we can do by not worrying about 
1498          * propogating the carry */
1499         if(lit == 0xff) {
1500           /* 0xff - x == ~x */
1501           if(same) {
1502             pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1503             emitSKPC;
1504             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1505           } else {
1506             pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1507             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1508             emitSKPC;
1509             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1510           }
1511         } else {
1512             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1513             emitSKPC;
1514             pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1515             pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1516             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1517         }
1518
1519         goto release;
1520       }
1521
1522       if(same) {
1523
1524         if(lit & 0xff) {
1525           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1526           emitSKPC;
1527           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1528           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1529         } else {
1530           emitSKPNC;
1531           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1532
1533         }
1534       } else {
1535
1536         if(lit & 0xff) {
1537           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1538           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1539         } else
1540           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1541
1542         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1543         emitSKPC;
1544         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1545         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1546       }
1547     }
1548   
1549
1550   } else {
1551
1552     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1553                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1554                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1555                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1556
1557     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1558       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1559       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1560       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1561       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1562     } else {
1563
1564       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1565         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1566         pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1567         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1568           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1569       } else {
1570
1571         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1572         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1573           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1574
1575         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1576           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1577         else {
1578           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1579               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1580             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1581           } else {
1582             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1583           }
1584           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1585             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1586               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1587               emitSKPZ;
1588               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1589             }else
1590               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1591           }
1592         }
1593       }
1594     }
1595
1596     /*
1597       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1598
1599       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1600       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1601       } else {
1602       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1603       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1604       }
1605     */
1606     offset = 1;
1607     size--;
1608
1609     while(size--){
1610       if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1611         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1612         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1613       }
1614       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1615       emitSKPC;
1616       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1617       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1618
1619       offset++;
1620     }
1621
1622   }
1623
1624
1625   //    adjustArithmeticResult(ic);
1626         
1627  release:
1628   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1629   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1630   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1631 }
1632
1633
1634 /*-----------------------------------------------------------------*
1635  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1636  * 
1637  * 
1638  *-----------------------------------------------------------------*/
1639 void pic16_genUMult8XLit_8 (operand *left,
1640                              operand *right,
1641                              operand *result)
1642 {
1643   unsigned int lit;
1644   int same;
1645
1646
1647         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1648         DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1649   
1650         if (AOP_TYPE(right) != AOP_LIT){
1651                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1652                 exit(1);
1653         }
1654
1655         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1656         lit &= 0xff;
1657         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1658         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1659         
1660         same = pic16_sameRegs(AOP(left), AOP(result));
1661         if(same) {
1662                 switch(lit) {
1663                         case 0:
1664                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1665                                 return;
1666                         case 2:
1667                                 // its faster to left shift
1668                                 emitCLRC;
1669                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1670                                 return;
1671
1672                         default:
1673                                 if(AOP_TYPE(left) != AOP_ACC)
1674                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1675                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1676                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1677                                         pic16_popGet(AOP(result), 0)));
1678                                 return;
1679                 }
1680         } else {
1681                 // operands different
1682                 switch(lit) {
1683                         case 0:
1684                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1685                                 return;
1686                         case 2:
1687                                 emitCLRC;
1688                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1689                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1690                                 return;
1691                         default:
1692                                 if(AOP_TYPE(left) != AOP_ACC)
1693                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1694                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1695                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1696                                         pic16_popGet(AOP(result), 0)));
1697                                 return;
1698                 }
1699         }
1700 }
1701
1702 /*-----------------------------------------------------------------------*
1703  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1704  *-----------------------------------------------------------------------*/
1705 void pic16_genUMult16XLit_16 (operand *left,
1706                              operand *right,
1707                              operand *result)
1708 {
1709   pCodeOp *pct1, *pct2, *pct3, *pct4;
1710   unsigned int lit;
1711   int same;
1712
1713
1714         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1715
1716         if (AOP_TYPE(right) != AOP_LIT){
1717                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1718                 exit(1);
1719         }
1720
1721         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1722         lit &= 0xffff;
1723
1724         same = pic16_sameRegs(AOP(left), AOP(result));
1725         if(same) {
1726                 switch(lit) {
1727                         case 0:
1728                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1729                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1730                                 return;
1731                         case 2:
1732                                 // its faster to left shift
1733                                 emitCLRC;
1734                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1735                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1736                                 return;
1737
1738                         default: {
1739                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1740
1741                                 pct1 = pic16_popGetTempReg();
1742                                 pct2 = pic16_popGetTempReg();
1743                                 pct3 = pic16_popGetTempReg();
1744                                 pct4 = pic16_popGetTempReg();
1745
1746                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1747                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1748                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1749                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1750                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1751                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1752                                         
1753                                 /* WREG still holds the low literal */
1754                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1755                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1756                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1757                                         
1758                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1759                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1760                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1761                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1762                                         
1763                                 /* load result */
1764                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1765                                         pct1, pic16_popGet(AOP(result), 0)));
1766                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1767                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1768                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1769                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1770
1771                                 pic16_popReleaseTempReg( pct4 );
1772                                 pic16_popReleaseTempReg( pct3 );
1773                                 pic16_popReleaseTempReg( pct2 );
1774                                 pic16_popReleaseTempReg( pct1 );
1775                         }; return;
1776                 }
1777         } else {
1778                 // operands different
1779                 switch(lit) {
1780                         case 0:
1781                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1782                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1783                                 return;
1784                         case 2:
1785                                 emitCLRC;
1786                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1787                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1788                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1789                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1790                                 return;
1791                         default: {
1792                                         
1793                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1794                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1795                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1796                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1797                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1798                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1799                                         
1800                                 /* WREG still holds the low literal */
1801                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1802                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1803                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1804                                         
1805                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1806                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1807                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1808                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1809
1810                         }; return;
1811                 }
1812         }
1813 }
1814
1815
1816 /*-----------------------------------------------------------------*
1817  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1818  * 
1819  * 
1820  *-----------------------------------------------------------------*/
1821 void pic16_genUMult8X8_8 (operand *left,
1822                            operand *right,
1823                            operand *result)
1824
1825 {
1826         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1827
1828
1829         if (AOP_TYPE(right) == AOP_LIT) {
1830                 pic16_genUMult8XLit_8(left,right,result);
1831           return;
1832         }
1833
1834         /* cases:
1835                 A = A x B       B = A x B
1836                 A = B x C
1837                 W = A x B
1838                 W = W x B       W = B x W
1839         */
1840         /* if result == right then exchange left and right */
1841         if(pic16_sameRegs(AOP(result), AOP(right))) {
1842           operand *tmp;
1843                 tmp = left;
1844                 left = right;
1845                 right = tmp;
1846         }
1847                 
1848         if(AOP_TYPE(left) != AOP_ACC) {
1849                 // left is not WREG
1850                 if(AOP_TYPE(right) != AOP_ACC) {
1851                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1852                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1853                 } else {
1854                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1855                 }
1856         } else {
1857                 // left is WREG, right cannot be WREG (or can?!)
1858                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1859         }
1860         
1861         /* result is in PRODL:PRODH */
1862         if(AOP_TYPE(result) != AOP_ACC) {
1863                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1864                         pic16_popGet(AOP(result), 0)));
1865
1866
1867                 if(AOP_SIZE(result)>1) {
1868                   int i;
1869
1870                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1871                         pic16_popGet(AOP(result), 1)));
1872                         
1873                         for(i=2;i<AOP_SIZE(result);i++)
1874                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1875                 }
1876         } else {
1877                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1878         }
1879 }
1880
1881 /*------------------------------------------------------------------*
1882  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1883  *------------------------------------------------------------------*/
1884 void pic16_genUMult16X16_16 (operand *left,
1885                            operand *right,
1886                            operand *result)
1887
1888 {
1889   pCodeOp *pct1, *pct2, *pct3, *pct4;
1890
1891         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1892
1893
1894         if (AOP_TYPE(right) == AOP_LIT) {
1895                 pic16_genUMult8XLit_8(left,right,result);
1896           return;
1897         }
1898
1899         /* cases:
1900                 A = A x B       B = A x B
1901                 A = B x C
1902         */
1903         /* if result == right then exchange left and right */
1904         if(pic16_sameRegs(AOP(result), AOP(right))) {
1905           operand *tmp;
1906                 tmp = left;
1907                 left = right;
1908                 right = tmp;
1909         }
1910
1911
1912         if(pic16_sameRegs(AOP(result), AOP(left))) {
1913
1914                 pct1 = pic16_popGetTempReg();
1915                 pct2 = pic16_popGetTempReg();
1916                 pct3 = pic16_popGetTempReg();
1917                 pct4 = pic16_popGetTempReg();
1918
1919                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1920                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1921                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1922                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1923                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1924                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1925                                         
1926                 /* WREG still holds the lower left */
1927                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1928                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1929                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1930                 
1931                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1932                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1933                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1934                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1935                                         
1936                 /* load result */
1937                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1938                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1939                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1940                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1941                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1942                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1943
1944                 pic16_popReleaseTempReg( pct4 );
1945                 pic16_popReleaseTempReg( pct3 );
1946                 pic16_popReleaseTempReg( pct2 );
1947                 pic16_popReleaseTempReg( pct1 );
1948
1949         } else {
1950
1951                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1952                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1953                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1954                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1955                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1956                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1957
1958                 /* WREG still holds the lower left */
1959                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1960                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1961                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1962                 
1963                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1964                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1965                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1966                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1967         }       
1968 }
1969
1970
1971 void pic16_genSMult16X16_16(operand *left,
1972                         operand *right,
1973                         operand *result)
1974 {
1975
1976 }
1977
1978 #if 0
1979 /*-----------------------------------------------------------------*
1980  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1981  *
1982  *  this routine will call the unsigned multiply routine and then
1983  * post-fix the sign bit.
1984  *-----------------------------------------------------------------*/
1985 void pic16_genSMult8X8_8 (operand *left,
1986                            operand *right,
1987                            operand *result,
1988                            pCodeOpReg *result_hi)
1989 {
1990         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1991
1992
1993   if(!result_hi) {
1994     result_hi = PCOR(pic16_popGet(AOP(result),1));
1995   }
1996
1997
1998   pic16_genUMult8X8_8(left,right,result);
1999
2000   
2001 #if 0
2002   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2003   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2004   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2005   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2006   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2007 #endif
2008 }
2009 #endif
2010
2011 /*-----------------------------------------------------------------*
2012  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2013  *-----------------------------------------------------------------*/
2014 void pic16_genMult8X8_8 (operand *left,
2015                          operand *right,
2016                          operand *result)
2017 {
2018         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2019
2020         if(AOP_TYPE(right) == AOP_LIT)
2021                 pic16_genUMult8XLit_8(left,right,result);
2022         else
2023                 pic16_genUMult8X8_8(left,right,result);
2024 }
2025
2026
2027 /*-----------------------------------------------------------------*
2028  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2029  *-----------------------------------------------------------------*/
2030 void pic16_genMult16X16_16 (operand *left,
2031                          operand *right,
2032                          operand *result)
2033 {
2034         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2035
2036         if (AOP_TYPE(right) == AOP_LIT)
2037                 pic16_genUMult16XLit_16(left,right,result);
2038         else
2039                 pic16_genUMult16X16_16(left,right,result);
2040
2041 }
2042
2043
2044
2045
2046 /*-----------------------------------------------------------------------*
2047  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2048  *-----------------------------------------------------------------------*/
2049 void pic16_genUMult32XLit_32 (operand *left,
2050                              operand *right,
2051                              operand *result)
2052 {
2053   pCodeOp *pct1, *pct2, *pct3, *pct4;
2054   unsigned int lit;
2055   int same;
2056
2057
2058         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2059
2060         if (AOP_TYPE(right) != AOP_LIT){
2061                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2062                 exit(1);
2063         }
2064
2065         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2066         lit &= 0xffff;
2067
2068         same = pic16_sameRegs(AOP(left), AOP(result));
2069         if(same) {
2070                 switch(lit) {
2071                         case 0:
2072                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2073                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2074                                 return;
2075                         case 2:
2076                                 // its faster to left shift
2077                                 emitCLRC;
2078                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2079                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2080                                 return;
2081
2082                         default: {
2083                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2084
2085                                 pct1 = pic16_popGetTempReg();
2086                                 pct2 = pic16_popGetTempReg();
2087                                 pct3 = pic16_popGetTempReg();
2088                                 pct4 = pic16_popGetTempReg();
2089
2090                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2091                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2092                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2093                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2094                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2095                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2096                                         
2097                                 /* WREG still holds the low literal */
2098                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2099                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2101                                         
2102                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2103                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2104                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2105                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2106                                         
2107                                 /* load result */
2108                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2109                                         pct1, pic16_popGet(AOP(result), 0)));
2110                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2111                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2112                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2113                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2114
2115                                 pic16_popReleaseTempReg( pct4 );
2116                                 pic16_popReleaseTempReg( pct3 );
2117                                 pic16_popReleaseTempReg( pct2 );
2118                                 pic16_popReleaseTempReg( pct1 );
2119                         }; return;
2120                 }
2121         } else {
2122                 // operands different
2123                 switch(lit) {
2124                         case 0:
2125                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2126                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2127                                 return;
2128                         case 2:
2129                                 emitCLRC;
2130                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2131                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2132                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2133                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2134                                 return;
2135                         default: {
2136                                         
2137                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2138                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2139                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2140                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2141                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2142                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2143                                         
2144                                 /* WREG still holds the low literal */
2145                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2146                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2147                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2148                                         
2149                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2150                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2151                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2152                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2153
2154                         }; return;
2155                 }
2156         }
2157 }
2158
2159
2160 /*------------------------------------------------------------------*
2161  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2162  *------------------------------------------------------------------*/
2163 void pic16_genUMult32X32_32 (operand *left,
2164                            operand *right,
2165                            operand *result)
2166
2167 {
2168   pCodeOp *pct1, *pct2, *pct3, *pct4;
2169
2170         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2171
2172
2173         if (AOP_TYPE(right) == AOP_LIT) {
2174                 pic16_genUMult8XLit_8(left,right,result);
2175           return;
2176         }
2177
2178         /* cases:
2179                 A = A x B       B = A x B
2180                 A = B x C
2181         */
2182         /* if result == right then exchange left and right */
2183         if(pic16_sameRegs(AOP(result), AOP(right))) {
2184           operand *tmp;
2185                 tmp = left;
2186                 left = right;
2187                 right = tmp;
2188         }
2189
2190
2191         if(pic16_sameRegs(AOP(result), AOP(left))) {
2192
2193                 pct1 = pic16_popGetTempReg();
2194                 pct2 = pic16_popGetTempReg();
2195                 pct3 = pic16_popGetTempReg();
2196                 pct4 = pic16_popGetTempReg();
2197
2198                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2199                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2200                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2201                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2202                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2204                                         
2205                 /* WREG still holds the lower left */
2206                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2207                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2209                 
2210                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2211                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2212                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2213                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2214                                         
2215                 /* load result */
2216                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2218                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2219                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2220                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2221                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2222
2223                 pic16_popReleaseTempReg( pct4 );
2224                 pic16_popReleaseTempReg( pct3 );
2225                 pic16_popReleaseTempReg( pct2 );
2226                 pic16_popReleaseTempReg( pct1 );
2227
2228         } else {
2229
2230                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2231                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2232                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2233                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2234                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2236
2237                 /* WREG still holds the lower left */
2238                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2239                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2240                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2241                 
2242                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2243                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2244                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2245                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2246         }       
2247 }
2248
2249
2250 /*-----------------------------------------------------------------*
2251  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2252  *-----------------------------------------------------------------*/
2253 void pic16_genMult32X32_32 (operand *left,
2254                          operand *right,
2255                          operand *result)
2256 {
2257         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2258
2259         if (AOP_TYPE(right) == AOP_LIT)
2260                 pic16_genUMult32XLit_32(left,right,result);
2261         else
2262                 pic16_genUMult32X32_32(left,right,result);
2263
2264 }
2265
2266
2267
2268
2269
2270
2271
2272 #if 0
2273 /*-----------------------------------------------------------------*/
2274 /* constMult - generates code for multiplication by a constant     */
2275 /*-----------------------------------------------------------------*/
2276 void genMultConst(unsigned C)
2277 {
2278
2279   unsigned lit;
2280   unsigned sr3; // Shift right 3
2281   unsigned mask;
2282
2283   int size = 1;
2284
2285   /*
2286     Convert a string of 3 binary 1's in the lit into
2287     0111 = 1000 - 1;
2288   */
2289
2290   mask = 7 << ( (size*8) - 3);
2291   lit = C;
2292   sr3 = 0;
2293
2294   while(mask < (1<<size*8)) {
2295
2296     if( (mask & lit) == lit) {
2297       unsigned lsb;
2298
2299       /* We found 3 (or more) consecutive 1's */
2300
2301       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2302
2303       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2304
2305       lit ^= consecutive_bits;
2306
2307       mask <<= 3;
2308
2309       sr3 |= (consecutive + lsb);
2310
2311     }
2312
2313     mask >>= 1;
2314
2315   }
2316
2317 }
2318
2319 #endif