d919602c50740f8026655fb28feed25326deafba
[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)
40 #define __FUNCTION__            __FILE__
41 #endif
42
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
45 #else
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
48 #else
49 #ifdef HAVE_ENDIAN_H
50 #include <endian.h>
51 #else
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
55 #endif
56 #endif
57 #endif
58 #endif
59
60 #include "common.h"
61 #include "SDCCpeeph.h"
62 #include "ralloc.h"
63 #include "pcode.h"
64 #include "gen.h"
65
66
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68
69 const char *AopType(short type)
70 {
71   switch(type) {
72   case AOP_LIT:
73     return "AOP_LIT";
74     break;
75   case AOP_REG:
76     return "AOP_REG";
77     break;
78   case AOP_DIR:
79     return "AOP_DIR";
80     break;
81   case AOP_DPTR:
82     return "AOP_DPTR";
83     break;
84   case AOP_DPTR2:
85     return "AOP_DPTR2";
86     break;
87   case AOP_R0:
88     return "AOP_R0";
89     break;
90   case AOP_R1:
91     return "AOP_R1";
92     break;
93   case AOP_STK:
94     return "AOP_STK";
95     break;
96   case AOP_IMMD:
97     return "AOP_IMMD";
98     break;
99   case AOP_STR:
100     return "AOP_STR";
101     break;
102   case AOP_CRY:
103     return "AOP_CRY";
104     break;
105   case AOP_ACC:
106     return "AOP_ACC";
107     break;
108   }
109
110   return "BAD TYPE";
111 }
112 /*-----------------------------------------------------------------*/
113 /* genPlusIncr :- does addition with increment if possible         */
114 /*-----------------------------------------------------------------*/
115 bool genPlusIncr (iCode *ic)
116 {
117     unsigned int icount ;
118     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
119
120     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
121     DEBUGpic14_emitcode ("; ","result %d, left %d, right %d",
122                    AOP_TYPE(IC_RESULT(ic)),
123                    AOP_TYPE(IC_LEFT(ic)),
124                    AOP_TYPE(IC_RIGHT(ic)));
125
126     /* will try to generate an increment */
127     /* if the right side is not a literal 
128        we cannot */
129     if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
130         return FALSE ;
131     
132     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
133     /* if the literal value of the right hand side
134        is greater than 1 then it is faster to add */
135     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
136         return FALSE ;
137     
138     /* if increment 16 bits in register */
139     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
140         (icount == 1)) {
141
142       int offset = MSB16;
143
144       emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
145       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
146
147       while(--size) {
148         emitSKPNZ;
149         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
150         //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
151       }
152
153       return TRUE;
154     }
155     
156     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
157     /* if left is in accumulator  - probably a bit operation*/
158     if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a")  &&
159         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
160       
161       emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
162       pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
163                AOP(IC_RESULT(ic))->aopu.aop_dir,
164                AOP(IC_RESULT(ic))->aopu.aop_dir);
165       if(icount)
166         emitpcode(POC_XORLW,popGetLit(1));
167       //pic14_emitcode("xorlw","1");
168       else
169         emitpcode(POC_ANDLW,popGetLit(1));
170       //pic14_emitcode("andlw","1");
171
172       emitSKPZ;
173       emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
174       pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
175                AOP(IC_RESULT(ic))->aopu.aop_dir,
176                AOP(IC_RESULT(ic))->aopu.aop_dir);
177
178       return TRUE;
179     }
180
181
182
183     /* if the sizes are greater than 1 then we cannot */
184     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
185         AOP_SIZE(IC_LEFT(ic)) > 1   )
186         return FALSE ;
187     
188     /* If we are incrementing the same register by two: */
189
190     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
191         
192       while (icount--) 
193         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
194       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
195         
196       return TRUE ;
197     }
198     
199     DEBUGpic14_emitcode ("; ","couldn't increment result-%s  left-%s",
200                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
201                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
202     return FALSE ;
203 }
204
205 /*-----------------------------------------------------------------*/
206 /* pic14_outBitAcc - output a bit in acc                                 */
207 /*-----------------------------------------------------------------*/
208 void pic14_outBitAcc(operand *result)
209 {
210     symbol *tlbl = newiTempLabel(NULL);
211     /* if the result is a bit */
212     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
213
214     if (AOP_TYPE(result) == AOP_CRY){
215         aopPut(AOP(result),"a",0);
216     }
217     else {
218         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
219         pic14_emitcode("mov","a,#01");
220         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
221         pic14_outAcc(result);
222     }
223 }
224
225 /*-----------------------------------------------------------------*/
226 /* genPlusBits - generates code for addition of two bits           */
227 /*-----------------------------------------------------------------*/
228 void genPlusBits (iCode *ic)
229 {
230
231     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
232     /*
233       The following block of code will add two bits. 
234       Note that it'll even work if the destination is
235       the carry (C in the status register).
236       It won't work if the 'Z' bit is a source or destination.
237     */
238
239     /* If the result is stored in the accumulator (w) */
240     //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
241     if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
242       //emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
243       //              popGet(AOP(result),0,FALSE,FALSE));
244
245       emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
246       emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
247       emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
248       emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
249       emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
250       emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
251
252         pic14_emitcode("movlw","(1 << (%s & 7))",
253                  AOP(IC_RESULT(ic))->aopu.aop_dir,
254                  AOP(IC_RESULT(ic))->aopu.aop_dir);
255         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
256                  AOP(IC_RESULT(ic))->aopu.aop_dir,
257                  AOP(IC_RESULT(ic))->aopu.aop_dir);
258         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
259                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
260                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
261         pic14_emitcode("xorwf","(%s >>3),f",
262                  AOP(IC_RESULT(ic))->aopu.aop_dir);
263         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
264                  AOP(IC_LEFT(ic))->aopu.aop_dir,
265                  AOP(IC_LEFT(ic))->aopu.aop_dir);
266         pic14_emitcode("xorwf","(%s>>3),f",
267                  AOP(IC_RESULT(ic))->aopu.aop_dir);
268     } else { 
269
270       emitpcode(POC_CLRW, NULL);
271       emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
272       emitpcode(POC_XORLW, popGetLit(1));
273       emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
274       emitpcode(POC_XORLW, popGetLit(1));
275
276       pic14_emitcode("clrw","");
277       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
278                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
279                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
280       pic14_emitcode("xorlw","1");
281       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
282                AOP(IC_LEFT(ic))->aopu.aop_dir,
283                AOP(IC_LEFT(ic))->aopu.aop_dir);
284       pic14_emitcode("xorlw","1");
285     }
286
287 }
288
289 #if 0
290 /* This is the original version of this code.
291  *
292  * This is being kept around for reference, 
293  * because I am not entirely sure I got it right...
294  */
295 static void adjustArithmeticResult(iCode *ic)
296 {
297     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
298         AOP_SIZE(IC_LEFT(ic)) == 3   &&
299         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
300         aopPut(AOP(IC_RESULT(ic)),
301                aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
302                2);
303
304     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
305         AOP_SIZE(IC_RIGHT(ic)) == 3   &&
306         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
307         aopPut(AOP(IC_RESULT(ic)),
308                aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
309                2);
310     
311     if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
312         AOP_SIZE(IC_LEFT(ic)) < 3    &&
313         AOP_SIZE(IC_RIGHT(ic)) < 3   &&
314         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
315         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
316         char buffer[5];
317         sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
318         aopPut(AOP(IC_RESULT(ic)),buffer,2);
319     }
320 }
321 //#else
322 /* This is the pure and virtuous version of this code.
323  * I'm pretty certain it's right, but not enough to toss the old 
324  * code just yet...
325  */
326 static void adjustArithmeticResult(iCode *ic)
327 {
328     if (opIsGptr(IC_RESULT(ic)) &&
329         opIsGptr(IC_LEFT(ic))   &&
330         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
331     {
332         aopPut(AOP(IC_RESULT(ic)),
333                aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
334                GPTRSIZE - 1);
335     }
336
337     if (opIsGptr(IC_RESULT(ic)) &&
338         opIsGptr(IC_RIGHT(ic))   &&
339         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
340     {
341         aopPut(AOP(IC_RESULT(ic)),
342                aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
343                GPTRSIZE - 1);
344     }
345
346     if (opIsGptr(IC_RESULT(ic))            &&
347         AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
348         AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
349          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
350          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
351          char buffer[5];
352          sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
353          aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
354      }
355 }
356 #endif
357
358 /*-----------------------------------------------------------------*/
359 /* genAddlit - generates code for addition                         */
360 /*-----------------------------------------------------------------*/
361 static void genAddLit2byte (operand *result, int offr, int lit)
362 {
363
364   switch(lit & 0xff) {
365   case 0:
366     break;
367   case 1:
368     emitpcode(POC_INCF, popGet(AOP(result),offr,FALSE,FALSE));
369     break;
370   case 0xff:
371     emitpcode(POC_DECF, popGet(AOP(result),offr,FALSE,FALSE));
372     break;
373   default:
374     emitpcode(POC_MOVLW,popGetLit(lit&0xff));
375     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
376   }
377
378 }
379
380 static void genAddLit (iCode *ic, int lit)
381 {
382
383   int size,same;
384   int lo;
385
386   operand *result;
387   operand *left;
388
389   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
390
391
392   left = IC_LEFT(ic);
393   result = IC_RESULT(ic);
394   same = pic14_sameRegs(AOP(left), AOP(result));
395   size = pic14_getDataSize(result);
396
397   if(same) {
398
399     /* Handle special cases first */
400     if(size == 1) 
401       genAddLit2byte (result, 0, lit);
402      
403     else if(size == 2) {
404       int hi = 0xff & (lit >> 8);
405       lo = lit & 0xff;
406
407       switch(hi) {
408       case 0: 
409
410         /* lit = 0x00LL */
411         DEBUGpic14_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
412         switch(lo) {
413         case 0:
414           break;
415         case 1:
416           emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
417           emitSKPNZ;
418           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
419           break;
420         case 0xff:
421           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
422           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
423           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
424
425           break;
426         default:
427           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
428           emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
429           emitSKPNC;
430           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
431
432
433         }
434         break;
435
436       case 1:
437         /* lit = 0x01LL */
438         DEBUGpic14_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
439         switch(lo) {
440         case 0:  /* 0x0100 */
441           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
442           break;
443         case 1:  /* 0x0101  */
444           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
445           emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
446           emitSKPNZ;
447           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
448           break;
449         case 0xff: /* 0x01ff */
450           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
451           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
452           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
453           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
454         }         
455         break;
456
457       case 0xff:
458         DEBUGpic14_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
459         /* lit = 0xffLL */
460         switch(lo) {
461         case 0:  /* 0xff00 */
462           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
463           break;
464         case 1:  /*0xff01 */
465           emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
466           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
467           break;
468 /*      case 0xff: * 0xffff *
469           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
470           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
471           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
472           break;
473 */
474         default:
475           emitpcode(POC_MOVLW,popGetLit(lo));
476           emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
477           emitSKPC;
478           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
479           
480         }
481
482         break;
483         
484       default:
485         DEBUGpic14_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
486
487         /* lit = 0xHHLL */
488         switch(lo) {
489         case 0:  /* 0xHH00 */
490           genAddLit2byte (result, MSB16, hi);
491           break;
492         case 1:  /* 0xHH01 */
493           emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
494           emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
495           emitpcode(POC_MOVLW,popGetLit(hi));
496           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
497           break;
498 /*      case 0xff: * 0xHHff *
499           emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
500           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
501           emitpcode(POC_MOVLW,popGetLit(hi));
502           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
503           break;
504 */      default:  /* 0xHHLL */
505           emitpcode(POC_MOVLW,popGetLit(lo));
506           emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
507           emitpcode(POC_MOVLW,popGetLit(hi));
508           emitSKPNC;
509           emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
510           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
511           break;
512         }
513
514       }
515     } else {
516       int carry_info = 0;
517       int offset = 0;
518       /* size > 2 */
519       DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
520
521       while(size--) {
522         lo = BYTEofLONG(lit,0);
523
524         if(carry_info) {
525           switch(lo) {
526           case 0:
527             switch(carry_info) {
528             case 1:
529               emitSKPNZ;
530               emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
531               break;
532             case 2:
533               emitpcode(POC_RLFW, popGet(AOP(result),offset,FALSE,FALSE));
534               emitpcode(POC_ANDLW,popGetLit(1));
535               emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
536               break;
537             default: /* carry_info = 3  */
538               emitSKPNC;
539               emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
540               carry_info = 1;
541               break;
542             }
543             break;
544           case 0xff:
545             emitpcode(POC_MOVLW,popGetLit(lo));
546             if(carry_info==1) 
547               emitSKPZ;
548             else
549               emitSKPC;
550             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
551             break;
552           default:
553             emitpcode(POC_MOVLW,popGetLit(lo));
554             if(carry_info==1) 
555               emitSKPNZ;
556             else
557               emitSKPNC;
558             emitpcode(POC_MOVLW,popGetLit(lo+1));
559             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
560             carry_info=2;
561             break;
562           }
563         }else {
564           /* no carry info from previous step */
565           /* this means this is the first time to add */
566           switch(lo) {
567           case 0:
568             break;
569           case 1:
570             emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
571             carry_info=1;
572             break;
573           default:
574             emitpcode(POC_MOVLW,popGetLit(lo));
575             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
576             if(lit <0x100) 
577               carry_info = 3;  /* Were adding only one byte and propogating the carry */
578             else
579               carry_info = 2;
580             break;
581           }
582         }
583         offset++;
584         lit >>= 8;
585       }
586     
587 /*
588       lo = BYTEofLONG(lit,0);
589
590       if(lit < 0x100) {
591         if(lo) {
592           if(lo == 1) {
593             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
594             emitSKPNZ;
595           } else {
596             emitpcode(POC_MOVLW,popGetLit(lo));
597             emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
598             emitSKPNC;
599           }
600           emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
601           emitSKPNZ;
602           emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
603           emitSKPNZ;
604           emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
605
606         } 
607       } 
608     }
609
610 */
611     }
612   } else {
613     int offset = 1;
614     DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
615
616     if(size == 1) {
617
618       if(AOP_TYPE(left) == AOP_ACC) {
619         /* left addend is already in accumulator */
620         switch(lit & 0xff) {
621         case 0:
622           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
623           break;
624         default:
625           emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
626           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
627         }
628       } else {
629         /* left addend is in a register */
630         switch(lit & 0xff) {
631         case 0:
632           emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
633           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
634           break;
635         case 1:
636           emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE));
637           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
638           break;
639         case 0xff:
640           emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE));
641           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
642           break;
643         default:
644           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
645           emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
646           emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
647         }
648       }
649
650     } else {
651
652       if(lit & 0xff) {
653         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
654         emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
655       } else
656         emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
657
658       emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
659       lit >>= 8;
660       while(--size) {
661       
662         if(lit & 0xff) {
663           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
664           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
665           emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
666           emitSKPNC;
667           emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
668           emitpcode(POC_ADDWF,  popGet(AOP(result),offset,FALSE,FALSE));
669         } else {
670           emitpcode(POC_CLRF,  popGet(AOP(result),offset,FALSE,FALSE));
671           emitpcode(POC_RLF,   popGet(AOP(result),offset,FALSE,FALSE));
672           emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
673           emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
674         }
675       offset++;
676       }
677     }
678   }
679 }
680
681 /*-----------------------------------------------------------------*/
682 /* genPlus - generates code for addition                           */
683 /*-----------------------------------------------------------------*/
684 void genPlus (iCode *ic)
685 {
686   int size, offset = 0;
687
688   /* special cases :- */
689   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
690
691   aopOp (IC_LEFT(ic),ic,FALSE);
692   aopOp (IC_RIGHT(ic),ic,FALSE);
693   aopOp (IC_RESULT(ic),ic,TRUE);
694
695   /* if literal, literal on the right or
696      if left requires ACC or right is already
697      in ACC */
698
699   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
700     operand *t = IC_RIGHT(ic);
701     IC_RIGHT(ic) = IC_LEFT(ic);
702     IC_LEFT(ic) = t;
703   }
704
705   /* if both left & right are in bit space */
706   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
707       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
708     genPlusBits (ic);
709     goto release ;
710   }
711
712   /* if left in bit space & right literal */
713   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
714       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
715     /* if result in bit space */
716     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
717       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
718         emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
719         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
720           emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
721         emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
722       }
723     } else {
724       size = pic14_getDataSize(IC_RESULT(ic));
725       while (size--) {
726         MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
727         pic14_emitcode("addc","a,#00  ;%d",__LINE__);
728         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
729       }
730     }
731     goto release ;
732   }
733
734   /* if I can do an increment instead
735      of add then GOOD for ME */
736   if (genPlusIncr (ic) == TRUE)
737     goto release;   
738
739   size = pic14_getDataSize(IC_RESULT(ic));
740
741   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
742     /* Add a literal to something else */
743     //bool know_W=0;
744     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
745     //      unsigned l1=0;
746
747     //      offset = 0;
748     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
749
750     genAddLit (ic,  lit);
751 #if 0
752     while(size--){
753
754       DEBUGpic14_emitcode(";","size %d",size);
755
756       switch (lit & 0xff) {
757       case 0:
758         break;
759       case 1:
760         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
761           emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
762         else {
763           know_W = 0;
764           emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
765           if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
766             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
767         }
768         break;
769       case 0xff:
770         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
771           emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
772         else {
773           know_W = 0;
774           emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
775           if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
776             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
777         }
778         break;
779       default:
780         if( !know_W || ( (lit&0xff) != l1)  ) {
781           know_W = 1;
782           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
783         }
784         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
785           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
786           if(size) {
787             emitSKPNC;
788             emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
789           }
790
791         } else {
792           know_W = 0;
793           emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
794           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
795           if(size) {
796             emitSKPNC;
797             emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE));
798           }
799         }
800       }
801
802       l1 = lit & 0xff;
803       lit >>= 8;
804       offset++;
805     }
806 #endif
807
808   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
809
810     pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
811     pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
812     pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
813
814     /* here we are adding a bit to a char or int */
815     if(size == 1) {
816       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
817
818         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
819         emitpcode(POC_INCF ,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
820
821         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
822                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
823                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
824         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
825       } else {
826
827         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
828           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
829           emitpcode(POC_XORLW , popGetLit(1));
830
831           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
832                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
833                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
834           pic14_emitcode(" xorlw","1");
835         } else {
836           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
837           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
838           emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
839
840           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
841           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
842                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
843                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
844           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
845         }
846           
847         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
848             
849           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
850             emitpcode(POC_ANDLW , popGetLit(1));
851             emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
852             emitSKPZ;
853             emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
854           } else {
855             emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
856             pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
857           }
858         }
859       }
860
861     } else {
862       int offset = 1;
863
864       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
865         emitCLRZ;
866         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
867         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
868
869         pic14_emitcode("clrz","");
870
871         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
872                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
873                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
874         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
875
876       } else {
877
878         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
879         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
880         emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
881         emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
882
883
884         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
885         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
886                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
887                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
888         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
889         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
890
891       }
892
893       while(--size){
894         emitSKPZ;
895         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
896         //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
897       }
898
899     }
900       
901   } else {
902     
903     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
904       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
905       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
906     } else {
907
908       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
909         emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
910         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
911           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
912       } else {
913
914         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
915
916         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
917           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
918         else {
919           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
920               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
921             emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
922           } else {
923             emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
924             if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
925               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
926           }
927         }
928       }
929     }
930
931     offset = 1;
932     size--;
933
934     while(size--){
935       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
936         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
937         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
938
939         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
940         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
941       }
942
943       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
944       emitSKPNC;
945       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
946       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
947
948       /*
949         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
950         emitSKPNC;
951         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
952         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
953       */
954
955       offset++;
956     }
957
958   }
959
960   //adjustArithmeticResult(ic);
961
962  release:
963   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
964   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
965   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
966 }
967
968 /*-----------------------------------------------------------------*/
969 /* genMinusDec :- does subtraction with decrement if possible     */
970 /*-----------------------------------------------------------------*/
971 bool genMinusDec (iCode *ic)
972 {
973     unsigned int icount ;
974     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
975
976     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
977     /* will try to generate an increment */
978     /* if the right side is not a literal 
979     we cannot */
980     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
981         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
982         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
983         return FALSE ;
984
985     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
986
987     /* if the literal value of the right hand side
988     is greater than 4 then it is not worth it */
989     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
990         return FALSE ;
991
992     /* if decrement 16 bits in register */
993     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
994         (size > 1) &&
995         (icount == 1)) {
996
997       if(size == 2) { 
998         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
999         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1000         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1001         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1002
1003         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1004         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1005         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1006       } else {
1007         /* size is 3 or 4 */
1008         emitpcode(POC_MOVLW,  popGetLit(0xff));
1009         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1010         emitSKPNC;
1011         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1012         emitSKPNC;
1013         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1014
1015         pic14_emitcode("movlw","0xff");
1016         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1017
1018         emitSKPNC;
1019         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1020         emitSKPNC;
1021         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1022
1023         if(size > 3) {
1024           emitSKPNC;
1025           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1026
1027           pic14_emitcode("skpnc","");
1028           emitSKPNC;
1029           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1030         }
1031
1032       }
1033
1034       return TRUE;
1035
1036     }
1037
1038     /* if the sizes are greater than 1 then we cannot */
1039     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1040         AOP_SIZE(IC_LEFT(ic)) > 1   )
1041         return FALSE ;
1042
1043     /* we can if the aops of the left & result match or
1044     if they are in registers and the registers are the
1045     same */
1046     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1047
1048       while (icount--) 
1049         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1050
1051         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1052
1053         return TRUE ;
1054     }
1055
1056     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1057                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1058                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1059     if(size==1) {
1060
1061       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1062       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1063
1064       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1065       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1066
1067       return TRUE;
1068     }
1069
1070     return FALSE ;
1071 }
1072
1073 /*-----------------------------------------------------------------*/
1074 /* addSign - complete with sign                                    */
1075 /*-----------------------------------------------------------------*/
1076 void addSign(operand *result, int offset, int sign)
1077 {
1078     int size = (pic14_getDataSize(result) - offset);
1079     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1080     if(size > 0){
1081         if(sign){
1082             pic14_emitcode("rlc","a");
1083             pic14_emitcode("subb","a,acc");
1084             while(size--)
1085                 aopPut(AOP(result),"a",offset++); 
1086         } else
1087             while(size--)
1088                 aopPut(AOP(result),"#0",offset++);
1089     }
1090 }
1091
1092 /*-----------------------------------------------------------------*/
1093 /* genMinusBits - generates code for subtraction  of two bits      */
1094 /*-----------------------------------------------------------------*/
1095 void genMinusBits (iCode *ic)
1096 {
1097     symbol *lbl = newiTempLabel(NULL);
1098     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1099     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1100         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1101         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1102         pic14_emitcode("cpl","c");
1103         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1104         pic14_outBitC(IC_RESULT(ic));
1105     }
1106     else{
1107         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1108         pic14_emitcode("subb","a,acc");
1109         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1110         pic14_emitcode("inc","a");
1111         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1112         aopPut(AOP(IC_RESULT(ic)),"a",0);
1113         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1114     }
1115 }
1116
1117 /*-----------------------------------------------------------------*/
1118 /* genMinus - generates code for subtraction                       */
1119 /*-----------------------------------------------------------------*/
1120 void genMinus (iCode *ic)
1121 {
1122   int size, offset = 0,same;
1123   unsigned long lit = 0L;
1124
1125   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1126   aopOp (IC_LEFT(ic),ic,FALSE);
1127   aopOp (IC_RIGHT(ic),ic,FALSE);
1128   aopOp (IC_RESULT(ic),ic,TRUE);
1129
1130   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1131       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1132     operand *t = IC_RIGHT(ic);
1133     IC_RIGHT(ic) = IC_LEFT(ic);
1134     IC_LEFT(ic) = t;
1135   }
1136
1137   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1138                    AopType(AOP_TYPE(IC_RESULT(ic))),
1139                    AopType(AOP_TYPE(IC_LEFT(ic))),
1140                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1141
1142   DEBUGpic14_emitcode ("; ","same = %d, result-%s  left-%s",same,
1143                        aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1144                        aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1145
1146   /* special cases :- */
1147   /* if both left & right are in bit space */
1148   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1149       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1150     genPlusBits (ic);
1151     goto release ;
1152   }
1153
1154   /* if I can do an decrement instead
1155      of subtract then GOOD for ME */
1156   //  if (genMinusDec (ic) == TRUE)
1157   //    goto release;   
1158
1159   size = pic14_getDataSize(IC_RESULT(ic));   
1160   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1161
1162   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1163     /* Add a literal to something else */
1164
1165     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1166     lit = - (long)lit;
1167
1168     genAddLit ( ic,  lit);
1169     
1170 #if 0
1171     /* add the first byte: */
1172     pic14_emitcode("movlw","0x%x", lit & 0xff);
1173     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1174     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1175     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1176
1177
1178     offset = 1;
1179     size--;
1180
1181     while(size-- > 0) {
1182
1183       lit >>= 8;
1184
1185       if(lit & 0xff) {
1186
1187         if((lit & 0xff) == 0xff) {
1188           emitpcode(POC_MOVLW,  popGetLit(0xff));
1189           emitSKPC;
1190           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1191         } else {
1192           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1193           emitSKPNC;
1194           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1195           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1196         }
1197
1198       } else {
1199         /* do the rlf known zero trick here */
1200         emitpcode(POC_MOVLW,  popGetLit(1));
1201         emitSKPNC;
1202         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1203       }
1204       offset++;
1205     }
1206 #endif
1207   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1208     // bit subtraction
1209
1210     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1211     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1212     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1213
1214     /* here we are subtracting a bit from a char or int */
1215     if(size == 1) {
1216       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1217
1218         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1219         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1220
1221         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1222                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1223                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1224         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1225       } else {
1226
1227         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1228           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1229           emitpcode(POC_XORLW , popGetLit(1));
1230         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1231               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1232
1233           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1234
1235           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1236             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1237               if(lit & 1) {
1238                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1239                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1240               }
1241             }else{
1242               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1243               if(lit & 1) 
1244                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1245               else
1246                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1247               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1248             }
1249             goto release;
1250           } else {
1251             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1252             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1253             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1254             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1255
1256           }
1257
1258         } else {
1259           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1260           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1261           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1262         }
1263           
1264         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1265             
1266           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1267
1268         } else  {
1269           emitpcode(POC_ANDLW , popGetLit(1));
1270 /*
1271           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1272           emitSKPZ;
1273           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1274 */
1275         }
1276
1277       }
1278
1279     }
1280   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1281               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1282               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1283
1284     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1285     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1286                    AopType(AOP_TYPE(IC_RESULT(ic))),
1287                    AopType(AOP_TYPE(IC_LEFT(ic))),
1288                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1289
1290
1291     if( (size == 1) && ((lit & 0xff) == 0) ) {
1292       /* res = 0 - right */
1293       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1294         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1295       } else { 
1296         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1297         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1298       }
1299       goto release;
1300     }
1301
1302     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1303     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1304     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1305
1306
1307     offset = 1;
1308     while(--size) {
1309       lit >>= 8;
1310
1311       if(size == 1) {
1312         /* This is the last byte in a multibyte subtraction 
1313          * There are a couple of tricks we can do by not worrying about 
1314          * propogating the carry */
1315         if(lit == 0xff) {
1316           /* 0xff - x == ~x */
1317           if(same) {
1318             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1319             emitSKPC;
1320             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1321           } else {
1322             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1323             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1324             emitSKPC;
1325             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1326           }
1327         } else {
1328             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1329             emitSKPC;
1330             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1331             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1332             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1333         }
1334
1335         goto release;
1336       }
1337
1338       if(same) {
1339
1340         if(lit & 0xff) {
1341           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1342           emitSKPC;
1343           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1344           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1345         } else {
1346           emitSKPNC;
1347           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1348
1349         }
1350       } else {
1351
1352         if(lit & 0xff) {
1353           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1354           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1355         } else
1356           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1357
1358         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1359         emitSKPC;
1360         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1361         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1362       }
1363     }
1364   
1365
1366   } else {
1367
1368     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1369                    AopType(AOP_TYPE(IC_RESULT(ic))),
1370                    AopType(AOP_TYPE(IC_LEFT(ic))),
1371                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1372
1373     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1374       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1375       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1376       emitpcode(POC_SUBLW, popGetLit(0));
1377       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1378     } else {
1379
1380       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1381         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1382         emitpcode(POC_SUBLW, popGetLit(0));
1383         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1384           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1385       } else {
1386
1387         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1388         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1389           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1390
1391         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1392           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1393         else {
1394           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1395               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1396             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1397           } else {
1398             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1399           }
1400           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1401             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1402               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1403               emitSKPZ;
1404               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1405             }else
1406               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1407           }
1408         }
1409       }
1410     }
1411
1412     /*
1413       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1414
1415       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1416       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1417       } else {
1418       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1419       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1420       }
1421     */
1422     offset = 1;
1423     size--;
1424
1425     while(size--){
1426       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1427         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1428         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1429       }
1430       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1431       emitSKPC;
1432       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1433       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1434
1435       offset++;
1436     }
1437
1438   }
1439
1440
1441   //    adjustArithmeticResult(ic);
1442         
1443  release:
1444   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1445   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1446   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1447 }
1448
1449