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