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