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