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