]> git.gag.com Git - fw/sdcc/blob - src/pic/genarith.c
- signed/unsigned long comparisons now work.
[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 (operand *result,operand *left, int lit)
381 {
382
383   int size,same;
384   int lo;
385
386   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
387   size = pic14_getDataSize(result);
388
389   same = ((left == result) || (AOP(left) == AOP(result)));
390
391   if(same) {
392
393     /* Handle special cases first */
394     if(size == 1) 
395       genAddLit2byte (result, 0, lit);
396      
397     else if(size == 2) {
398       int hi = 0xff & (lit >> 8);
399       lo = lit & 0xff;
400
401       switch(hi) {
402       case 0: 
403
404         /* lit = 0x00LL */
405         DEBUGpic14_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
406         switch(lo) {
407         case 0:
408           break;
409         case 1:
410           emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
411           emitSKPNZ;
412           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
413           break;
414         case 0xff:
415           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
416           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
417           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
418
419           break;
420         default:
421           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
422           emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
423           emitSKPNC;
424           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
425
426
427         }
428         break;
429
430       case 1:
431         /* lit = 0x01LL */
432         DEBUGpic14_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
433         switch(lo) {
434         case 0:  /* 0x0100 */
435           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
436           break;
437         case 1:  /* 0x0101  */
438           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
439           emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
440           emitSKPNZ;
441           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
442           break;
443         case 0xff: /* 0x01ff */
444           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
445           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
446           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
447           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));   
448         }         
449         break;
450
451       case 0xff:
452         DEBUGpic14_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
453         /* lit = 0xffLL */
454         switch(lo) {
455         case 0:  /* 0xff00 */
456           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
457           break;
458         case 1:  /*0xff01 */
459           emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
460           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
461           break;
462 /*      case 0xff: * 0xffff *
463           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
464           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
465           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
466           break;
467 */
468         default:
469           emitpcode(POC_MOVLW,popGetLit(lo));
470           emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
471           emitSKPC;
472           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
473           
474         }
475
476         break;
477         
478       default:
479         DEBUGpic14_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
480
481         /* lit = 0xHHLL */
482         switch(lo) {
483         case 0:  /* 0xHH00 */
484           genAddLit2byte (result, MSB16, hi);
485           break;
486         case 1:  /* 0xHH01 */
487           emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
488           emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
489           emitpcode(POC_MOVLW,popGetLit(hi));
490           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
491           break;
492 /*      case 0xff: * 0xHHff *
493           emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
494           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
495           emitpcode(POC_MOVLW,popGetLit(hi));
496           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
497           break;
498 */      default:  /* 0xHHLL */
499           emitpcode(POC_MOVLW,popGetLit(lo));
500           emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
501           emitpcode(POC_MOVLW,popGetLit(hi));
502           emitSKPNC;
503           emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
504           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
505           break;
506         }
507
508       }
509     } else {
510       int carry_info = 0;
511       int offset = 0;
512       /* size > 2 */
513       DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
514
515       while(size--) {
516         lo = BYTEofLONG(lit,0);
517
518         if(carry_info) {
519           switch(lo) {
520           case 0:
521             switch(carry_info) {
522             case 1:
523               emitSKPNZ;
524               emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
525               break;
526             case 2:
527               emitpcode(POC_RLFW, popGet(AOP(result),offset,FALSE,FALSE));
528               emitpcode(POC_ANDLW,popGetLit(1));
529               emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
530               break;
531             default: /* carry_info = 3  */
532               emitSKPNC;
533               emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
534               carry_info = 1;
535               break;
536             }
537             break;
538           case 0xff:
539             emitpcode(POC_MOVLW,popGetLit(lo));
540             if(carry_info==1) 
541               emitSKPZ;
542             else
543               emitSKPC;
544             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
545             break;
546           default:
547             emitpcode(POC_MOVLW,popGetLit(lo));
548             if(carry_info==1) 
549               emitSKPNZ;
550             else
551               emitSKPNC;
552             emitpcode(POC_MOVLW,popGetLit(lo+1));
553             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
554             carry_info=2;
555             break;
556           }
557         }else {
558           /* no carry info from previous step */
559           /* this means this is the first time to add */
560           switch(lo) {
561           case 0:
562             break;
563           case 1:
564             emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
565             carry_info=1;
566             break;
567           default:
568             emitpcode(POC_MOVLW,popGetLit(lo));
569             emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
570             if(lit <0x100) 
571               carry_info = 3;  /* Were adding only one byte and propogating the carry */
572             else
573               carry_info = 2;
574             break;
575           }
576         }
577         offset++;
578         lit >>= 8;
579       }
580     
581 /*
582       lo = BYTEofLONG(lit,0);
583
584       if(lit < 0x100) {
585         if(lo) {
586           if(lo == 1) {
587             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
588             emitSKPNZ;
589           } else {
590             emitpcode(POC_MOVLW,popGetLit(lo));
591             emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
592             emitSKPNC;
593           }
594           emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
595           emitSKPNZ;
596           emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
597           emitSKPNZ;
598           emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
599
600         } 
601       } 
602     }
603
604 */
605     }
606   } else {
607     int offset = 1;
608     DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
609
610     if(size == 1) {
611
612       switch(lit & 0xff) {
613       case 0:
614         emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
615         emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
616         break;
617       case 1:
618         emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE));
619         emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
620         break;
621       case 0xff:
622         emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE));
623         emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
624         break;
625       default:
626         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
627         emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
628         emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
629       }
630
631
632     } else {
633
634       if(lit & 0xff) {
635         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
636         emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
637       } else
638         emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
639
640       emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
641       lit >>= 8;
642       while(--size) {
643       
644         if(lit & 0xff) {
645           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
646           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
647           emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
648           emitSKPNC;
649           emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
650           emitpcode(POC_ADDWF,  popGet(AOP(result),offset,FALSE,FALSE));
651         } else {
652           emitpcode(POC_CLRF,  popGet(AOP(result),offset,FALSE,FALSE));
653           emitpcode(POC_RLF,   popGet(AOP(result),offset,FALSE,FALSE));
654           emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
655           emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
656         }
657       offset++;
658       }
659     }
660   }
661 }
662
663 /*-----------------------------------------------------------------*/
664 /* genPlus - generates code for addition                           */
665 /*-----------------------------------------------------------------*/
666 void genPlus (iCode *ic)
667 {
668   int size, offset = 0;
669
670   /* special cases :- */
671   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
672
673   aopOp (IC_LEFT(ic),ic,FALSE);
674   aopOp (IC_RIGHT(ic),ic,FALSE);
675   aopOp (IC_RESULT(ic),ic,TRUE);
676
677   /* if literal, literal on the right or
678      if left requires ACC or right is already
679      in ACC */
680
681   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
682     operand *t = IC_RIGHT(ic);
683     IC_RIGHT(ic) = IC_LEFT(ic);
684     IC_LEFT(ic) = t;
685   }
686
687   /* if both left & right are in bit space */
688   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
689       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
690     genPlusBits (ic);
691     goto release ;
692   }
693
694   /* if left in bit space & right literal */
695   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
696       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
697     /* if result in bit space */
698     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
699       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
700         emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
701         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
702           emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
703         emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
704       }
705     } else {
706       size = pic14_getDataSize(IC_RESULT(ic));
707       while (size--) {
708         MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
709         pic14_emitcode("addc","a,#00  ;%d",__LINE__);
710         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
711       }
712     }
713     goto release ;
714   }
715
716   /* if I can do an increment instead
717      of add then GOOD for ME */
718   if (genPlusIncr (ic) == TRUE)
719     goto release;   
720
721   size = pic14_getDataSize(IC_RESULT(ic));
722
723   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
724     /* Add a literal to something else */
725     //bool know_W=0;
726     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
727     //      unsigned l1=0;
728
729     //      offset = 0;
730     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
731
732     genAddLit ( IC_RESULT(ic),IC_LEFT(ic),  lit);
733 #if 0
734     while(size--){
735
736       DEBUGpic14_emitcode(";","size %d",size);
737
738       switch (lit & 0xff) {
739       case 0:
740         break;
741       case 1:
742         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
743           emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
744         else {
745           know_W = 0;
746           emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
747           if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
748             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
749         }
750         break;
751       case 0xff:
752         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
753           emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
754         else {
755           know_W = 0;
756           emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
757           if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
758             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
759         }
760         break;
761       default:
762         if( !know_W || ( (lit&0xff) != l1)  ) {
763           know_W = 1;
764           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
765         }
766         if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
767           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
768           if(size) {
769             emitSKPNC;
770             emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
771           }
772
773         } else {
774           know_W = 0;
775           emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
776           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
777           if(size) {
778             emitSKPNC;
779             emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE));
780           }
781         }
782       }
783
784       l1 = lit & 0xff;
785       lit >>= 8;
786       offset++;
787     }
788 #endif
789
790   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
791
792     pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
793     pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
794     pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
795
796     /* here we are adding a bit to a char or int */
797     if(size == 1) {
798       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
799
800         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
801         emitpcode(POC_INCF ,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
802
803         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
804                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
805                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
806         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
807       } else {
808
809         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
810           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
811           emitpcode(POC_XORLW , popGetLit(1));
812
813           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
814                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
815                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
816           pic14_emitcode(" xorlw","1");
817         } else {
818           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
819           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
820           emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
821
822           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
823           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
824                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
825                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
826           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
827         }
828           
829         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
830             
831           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
832             emitpcode(POC_ANDLW , popGetLit(1));
833             emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
834             emitSKPZ;
835             emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
836           } else {
837             emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
838             pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
839           }
840         }
841       }
842
843     } else {
844       int offset = 1;
845
846       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
847         emitCLRZ;
848         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
849         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
850
851         pic14_emitcode("clrz","");
852
853         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
854                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
855                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
856         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
857
858       } else {
859
860         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
861         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
862         emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
863         emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
864
865
866         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
867         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
868                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
869                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
870         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
871         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
872
873       }
874
875       while(--size){
876         emitSKPZ;
877         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
878         //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
879       }
880
881     }
882       
883   } else {
884     
885     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
886       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
887       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
888     } else {
889
890       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
891         emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
892         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
893           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
894       } else {
895
896         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
897
898         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
899           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
900         else {
901           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
902               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
903             emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
904           } else {
905             emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
906             if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
907               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
908           }
909         }
910       }
911     }
912
913     offset = 1;
914     size--;
915
916     while(size--){
917       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
918         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
919         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
920
921         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
922         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
923       }
924
925       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
926       emitSKPNC;
927       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
928       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
929
930       /*
931         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
932         emitSKPNC;
933         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
934         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
935       */
936
937       offset++;
938     }
939
940   }
941
942   //adjustArithmeticResult(ic);
943
944  release:
945   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
946   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
947   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
948 }
949
950 /*-----------------------------------------------------------------*/
951 /* genMinusDec :- does subtraction with decrement if possible     */
952 /*-----------------------------------------------------------------*/
953 bool genMinusDec (iCode *ic)
954 {
955     unsigned int icount ;
956     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
957
958     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
959     /* will try to generate an increment */
960     /* if the right side is not a literal 
961     we cannot */
962     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
963         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
964         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
965         return FALSE ;
966
967     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
968
969     /* if the literal value of the right hand side
970     is greater than 4 then it is not worth it */
971     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
972         return FALSE ;
973
974     /* if decrement 16 bits in register */
975     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
976         (size > 1) &&
977         (icount == 1)) {
978
979       if(size == 2) { 
980         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
981         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
982         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
983         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
984
985         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
986         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
987         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
988       } else {
989         /* size is 3 or 4 */
990         emitpcode(POC_MOVLW,  popGetLit(0xff));
991         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
992         emitSKPNC;
993         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
994         emitSKPNC;
995         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
996
997         pic14_emitcode("movlw","0xff");
998         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
999
1000         emitSKPNC;
1001         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1002         emitSKPNC;
1003         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1004
1005         if(size > 3) {
1006           emitSKPNC;
1007           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1008
1009           pic14_emitcode("skpnc","");
1010           emitSKPNC;
1011           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1012         }
1013
1014       }
1015
1016       return TRUE;
1017
1018     }
1019
1020     /* if the sizes are greater than 1 then we cannot */
1021     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1022         AOP_SIZE(IC_LEFT(ic)) > 1   )
1023         return FALSE ;
1024
1025     /* we can if the aops of the left & result match or
1026     if they are in registers and the registers are the
1027     same */
1028     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1029
1030       while (icount--) 
1031         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1032
1033         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1034
1035         return TRUE ;
1036     }
1037
1038     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1039                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1040                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1041     if(size==1) {
1042
1043       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1044       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1045
1046       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1047       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1048
1049       return TRUE;
1050     }
1051
1052     return FALSE ;
1053 }
1054
1055 /*-----------------------------------------------------------------*/
1056 /* addSign - complete with sign                                    */
1057 /*-----------------------------------------------------------------*/
1058 void addSign(operand *result, int offset, int sign)
1059 {
1060     int size = (pic14_getDataSize(result) - offset);
1061     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1062     if(size > 0){
1063         if(sign){
1064             pic14_emitcode("rlc","a");
1065             pic14_emitcode("subb","a,acc");
1066             while(size--)
1067                 aopPut(AOP(result),"a",offset++); 
1068         } else
1069             while(size--)
1070                 aopPut(AOP(result),"#0",offset++);
1071     }
1072 }
1073
1074 /*-----------------------------------------------------------------*/
1075 /* genMinusBits - generates code for subtraction  of two bits      */
1076 /*-----------------------------------------------------------------*/
1077 void genMinusBits (iCode *ic)
1078 {
1079     symbol *lbl = newiTempLabel(NULL);
1080     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1081     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1082         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1083         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1084         pic14_emitcode("cpl","c");
1085         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1086         pic14_outBitC(IC_RESULT(ic));
1087     }
1088     else{
1089         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1090         pic14_emitcode("subb","a,acc");
1091         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1092         pic14_emitcode("inc","a");
1093         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1094         aopPut(AOP(IC_RESULT(ic)),"a",0);
1095         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1096     }
1097 }
1098
1099 /*-----------------------------------------------------------------*/
1100 /* genMinus - generates code for subtraction                       */
1101 /*-----------------------------------------------------------------*/
1102 void genMinus (iCode *ic)
1103 {
1104   int size, offset = 0,same;
1105   unsigned long lit = 0L;
1106
1107   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1108   aopOp (IC_LEFT(ic),ic,FALSE);
1109   aopOp (IC_RIGHT(ic),ic,FALSE);
1110   aopOp (IC_RESULT(ic),ic,TRUE);
1111
1112   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1113       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1114     operand *t = IC_RIGHT(ic);
1115     IC_RIGHT(ic) = IC_LEFT(ic);
1116     IC_LEFT(ic) = t;
1117   }
1118
1119   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1120                    AopType(AOP_TYPE(IC_RESULT(ic))),
1121                    AopType(AOP_TYPE(IC_LEFT(ic))),
1122                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1123
1124   /* special cases :- */
1125   /* if both left & right are in bit space */
1126   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1127       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1128     genPlusBits (ic);
1129     goto release ;
1130   }
1131
1132   /* if I can do an decrement instead
1133      of subtract then GOOD for ME */
1134   //  if (genMinusDec (ic) == TRUE)
1135   //    goto release;   
1136
1137   size = pic14_getDataSize(IC_RESULT(ic));   
1138   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1139
1140   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1141     /* Add a literal to something else */
1142
1143     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1144     lit = - (long)lit;
1145
1146     genAddLit ( IC_RESULT(ic),IC_LEFT(ic),  lit);
1147     
1148 #if 0
1149     /* add the first byte: */
1150     pic14_emitcode("movlw","0x%x", lit & 0xff);
1151     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1152     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1153     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1154
1155
1156     offset = 1;
1157     size--;
1158
1159     while(size-- > 0) {
1160
1161       lit >>= 8;
1162
1163       if(lit & 0xff) {
1164
1165         if((lit & 0xff) == 0xff) {
1166           emitpcode(POC_MOVLW,  popGetLit(0xff));
1167           emitSKPC;
1168           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1169         } else {
1170           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1171           emitSKPNC;
1172           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1173           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1174         }
1175
1176       } else {
1177         /* do the rlf known zero trick here */
1178         emitpcode(POC_MOVLW,  popGetLit(1));
1179         emitSKPNC;
1180         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1181       }
1182       offset++;
1183     }
1184 #endif
1185   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1186     // bit subtraction
1187
1188     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1189     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1190     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1191
1192     /* here we are subtracting a bit from a char or int */
1193     if(size == 1) {
1194       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1195
1196         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1197         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1198
1199         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1200                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1201                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1202         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1203       } else {
1204
1205         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1206           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1207           emitpcode(POC_XORLW , popGetLit(1));
1208         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1209               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1210
1211           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1212
1213           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1214             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1215               if(lit & 1) {
1216                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1217                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1218               }
1219             }else{
1220               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1221               if(lit & 1) 
1222                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1223               else
1224                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1225               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1226             }
1227             goto release;
1228           } else {
1229             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1230             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1231             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1232             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1233
1234           }
1235
1236         } else {
1237           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1238           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1239           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1240         }
1241           
1242         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1243             
1244           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1245
1246         } else  {
1247           emitpcode(POC_ANDLW , popGetLit(1));
1248 /*
1249           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1250           emitSKPZ;
1251           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1252 */
1253         }
1254
1255       }
1256
1257     }
1258   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1259               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1260               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1261
1262     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1263     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1264                    AopType(AOP_TYPE(IC_RESULT(ic))),
1265                    AopType(AOP_TYPE(IC_LEFT(ic))),
1266                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1267
1268
1269     if( (size == 1) && ((lit & 0xff) == 0) ) {
1270       /* res = 0 - right */
1271       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1272         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1273       } else { 
1274         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1275         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1276       }
1277       goto release;
1278     }
1279
1280     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1281     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1282     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1283
1284
1285     offset = 1;
1286     while(--size) {
1287       lit >>= 8;
1288
1289       if(size == 1) {
1290         /* This is the last byte in a multibyte subtraction 
1291          * There are a couple of tricks we can do by not worrying about 
1292          * propogating the carry */
1293         if(lit == 0xff) {
1294           /* 0xff - x == ~x */
1295           if(same) {
1296             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1297             emitSKPC;
1298             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1299           } else {
1300             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1301             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1302             emitSKPC;
1303             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1304           }
1305         } else {
1306             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1307             emitSKPC;
1308             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1309             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1310             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1311         }
1312
1313         goto release;
1314       }
1315
1316       if(same) {
1317
1318         if(lit & 0xff) {
1319           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1320           emitSKPC;
1321           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1322           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1323         } else {
1324           emitSKPNC;
1325           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1326
1327         }
1328       } else {
1329
1330         if(lit & 0xff) {
1331           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1332           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1333         } else
1334           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1335
1336         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1337         emitSKPC;
1338         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1339         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1340       }
1341     }
1342   
1343
1344   } else {
1345
1346     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1347                    AopType(AOP_TYPE(IC_RESULT(ic))),
1348                    AopType(AOP_TYPE(IC_LEFT(ic))),
1349                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1350
1351     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1352       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1353       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1354       emitpcode(POC_SUBLW, popGetLit(0));
1355       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1356     } else {
1357
1358       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1359         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1360         emitpcode(POC_SUBLW, popGetLit(0));
1361         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1362           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1363       } else {
1364
1365         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1366         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1367           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1368
1369         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1370           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1371         else {
1372           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1373               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1374             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1375           } else {
1376             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1377           }
1378           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1379             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1380               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1381               emitSKPZ;
1382               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1383             }else
1384               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1385           }
1386         }
1387       }
1388     }
1389
1390     /*
1391       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1392
1393       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1394       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1395       } else {
1396       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1397       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1398       }
1399     */
1400     offset = 1;
1401     size--;
1402
1403     while(size--){
1404       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1405         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1406         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1407       }
1408       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1409       emitSKPC;
1410       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1411       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1412
1413       offset++;
1414     }
1415
1416   }
1417
1418
1419   //    adjustArithmeticResult(ic);
1420         
1421  release:
1422   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1423   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1424   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1425 }
1426
1427