Pointers - Applied function ptr patch from Steve Tell. Fixed bugs with
[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     while(size--){
981       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
982         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
983         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
984
985         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
986         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
987       }
988
989       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
990       emitSKPNC;
991       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
992       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
993
994       /*
995         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
996         emitSKPNC;
997         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
998         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
999       */
1000
1001       offset++;
1002     }
1003
1004   }
1005
1006   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1007     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1008                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1009
1010
1011     /* Need to extend result to higher bytes */
1012     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1013
1014     /* First grab the carry from the lower bytes */
1015     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1016     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
1017
1018
1019     if(sign) {
1020       /* Now this is really horrid. Gotta check the sign of the addends and propogate
1021        * to the result */
1022
1023       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1024       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1025       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1026       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1027
1028       /* if chars or ints or being signed extended to longs: */
1029       if(size) {
1030         emitpcode(POC_MOVLW, popGetLit(0));
1031         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1032         emitpcode(POC_MOVLW, popGetLit(0xff));
1033       }
1034     }
1035
1036     offset++;
1037     while(size--) {
1038       
1039       if(sign)
1040         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1041       else
1042         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
1043
1044       offset++;
1045     }
1046   }
1047
1048
1049   //adjustArithmeticResult(ic);
1050
1051  release:
1052   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1053   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1054   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1055 }
1056
1057 /*-----------------------------------------------------------------*/
1058 /* genMinusDec :- does subtraction with decrement if possible     */
1059 /*-----------------------------------------------------------------*/
1060 bool genMinusDec (iCode *ic)
1061 {
1062     unsigned int icount ;
1063     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1064
1065     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1066     /* will try to generate an increment */
1067     /* if the right side is not a literal 
1068     we cannot */
1069     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1070         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1071         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1072         return FALSE ;
1073
1074     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1075
1076     /* if the literal value of the right hand side
1077     is greater than 4 then it is not worth it */
1078     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1079         return FALSE ;
1080
1081     /* if decrement 16 bits in register */
1082     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1083         (size > 1) &&
1084         (icount == 1)) {
1085
1086       if(size == 2) { 
1087         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1088         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1089         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1090         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1091
1092         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1093         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1094         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1095       } else {
1096         /* size is 3 or 4 */
1097         emitpcode(POC_MOVLW,  popGetLit(0xff));
1098         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1099         emitSKPNC;
1100         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1101         emitSKPNC;
1102         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1103
1104         pic14_emitcode("movlw","0xff");
1105         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1106
1107         emitSKPNC;
1108         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1109         emitSKPNC;
1110         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1111
1112         if(size > 3) {
1113           emitSKPNC;
1114           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1115
1116           pic14_emitcode("skpnc","");
1117           emitSKPNC;
1118           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1119         }
1120
1121       }
1122
1123       return TRUE;
1124
1125     }
1126
1127     /* if the sizes are greater than 1 then we cannot */
1128     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1129         AOP_SIZE(IC_LEFT(ic)) > 1   )
1130         return FALSE ;
1131
1132     /* we can if the aops of the left & result match or
1133     if they are in registers and the registers are the
1134     same */
1135     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1136
1137       while (icount--) 
1138         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1139
1140         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1141
1142         return TRUE ;
1143     }
1144
1145     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1146                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1147                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1148     if(size==1) {
1149
1150       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1151       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1152
1153       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1154       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1155
1156       return TRUE;
1157     }
1158
1159     return FALSE ;
1160 }
1161
1162 /*-----------------------------------------------------------------*/
1163 /* addSign - propogate sign bit to higher bytes                    */
1164 /*-----------------------------------------------------------------*/
1165 void addSign(operand *result, int offset, int sign)
1166 {
1167   int size = (pic14_getDataSize(result) - offset);
1168   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1169
1170   if(size > 0){
1171     if(sign && offset) {
1172
1173       if(size == 1) {
1174         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1175         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1176         emitpcode(POC_DECF, popGet(AOP(result),offset));
1177       } else {
1178
1179         emitpcode(POC_MOVLW, popGetLit(0));
1180         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1181         emitpcode(POC_MOVLW, popGetLit(0xff));
1182         while(size--)
1183           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1184
1185       }
1186     } else
1187       while(size--)
1188         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1189   }
1190 }
1191
1192 /*-----------------------------------------------------------------*/
1193 /* genMinusBits - generates code for subtraction  of two bits      */
1194 /*-----------------------------------------------------------------*/
1195 void genMinusBits (iCode *ic)
1196 {
1197     symbol *lbl = newiTempLabel(NULL);
1198     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1199     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1200         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1201         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1202         pic14_emitcode("cpl","c");
1203         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1204         pic14_outBitC(IC_RESULT(ic));
1205     }
1206     else{
1207         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1208         pic14_emitcode("subb","a,acc");
1209         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1210         pic14_emitcode("inc","a");
1211         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1212         aopPut(AOP(IC_RESULT(ic)),"a",0);
1213         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1214     }
1215 }
1216
1217 /*-----------------------------------------------------------------*/
1218 /* genMinus - generates code for subtraction                       */
1219 /*-----------------------------------------------------------------*/
1220 void genMinus (iCode *ic)
1221 {
1222   int size, offset = 0, same=0;
1223   unsigned long lit = 0L;
1224
1225   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1226   aopOp (IC_LEFT(ic),ic,FALSE);
1227   aopOp (IC_RIGHT(ic),ic,FALSE);
1228   aopOp (IC_RESULT(ic),ic,TRUE);
1229
1230   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1231       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1232     operand *t = IC_RIGHT(ic);
1233     IC_RIGHT(ic) = IC_LEFT(ic);
1234     IC_LEFT(ic) = t;
1235   }
1236
1237   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1238                    AopType(AOP_TYPE(IC_RESULT(ic))),
1239                    AopType(AOP_TYPE(IC_LEFT(ic))),
1240                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1241
1242   /* special cases :- */
1243   /* if both left & right are in bit space */
1244   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1245       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1246     genPlusBits (ic);
1247     goto release ;
1248   }
1249
1250   /* if I can do an decrement instead
1251      of subtract then GOOD for ME */
1252   //  if (genMinusDec (ic) == TRUE)
1253   //    goto release;   
1254
1255   size = pic14_getDataSize(IC_RESULT(ic));   
1256   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1257
1258   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1259     /* Add a literal to something else */
1260
1261     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1262     lit = - (long)lit;
1263
1264     genAddLit ( ic,  lit);
1265     
1266 #if 0
1267     /* add the first byte: */
1268     pic14_emitcode("movlw","0x%x", lit & 0xff);
1269     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1270     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1271     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1272
1273
1274     offset = 1;
1275     size--;
1276
1277     while(size-- > 0) {
1278
1279       lit >>= 8;
1280
1281       if(lit & 0xff) {
1282
1283         if((lit & 0xff) == 0xff) {
1284           emitpcode(POC_MOVLW,  popGetLit(0xff));
1285           emitSKPC;
1286           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1287         } else {
1288           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1289           emitSKPNC;
1290           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1291           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1292         }
1293
1294       } else {
1295         /* do the rlf known zero trick here */
1296         emitpcode(POC_MOVLW,  popGetLit(1));
1297         emitSKPNC;
1298         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1299       }
1300       offset++;
1301     }
1302 #endif
1303   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1304     // bit subtraction
1305
1306     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1307     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1308     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1309
1310     /* here we are subtracting a bit from a char or int */
1311     if(size == 1) {
1312       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1313
1314         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1315         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1316
1317         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1318                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1319                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1320         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1321       } else {
1322
1323         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1324           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1325           emitpcode(POC_XORLW , popGetLit(1));
1326         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1327               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1328
1329           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1330
1331           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1332             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1333               if(lit & 1) {
1334                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1335                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1336               }
1337             }else{
1338               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1339               if(lit & 1) 
1340                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1341               else
1342                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1343               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1344             }
1345             goto release;
1346           } else {
1347             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1348             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1349             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1350             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1351
1352           }
1353
1354         } else {
1355           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1356           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1357           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1358         }
1359           
1360         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1361             
1362           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1363
1364         } else  {
1365           emitpcode(POC_ANDLW , popGetLit(1));
1366 /*
1367           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1368           emitSKPZ;
1369           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1370 */
1371         }
1372
1373       }
1374
1375     }
1376   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1377               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1378               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1379
1380     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1381     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1382                    AopType(AOP_TYPE(IC_RESULT(ic))),
1383                    AopType(AOP_TYPE(IC_LEFT(ic))),
1384                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1385
1386
1387     if( (size == 1) && ((lit & 0xff) == 0) ) {
1388       /* res = 0 - right */
1389       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1390         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1391         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1392       } else { 
1393         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1394         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1395         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1396       }
1397       goto release;
1398     }
1399
1400     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1401     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1402     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1403
1404
1405     offset = 1;
1406     while(--size) {
1407       lit >>= 8;
1408
1409       if(size == 1) {
1410         /* This is the last byte in a multibyte subtraction 
1411          * There are a couple of tricks we can do by not worrying about 
1412          * propogating the carry */
1413         if(lit == 0xff) {
1414           /* 0xff - x == ~x */
1415           if(same) {
1416             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1417             emitSKPC;
1418             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1419           } else {
1420             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1421             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1422             emitSKPC;
1423             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1424           }
1425         } else {
1426             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1427             emitSKPC;
1428             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1429             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1430             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1431         }
1432
1433         goto release;
1434       }
1435
1436       if(same) {
1437
1438         if(lit & 0xff) {
1439           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1440           emitSKPC;
1441           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1442           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1443         } else {
1444           emitSKPNC;
1445           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1446
1447         }
1448       } else {
1449
1450         if(lit & 0xff) {
1451           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1452           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1453         } else
1454           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1455
1456         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1457         emitSKPC;
1458         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1459         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1460       }
1461     }
1462   
1463
1464   } else {
1465
1466     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1467                    AopType(AOP_TYPE(IC_RESULT(ic))),
1468                    AopType(AOP_TYPE(IC_LEFT(ic))),
1469                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1470
1471     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1472       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1473       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1474       emitpcode(POC_SUBLW, popGetLit(0));
1475       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1476     } else {
1477
1478       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1479         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1480         emitpcode(POC_SUBLW, popGetLit(0));
1481         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1482           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1483       } else {
1484
1485         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1486         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1487           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1488
1489         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1490           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1491         else {
1492           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1493               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1494             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1495           } else {
1496             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1497           }
1498           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1499             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1500               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1501               emitSKPZ;
1502               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1503             }else
1504               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1505           }
1506         }
1507       }
1508     }
1509
1510     /*
1511       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1512
1513       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1514       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1515       } else {
1516       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1517       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1518       }
1519     */
1520     offset = 1;
1521     size--;
1522
1523     while(size--){
1524       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1525         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1526         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1527       }
1528       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1529       emitSKPC;
1530       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1531       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1532
1533       offset++;
1534     }
1535
1536   }
1537
1538
1539   //    adjustArithmeticResult(ic);
1540         
1541  release:
1542   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1543   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1544   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1545 }
1546 /*-----------------------------------------------------------------*
1547  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1548  * 
1549  * 
1550  *-----------------------------------------------------------------*/
1551 void genUMult8XLit_16 (operand *left,
1552                        operand *right,
1553                        operand *result,
1554                        pCodeOpReg *result_hi)
1555
1556 {
1557
1558   unsigned int lit;
1559   unsigned int i,have_first_bit;
1560   int same;
1561   pCodeOp *temp;
1562
1563   if (AOP_TYPE(right) != AOP_LIT){
1564     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1565     exit(1);
1566   }
1567
1568
1569   if(!result_hi) {
1570     result_hi = PCOR(popGet(AOP(result),1));
1571   }
1572
1573   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1574   lit &= 0xff;
1575   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1576
1577   same = pic14_sameRegs(AOP(left), AOP(result));
1578
1579   if(same) {
1580     switch(lit) {
1581     case 0:
1582       emitpcode(POC_CLRF,  popGet(AOP(left),0));
1583       return;
1584     case 2:
1585       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1586       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1587       return;
1588     case 3:
1589       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1590       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1591       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1592       return;
1593     case 4:
1594       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1595       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1596       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1597       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1598       return;
1599     case 5:
1600       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1601       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1602       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1603       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1604       return;
1605     case 6:
1606       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1607       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1608       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1609       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1610       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1611       return;
1612     case 7:
1613       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1614       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1615       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1616       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1617       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
1618       return;
1619     case 8:
1620       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1621       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1622       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1623       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1624       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1625       return;
1626     case 9:
1627       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1628       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1629       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1630       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1631       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1632       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1633       return;
1634     case 10:
1635       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1636       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1637       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1638       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1639       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1640       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1641       return;
1642     case 11:
1643       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1644       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1645       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1646       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1647       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1648       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
1649       return;
1650     case 12:
1651       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1652       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1653       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1654       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1655       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1656       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1657       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1658       return;
1659     case 13:
1660       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1661       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1662       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1663       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1664       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1665       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
1666       return;
1667     case 14:
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_ADDFW, popGet(AOP(left),0));  // W = 5*F
1672       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1673       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
1674       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
1675       return;
1676     case 15:
1677       temp = popGetTempReg();
1678       if(!temp) {
1679         fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1680         exit(1);
1681       }
1682       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1683       emitpcode(POC_MOVWF,  temp);
1684       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1685       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1686       emitpcode(POC_SWAPFW, temp);
1687       emitpcode(POC_SUBWF,  popGet(AOP(left),0));
1688       popReleaseTempReg(temp);
1689       return;
1690     case 16:
1691       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1692       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1693       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1694       return;
1695     case 17:
1696       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1697       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1698       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1699       return;
1700     case 32:
1701       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1702       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1703       emitpcode(POC_ANDLW,  popGetLit(0xe0));
1704       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1705       return;
1706     case 64:
1707       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1708       emitpcode(POC_RLF,    popGet(AOP(left),0));
1709       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1710       emitpcode(POC_ANDLW,  popGetLit(0xc0));
1711       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1712       return;
1713     case 128:
1714       emitpcode(POC_RRFW,   popGet(AOP(left),0));
1715       emitpcode(POC_CLRF,   popGet(AOP(left),0));
1716       emitpcode(POC_RRF,    popGet(AOP(left),0));
1717       return;
1718
1719     }
1720   } else {
1721
1722     switch(lit) {
1723     case 0:
1724       emitpcode(POC_CLRF,  popGet(AOP(result),0));
1725       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1726       return;
1727     case 2:
1728       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1729       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1730       emitpcode(POC_ADDWF, popGet(AOP(result),0));
1731       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1732       emitpcode(POC_RLF,   popCopyReg(result_hi));
1733       return;
1734     }
1735
1736   }
1737
1738   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1739   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1740   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1741
1742   have_first_bit = 0;
1743   for(i=0; i<8; i++) {
1744
1745     if(lit & 1) {
1746       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1747       have_first_bit = 1;
1748     }
1749
1750     if(have_first_bit) {
1751       emitpcode(POC_RRF,   popCopyReg(result_hi));
1752       emitpcode(POC_RRF,   popGet(AOP(result),0));
1753     }
1754
1755     lit >>= 1;
1756   }
1757
1758 }
1759
1760 /*-----------------------------------------------------------------*
1761  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1762  * 
1763  * 
1764  *-----------------------------------------------------------------*/
1765 void genUMult8X8_16 (operand *left,
1766                      operand *right,
1767                      operand *result,
1768                      pCodeOpReg *result_hi)
1769
1770 {
1771
1772   int i;
1773   int looped = 1;
1774
1775   if(!result_hi) {
1776     result_hi = PCOR(popGet(AOP(result),1));
1777   }
1778
1779   if (AOP_TYPE(right) == AOP_LIT) {
1780     genUMult8XLit_16(left,right,result,result_hi);
1781     return;
1782   }
1783
1784   if(!looped) {
1785     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1786
1787     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1788     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1789     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1790     emitCLRC;
1791
1792     for(i=0; i<8; i++) {
1793       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1794       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1795       emitpcode(POC_RRF,   popCopyReg(result_hi));
1796       emitpcode(POC_RRF,   popGet(AOP(result),0));
1797     }
1798
1799
1800     /*
1801       Here's another version that does the same thing and takes the 
1802       same number of instructions. The one above is slightly better
1803       because the entry instructions have a higher probability of
1804       being optimized out.
1805     */
1806     /*
1807       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1808       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1809       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1810       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1811
1812       for(i=0; i<8; i++) {
1813       emitSKPNC;
1814       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1815       emitpcode(POC_RRF,   popCopyReg(result_hi));
1816       emitpcode(POC_RRF,   popGet(AOP(result),0));
1817       }
1818     */
1819
1820   } else {
1821     symbol  *tlbl = newiTempLabel(NULL);
1822     pCodeOp *temp;
1823
1824
1825     pic14_emitcode(";","Looped 8 X 8 multiplication");
1826
1827     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1828     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1829
1830     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1831
1832     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1833
1834     temp = popGetTempReg();
1835     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1836
1837     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1838
1839     emitpLabel(tlbl->key);
1840
1841     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1842     emitSKPNC;
1843     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1844
1845     emitpcode(POC_RRF,   popCopyReg(result_hi));
1846     emitpcode(POC_RRF,   popGet(AOP(result),0));
1847
1848     emitSKPC;
1849     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1850
1851     popReleaseTempReg(temp);
1852
1853   }
1854 }
1855
1856 /*-----------------------------------------------------------------*
1857  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1858  *
1859  *  this routine will call the unsigned multiply routine and then
1860  * post-fix the sign bit.
1861  *-----------------------------------------------------------------*/
1862 void genSMult8X8_16 (operand *left,
1863                      operand *right,
1864                      operand *result,
1865                      pCodeOpReg *result_hi)
1866 {
1867
1868   if(!result_hi) {
1869     result_hi = PCOR(popGet(AOP(result),1));
1870   }
1871
1872   genUMult8X8_16(left,right,result,result_hi);
1873
1874   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1875   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1876   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1877   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1878   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1879   
1880 }
1881
1882 /*-----------------------------------------------------------------*
1883  * genMult8X8_8 - multiplication of two 8-bit numbers
1884  *
1885  *  this routine will call the unsigned multiply 8X8=>16 routine and
1886  * then throw away the high byte of the result.
1887  *
1888  *-----------------------------------------------------------------*/
1889 void genMult8X8_8 (operand *left,
1890                    operand *right,
1891                    operand *result)
1892 {
1893   pCodeOp *result_hi = popGetTempReg();
1894
1895   if (AOP_TYPE(right) == AOP_LIT)
1896     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1897   else
1898     genUMult8X8_16(left,right,result,PCOR(result_hi));
1899
1900   popReleaseTempReg(result_hi);
1901 }
1902 #if 0
1903 /*-----------------------------------------------------------------*/
1904 /* constMult - generates code for multiplication by a constant     */
1905 /*-----------------------------------------------------------------*/
1906 void genMultConst(unsigned C)
1907 {
1908
1909   unsigned lit;
1910   unsigned sr3; // Shift right 3
1911   unsigned mask;
1912
1913   int size = 1;
1914
1915   /*
1916     Convert a string of 3 binary 1's in the lit into
1917     0111 = 1000 - 1;
1918   */
1919
1920   mask = 7 << ( (size*8) - 3);
1921   lit = C;
1922   sr3 = 0;
1923
1924   while(mask < (1<<size*8)) {
1925
1926     if( (mask & lit) == lit) {
1927       unsigned lsb;
1928
1929       /* We found 3 (or more) consecutive 1's */
1930
1931       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1932
1933       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1934
1935       lit ^= consecutive_bits;
1936
1937       mask <<= 3;
1938
1939       sr3 |= (consecutive + lsb);
1940
1941     }
1942
1943     mask >>= 1;
1944
1945   }
1946
1947 }
1948
1949 #endif