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