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