Added regression tests for compound comparisons.
[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) && (_MSC_VER < 1300)
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   case AOP_PCODE:
110     return "AOP_PCODE";
111     break;
112   }
113
114   return "BAD TYPE";
115 }
116
117 const char *pCodeOpType(  pCodeOp *pcop)
118 {
119
120   if(pcop) {
121
122     switch(pcop->type) {
123
124     case  PO_NONE:
125       return "PO_NONE";
126     case  PO_W:
127       return  "PO_W";
128     case  PO_STATUS:
129       return  "PO_STATUS";
130     case  PO_FSR:
131       return  "PO_FSR";
132     case  PO_INDF:
133       return  "PO_INDF";
134     case  PO_INTCON:
135       return  "PO_INTCON";
136     case  PO_GPR_REGISTER:
137       return  "PO_GPR_REGISTER";
138     case  PO_GPR_BIT:
139       return  "PO_GPR_BIT";
140     case  PO_GPR_TEMP:
141       return  "PO_GPR_TEMP";
142     case  PO_SFR_REGISTER:
143       return  "PO_SFR_REGISTER";
144     case  PO_PCL:
145       return  "PO_PCL";
146     case  PO_PCLATH:
147       return  "PO_PCLATH";
148     case  PO_LITERAL:
149       return  "PO_LITERAL";
150     case  PO_IMMEDIATE:
151       return  "PO_IMMEDIATE";
152     case  PO_DIR:
153       return  "PO_DIR";
154     case  PO_CRY:
155       return  "PO_CRY";
156     case  PO_BIT:
157       return  "PO_BIT";
158     case  PO_STR:
159       return  "PO_STR";
160     case  PO_LABEL:
161       return  "PO_LABEL";
162     case  PO_WILD:
163       return  "PO_WILD";
164     }
165   }
166
167   return "BAD PO_TYPE";
168 }
169
170 /*-----------------------------------------------------------------*/
171 /* genPlusIncr :- does addition with increment if possible         */
172 /*-----------------------------------------------------------------*/
173 bool genPlusIncr (iCode *ic)
174 {
175     unsigned int icount ;
176     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
177
178     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
179     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
180                          AopType(AOP_TYPE(IC_RESULT(ic))),
181                          AopType(AOP_TYPE(IC_LEFT(ic))),
182                          AopType(AOP_TYPE(IC_RIGHT(ic))));
183
184     /* will try to generate an increment */
185     /* if the right side is not a literal 
186        we cannot */
187     if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
188         return FALSE ;
189     
190     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
191     /* if the literal value of the right hand side
192        is greater than 1 then it is faster to add */
193     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
194         return FALSE ;
195     
196     /* if increment 16 bits in register */
197     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
198         (icount == 1)) {
199
200       int offset = MSB16;
201
202       emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
203       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
204
205       while(--size) {
206         emitSKPNZ;
207         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
208         //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
209       }
210
211       return TRUE;
212     }
213     
214     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
215     /* if left is in accumulator  - probably a bit operation*/
216     if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a")  &&
217         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
218       
219       emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
220       pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
221                AOP(IC_RESULT(ic))->aopu.aop_dir,
222                AOP(IC_RESULT(ic))->aopu.aop_dir);
223       if(icount)
224         emitpcode(POC_XORLW,popGetLit(1));
225       //pic14_emitcode("xorlw","1");
226       else
227         emitpcode(POC_ANDLW,popGetLit(1));
228       //pic14_emitcode("andlw","1");
229
230       emitSKPZ;
231       emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
232       pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
233                AOP(IC_RESULT(ic))->aopu.aop_dir,
234                AOP(IC_RESULT(ic))->aopu.aop_dir);
235
236       return TRUE;
237     }
238
239
240
241     /* if the sizes are greater than 1 then we cannot */
242     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
243         AOP_SIZE(IC_LEFT(ic)) > 1   )
244         return FALSE ;
245     
246     /* If we are incrementing the same register by two: */
247
248     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
249         
250       while (icount--) 
251         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
252       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
253         
254       return TRUE ;
255     }
256     
257     DEBUGpic14_emitcode ("; ","couldn't increment ");
258
259     return FALSE ;
260 }
261
262 /*-----------------------------------------------------------------*/
263 /* pic14_outBitAcc - output a bit in acc                                 */
264 /*-----------------------------------------------------------------*/
265 void pic14_outBitAcc(operand *result)
266 {
267     symbol *tlbl = newiTempLabel(NULL);
268     /* if the result is a bit */
269     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
270
271     if (AOP_TYPE(result) == AOP_CRY){
272         aopPut(AOP(result),"a",0);
273     }
274     else {
275         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
276         pic14_emitcode("mov","a,#01");
277         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
278         pic14_outAcc(result);
279     }
280 }
281
282 /*-----------------------------------------------------------------*/
283 /* genPlusBits - generates code for addition of two bits           */
284 /*-----------------------------------------------------------------*/
285 void genPlusBits (iCode *ic)
286 {
287
288   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
289
290   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
291                        AopType(AOP_TYPE(IC_RESULT(ic))),
292                        AopType(AOP_TYPE(IC_LEFT(ic))),
293                        AopType(AOP_TYPE(IC_RIGHT(ic))));
294   /*
295     The following block of code will add two bits. 
296     Note that it'll even work if the destination is
297     the carry (C in the status register).
298     It won't work if the 'Z' bit is a source or destination.
299   */
300
301   /* If the result is stored in the accumulator (w) */
302   //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
303   switch(AOP_TYPE(IC_RESULT(ic))) {
304   case AOP_ACC:
305     emitpcode(POC_CLRW, NULL);
306     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
307     emitpcode(POC_XORLW, popGetLit(1));
308     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
309     emitpcode(POC_XORLW, popGetLit(1));
310
311     pic14_emitcode("clrw","");
312     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
313                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
314                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
315     pic14_emitcode("xorlw","1");
316     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
317                    AOP(IC_LEFT(ic))->aopu.aop_dir,
318                    AOP(IC_LEFT(ic))->aopu.aop_dir);
319     pic14_emitcode("xorlw","1");
320     break;
321   case AOP_REG:
322     emitpcode(POC_MOVLW, popGetLit(0));
323     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
324     emitpcode(POC_XORLW, popGetLit(1));
325     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
326     emitpcode(POC_XORLW, popGetLit(1));
327     emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
328     break;
329   default:
330     emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
331     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
332     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
333     emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
334     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
335     emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
336
337     pic14_emitcode("movlw","(1 << (%s & 7))",
338                    AOP(IC_RESULT(ic))->aopu.aop_dir,
339                    AOP(IC_RESULT(ic))->aopu.aop_dir);
340     pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
341                    AOP(IC_RESULT(ic))->aopu.aop_dir,
342                    AOP(IC_RESULT(ic))->aopu.aop_dir);
343     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
344                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
345                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
346     pic14_emitcode("xorwf","(%s >>3),f",
347                    AOP(IC_RESULT(ic))->aopu.aop_dir);
348     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
349                    AOP(IC_LEFT(ic))->aopu.aop_dir,
350                    AOP(IC_LEFT(ic))->aopu.aop_dir);
351     pic14_emitcode("xorwf","(%s>>3),f",
352                    AOP(IC_RESULT(ic))->aopu.aop_dir);
353     break;
354   }
355
356 }
357
358 #if 0
359 /* This is the original version of this code.
360  *
361  * This is being kept around for reference, 
362  * because I am not entirely sure I got it right...
363  */
364 static void adjustArithmeticResult(iCode *ic)
365 {
366     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
367         AOP_SIZE(IC_LEFT(ic)) == 3   &&
368         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
369         aopPut(AOP(IC_RESULT(ic)),
370                aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
371                2);
372
373     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
374         AOP_SIZE(IC_RIGHT(ic)) == 3   &&
375         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
376         aopPut(AOP(IC_RESULT(ic)),
377                aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
378                2);
379     
380     if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
381         AOP_SIZE(IC_LEFT(ic)) < 3    &&
382         AOP_SIZE(IC_RIGHT(ic)) < 3   &&
383         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
384         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
385         char buffer[5];
386         sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
387         aopPut(AOP(IC_RESULT(ic)),buffer,2);
388     }
389 }
390 //#else
391 /* This is the pure and virtuous version of this code.
392  * I'm pretty certain it's right, but not enough to toss the old 
393  * code just yet...
394  */
395 static void adjustArithmeticResult(iCode *ic)
396 {
397     if (opIsGptr(IC_RESULT(ic)) &&
398         opIsGptr(IC_LEFT(ic))   &&
399         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
400     {
401         aopPut(AOP(IC_RESULT(ic)),
402                aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
403                GPTRSIZE - 1);
404     }
405
406     if (opIsGptr(IC_RESULT(ic)) &&
407         opIsGptr(IC_RIGHT(ic))   &&
408         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
409     {
410         aopPut(AOP(IC_RESULT(ic)),
411                aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
412                GPTRSIZE - 1);
413     }
414
415     if (opIsGptr(IC_RESULT(ic))            &&
416         AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
417         AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
418          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
419          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
420          char buffer[5];
421          sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
422          aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
423      }
424 }
425 #endif
426
427 /*-----------------------------------------------------------------*/
428 /* genAddlit - generates code for addition                         */
429 /*-----------------------------------------------------------------*/
430 static void genAddLit2byte (operand *result, int offr, int lit)
431 {
432
433   switch(lit & 0xff) {
434   case 0:
435     break;
436   case 1:
437     emitpcode(POC_INCF, popGet(AOP(result),offr));
438     break;
439   case 0xff:
440     emitpcode(POC_DECF, popGet(AOP(result),offr));
441     break;
442   default:
443     emitpcode(POC_MOVLW,popGetLit(lit&0xff));
444     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
445   }
446
447 }
448
449 static void emitMOVWF(operand *reg, int offset)
450 {
451   if(!reg)
452     return;
453
454   if (AOP_TYPE(reg) == AOP_ACC) {
455     DEBUGpic14_emitcode ("; ***","%s  %d ignoring mov into W",__FUNCTION__,__LINE__);
456     return;
457   }
458
459   emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
460
461 }
462
463 static void genAddLit (iCode *ic, int lit)
464 {
465
466   int size,same;
467   int lo;
468
469   operand *result;
470   operand *left;
471
472   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
473
474
475   left = IC_LEFT(ic);
476   result = IC_RESULT(ic);
477   same = pic14_sameRegs(AOP(left), AOP(result));
478   size = pic14_getDataSize(result);
479
480   if(same) {
481
482     /* Handle special cases first */
483     if(size == 1) 
484       genAddLit2byte (result, 0, lit);
485      
486     else if(size == 2) {
487       int hi = 0xff & (lit >> 8);
488       lo = lit & 0xff;
489
490       switch(hi) {
491       case 0: 
492
493         /* lit = 0x00LL */
494         DEBUGpic14_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
495         switch(lo) {
496         case 0:
497           break;
498         case 1:
499           emitpcode(POC_INCF, popGet(AOP(result),0));
500           emitSKPNZ;
501           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
502           break;
503         case 0xff:
504           emitpcode(POC_DECF, popGet(AOP(result),0));
505           emitpcode(POC_INCFSZW, popGet(AOP(result),0));
506           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
507
508           break;
509         default:
510           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
511           emitpcode(POC_ADDWF,popGet(AOP(result),0));
512           emitSKPNC;
513           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
514
515
516         }
517         break;
518
519       case 1:
520         /* lit = 0x01LL */
521         DEBUGpic14_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
522         switch(lo) {
523         case 0:  /* 0x0100 */
524           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
525           break;
526         case 1:  /* 0x0101  */
527           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
528           emitpcode(POC_INCF, popGet(AOP(result),0));
529           emitSKPNZ;
530           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
531           break;
532         case 0xff: /* 0x01ff */
533           emitpcode(POC_DECF, popGet(AOP(result),0));
534           emitpcode(POC_INCFSZW, popGet(AOP(result),0));
535           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
536           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
537         }         
538         break;
539
540       case 0xff:
541         DEBUGpic14_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
542         /* lit = 0xffLL */
543         switch(lo) {
544         case 0:  /* 0xff00 */
545           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
546           break;
547         case 1:  /*0xff01 */
548           emitpcode(POC_INCFSZ, popGet(AOP(result),0));
549           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
550           break;
551 /*      case 0xff: * 0xffff *
552           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
553           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
554           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
555           break;
556 */
557         default:
558           emitpcode(POC_MOVLW,popGetLit(lo));
559           emitpcode(POC_ADDWF,popGet(AOP(result),0));
560           emitSKPC;
561           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
562           
563         }
564
565         break;
566         
567       default:
568         DEBUGpic14_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
569
570         /* lit = 0xHHLL */
571         switch(lo) {
572         case 0:  /* 0xHH00 */
573           genAddLit2byte (result, MSB16, hi);
574           break;
575         case 1:  /* 0xHH01 */
576           emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
577           emitpcode(POC_INCFSZ, popGet(AOP(result),0));
578           emitpcode(POC_MOVLW,popGetLit(hi));
579           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
580           break;
581 /*      case 0xff: * 0xHHff *
582           emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
583           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
584           emitpcode(POC_MOVLW,popGetLit(hi));
585           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
586           break;
587 */      default:  /* 0xHHLL */
588           emitpcode(POC_MOVLW,popGetLit(lo));
589           emitpcode(POC_ADDWF, popGet(AOP(result),0));
590           emitpcode(POC_MOVLW,popGetLit(hi));
591           emitSKPNC;
592           emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
593           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
594           break;
595         }
596
597       }
598     } else {
599       int carry_info = 0;
600       int offset = 0;
601       /* size > 2 */
602       DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
603
604       while(size--) {
605         lo = BYTEofLONG(lit,0);
606
607         if(carry_info) {
608           switch(lo) {
609           case 0:
610             switch(carry_info) {
611             case 1:
612               emitSKPNZ;
613               emitpcode(POC_INCF, popGet(AOP(result),offset));
614               break;
615             case 2:
616               emitpcode(POC_RLFW, popGet(AOP(result),offset));
617               emitpcode(POC_ANDLW,popGetLit(1));
618               emitpcode(POC_ADDWF, popGet(AOP(result),offset));
619               break;
620             default: /* carry_info = 3  */
621               emitSKPNC;
622               emitpcode(POC_INCF, popGet(AOP(result),offset));
623               carry_info = 1;
624               break;
625             }
626             break;
627           case 0xff:
628             emitpcode(POC_MOVLW,popGetLit(lo));
629             if(carry_info==1) 
630               emitSKPZ;
631             else
632               emitSKPC;
633             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
634             break;
635           default:
636             emitpcode(POC_MOVLW,popGetLit(lo));
637             if(carry_info==1) 
638               emitSKPNZ;
639             else
640               emitSKPNC;
641             emitpcode(POC_MOVLW,popGetLit(lo+1));
642             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
643             carry_info=2;
644             break;
645           }
646         }else {
647           /* no carry info from previous step */
648           /* this means this is the first time to add */
649           switch(lo) {
650           case 0:
651             break;
652           case 1:
653             emitpcode(POC_INCF, popGet(AOP(result),offset));
654             carry_info=1;
655             break;
656           default:
657             emitpcode(POC_MOVLW,popGetLit(lo));
658             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
659             if(lit <0x100) 
660               carry_info = 3;  /* Were adding only one byte and propogating the carry */
661             else
662               carry_info = 2;
663             break;
664           }
665         }
666         offset++;
667         lit >>= 8;
668       }
669     
670 /*
671       lo = BYTEofLONG(lit,0);
672
673       if(lit < 0x100) {
674         if(lo) {
675           if(lo == 1) {
676             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
677             emitSKPNZ;
678           } else {
679             emitpcode(POC_MOVLW,popGetLit(lo));
680             emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
681             emitSKPNC;
682           }
683           emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
684           emitSKPNZ;
685           emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
686           emitSKPNZ;
687           emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
688
689         } 
690       } 
691     }
692
693 */
694     }
695   } else {
696     int offset = 1;
697     DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
698
699     if(size == 1) {
700
701       if(AOP_TYPE(left) == AOP_ACC) {
702         /* left addend is already in accumulator */
703         switch(lit & 0xff) {
704         case 0:
705           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
706           emitMOVWF(result,0);
707           break;
708         default:
709           emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
710           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
711           emitMOVWF(result,0);
712         }
713       } else {
714         /* left addend is in a register */
715         switch(lit & 0xff) {
716         case 0:
717           emitpcode(POC_MOVFW, popGet(AOP(left),0));
718           emitMOVWF(result, 0);
719           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
720           emitMOVWF(result,0);
721           break;
722         case 1:
723           emitpcode(POC_INCFW, popGet(AOP(left),0));
724           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
725           emitMOVWF(result,0);
726           break;
727         case 0xff:
728           emitpcode(POC_DECFW, popGet(AOP(left),0));
729           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
730           emitMOVWF(result,0);
731           break;
732         default:
733           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
734           emitpcode(POC_ADDFW, popGet(AOP(left),0));
735           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
736           emitMOVWF(result,0);
737         }
738       }
739
740     } else {
741       int clear_carry=0;
742
743       /* left is not the accumulator */
744       if(lit & 0xff) {
745         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
746         emitpcode(POC_ADDFW, popGet(AOP(left),0));
747       } else {
748         emitpcode(POC_MOVFW, popGet(AOP(left),0));
749         /* We don't know the state of the carry bit at this point */
750         clear_carry = 1;
751       }
752       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
753       emitMOVWF(result,0);
754       while(--size) {
755       
756         lit >>= 8;
757         if(lit & 0xff) {
758           if(clear_carry) {
759             /* The ls byte of the lit must've been zero - that 
760                means we don't have to deal with carry */
761
762             emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
763             emitpcode(POC_ADDFW,  popGet(AOP(left),offset));
764             emitpcode(POC_MOVWF, popGet(AOP(left),offset));
765
766             clear_carry = 0;
767
768           } else {
769             emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
770             //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
771             emitMOVWF(result,offset);
772             emitpcode(POC_MOVFW, popGet(AOP(left),offset));
773             emitSKPNC;
774             emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
775             emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
776           }
777
778         } else {
779           emitpcode(POC_CLRF,  popGet(AOP(result),offset));
780           emitpcode(POC_RLF,   popGet(AOP(result),offset));
781           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
782           emitpcode(POC_ADDWF, popGet(AOP(result),offset));
783         }
784         offset++;
785       }
786     }
787   }
788 }
789
790 /*-----------------------------------------------------------------*/
791 /* genPlus - generates code for addition                           */
792 /*-----------------------------------------------------------------*/
793 void genPlus (iCode *ic)
794 {
795   int size, offset = 0;
796
797   /* special cases :- */
798   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
799
800   aopOp (IC_LEFT(ic),ic,FALSE);
801   aopOp (IC_RIGHT(ic),ic,FALSE);
802   aopOp (IC_RESULT(ic),ic,TRUE);
803
804   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
805
806   /* if literal, literal on the right or
807      if left requires ACC or right is already
808      in ACC */
809
810   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
811     operand *t = IC_RIGHT(ic);
812     IC_RIGHT(ic) = IC_LEFT(ic);
813     IC_LEFT(ic) = t;
814   }
815
816   /* if both left & right are in bit space */
817   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
818       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
819     genPlusBits (ic);
820     goto release ;
821   }
822
823   /* if left in bit space & right literal */
824   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
825       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
826     /* if result in bit space */
827     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
828       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
829         emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
830         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
831           emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
832         emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
833       }
834     } else {
835       size = pic14_getDataSize(IC_RESULT(ic));
836       while (size--) {
837         MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
838         pic14_emitcode("addc","a,#00  ;%d",__LINE__);
839         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
840       }
841     }
842     goto release ;
843   }
844
845   /* if I can do an increment instead
846      of add then GOOD for ME */
847   if (genPlusIncr (ic) == TRUE)
848     goto release;   
849
850   size = pic14_getDataSize(IC_RESULT(ic));
851
852   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
853     /* Add a literal to something else */
854     //bool know_W=0;
855     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
856     //      unsigned l1=0;
857
858     //      offset = 0;
859     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
860
861     genAddLit (ic,  lit);
862     goto release;
863
864   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
865
866     pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
867     pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
868     pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
869
870     /* here we are adding a bit to a char or int */
871     if(size == 1) {
872       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
873
874         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
875         emitpcode(POC_INCF ,  popGet(AOP(IC_RESULT(ic)),0));
876
877         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
878                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
879                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
880         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
881       } else {
882
883         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
884           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
885           emitpcode(POC_XORLW , popGetLit(1));
886
887           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
888                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
889                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
890           pic14_emitcode(" xorlw","1");
891         } else {
892           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
893           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
894           emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
895
896           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
897           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
898                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
899                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
900           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
901         }
902           
903         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
904             
905           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
906             emitpcode(POC_ANDLW , popGetLit(1));
907             emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
908             emitSKPZ;
909             emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
910           } else {
911             emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
912             pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
913           }
914         }
915       }
916
917     } else {
918       int offset = 1;
919       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
920       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
921         emitCLRZ;
922         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
923         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
924
925         pic14_emitcode("clrz","");
926
927         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
928                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
929                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
930         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
931
932       } else {
933
934         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
935         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
936         emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
937         //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
938         emitMOVWF(IC_RIGHT(ic),0);
939
940         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
941         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
942                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
943                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
944         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
945         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
946
947       }
948
949       while(--size){
950         emitSKPZ;
951         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),offset++));
952         //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
953       }
954
955     }
956       
957   } else {
958     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
959
960     /* Add the first bytes */
961
962     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
963       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
964       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
965     } else {
966
967       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
968         emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
969         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
970           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
971       } else {
972
973         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
974
975         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
976           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
977         else {
978           PIC_OPCODE poc = POC_ADDFW;
979
980           if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
981               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
982               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
983             poc = POC_ADDLW;
984           emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
985           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
986             emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
987         }
988       }
989     }
990
991     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
992     offset = 1;
993
994
995     while(size--){
996       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
997         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
998         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
999
1000         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1001         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1002       }
1003
1004       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
1005       emitSKPNC;
1006       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1007       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
1008
1009       /*
1010         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1011         emitSKPNC;
1012         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1013         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1014       */
1015
1016       offset++;
1017     }
1018
1019   }
1020
1021   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1022     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1023                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1024
1025
1026     /* Need to extend result to higher bytes */
1027     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1028
1029     /* First grab the carry from the lower bytes */
1030     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1031     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
1032
1033
1034     if(sign) {
1035       /* Now this is really horrid. Gotta check the sign of the addends and propogate
1036        * to the result */
1037
1038       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1039       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1040       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1041       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1042
1043       /* if chars or ints or being signed extended to longs: */
1044       if(size) {
1045         emitpcode(POC_MOVLW, popGetLit(0));
1046         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1047         emitpcode(POC_MOVLW, popGetLit(0xff));
1048       }
1049     }
1050
1051     offset++;
1052     while(size--) {
1053       
1054       if(sign)
1055         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1056       else
1057         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
1058
1059       offset++;
1060     }
1061   }
1062
1063
1064   //adjustArithmeticResult(ic);
1065
1066  release:
1067   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1068   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1069   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1070 }
1071
1072 /*-----------------------------------------------------------------*/
1073 /* genMinusDec :- does subtraction with decrement if possible     */
1074 /*-----------------------------------------------------------------*/
1075 bool genMinusDec (iCode *ic)
1076 {
1077     unsigned int icount ;
1078     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1079
1080     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1081     /* will try to generate an increment */
1082     /* if the right side is not a literal 
1083     we cannot */
1084     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1085         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1086         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1087         return FALSE ;
1088
1089     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1090
1091     /* if the literal value of the right hand side
1092     is greater than 4 then it is not worth it */
1093     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1094         return FALSE ;
1095
1096     /* if decrement 16 bits in register */
1097     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1098         (size > 1) &&
1099         (icount == 1)) {
1100
1101       if(size == 2) { 
1102         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1103         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1104         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1105         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1106
1107         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1108         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1109         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1110       } else {
1111         /* size is 3 or 4 */
1112         emitpcode(POC_MOVLW,  popGetLit(0xff));
1113         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1114         emitSKPNC;
1115         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1116         emitSKPNC;
1117         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1118
1119         pic14_emitcode("movlw","0xff");
1120         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1121
1122         emitSKPNC;
1123         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1124         emitSKPNC;
1125         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1126
1127         if(size > 3) {
1128           emitSKPNC;
1129           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1130
1131           pic14_emitcode("skpnc","");
1132           emitSKPNC;
1133           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1134         }
1135
1136       }
1137
1138       return TRUE;
1139
1140     }
1141
1142     /* if the sizes are greater than 1 then we cannot */
1143     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1144         AOP_SIZE(IC_LEFT(ic)) > 1   )
1145         return FALSE ;
1146
1147     /* we can if the aops of the left & result match or
1148     if they are in registers and the registers are the
1149     same */
1150     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1151
1152       while (icount--) 
1153         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1154
1155         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1156
1157         return TRUE ;
1158     }
1159
1160     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1161                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1162                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1163     if(size==1) {
1164
1165       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1166       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1167
1168       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1169       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1170
1171       return TRUE;
1172     }
1173
1174     return FALSE ;
1175 }
1176
1177 /*-----------------------------------------------------------------*/
1178 /* addSign - propogate sign bit to higher bytes                    */
1179 /*-----------------------------------------------------------------*/
1180 void addSign(operand *result, int offset, int sign)
1181 {
1182   int size = (pic14_getDataSize(result) - offset);
1183   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1184
1185   if(size > 0){
1186     if(sign && offset) {
1187
1188       if(size == 1) {
1189         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1190         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1191         emitpcode(POC_DECF, popGet(AOP(result),offset));
1192       } else {
1193
1194         emitpcode(POC_MOVLW, popGetLit(0));
1195         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1196         emitpcode(POC_MOVLW, popGetLit(0xff));
1197         while(size--)
1198           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1199
1200       }
1201     } else
1202       while(size--)
1203         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1204   }
1205 }
1206
1207 /*-----------------------------------------------------------------*/
1208 /* genMinusBits - generates code for subtraction  of two bits      */
1209 /*-----------------------------------------------------------------*/
1210 void genMinusBits (iCode *ic)
1211 {
1212     symbol *lbl = newiTempLabel(NULL);
1213     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1214     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1215         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1216         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1217         pic14_emitcode("cpl","c");
1218         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1219         pic14_outBitC(IC_RESULT(ic));
1220     }
1221     else{
1222         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1223         pic14_emitcode("subb","a,acc");
1224         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1225         pic14_emitcode("inc","a");
1226         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1227         aopPut(AOP(IC_RESULT(ic)),"a",0);
1228         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1229     }
1230 }
1231
1232 /*-----------------------------------------------------------------*/
1233 /* genMinus - generates code for subtraction                       */
1234 /*-----------------------------------------------------------------*/
1235 void genMinus (iCode *ic)
1236 {
1237   int size, offset = 0, same=0;
1238   unsigned long lit = 0L;
1239
1240   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1241   aopOp (IC_LEFT(ic),ic,FALSE);
1242   aopOp (IC_RIGHT(ic),ic,FALSE);
1243   aopOp (IC_RESULT(ic),ic,TRUE);
1244
1245   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1246       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1247     operand *t = IC_RIGHT(ic);
1248     IC_RIGHT(ic) = IC_LEFT(ic);
1249     IC_LEFT(ic) = t;
1250   }
1251
1252   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1253                    AopType(AOP_TYPE(IC_RESULT(ic))),
1254                    AopType(AOP_TYPE(IC_LEFT(ic))),
1255                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1256
1257   /* special cases :- */
1258   /* if both left & right are in bit space */
1259   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1260       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1261     genPlusBits (ic);
1262     goto release ;
1263   }
1264
1265   /* if I can do an decrement instead
1266      of subtract then GOOD for ME */
1267   //  if (genMinusDec (ic) == TRUE)
1268   //    goto release;   
1269
1270   size = pic14_getDataSize(IC_RESULT(ic));   
1271   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1272
1273   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1274     /* Add a literal to something else */
1275
1276     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1277     lit = - (long)lit;
1278
1279     genAddLit ( ic,  lit);
1280     
1281 #if 0
1282     /* add the first byte: */
1283     pic14_emitcode("movlw","0x%x", lit & 0xff);
1284     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1285     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1286     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1287
1288
1289     offset = 1;
1290     size--;
1291
1292     while(size-- > 0) {
1293
1294       lit >>= 8;
1295
1296       if(lit & 0xff) {
1297
1298         if((lit & 0xff) == 0xff) {
1299           emitpcode(POC_MOVLW,  popGetLit(0xff));
1300           emitSKPC;
1301           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1302         } else {
1303           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1304           emitSKPNC;
1305           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1306           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1307         }
1308
1309       } else {
1310         /* do the rlf known zero trick here */
1311         emitpcode(POC_MOVLW,  popGetLit(1));
1312         emitSKPNC;
1313         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1314       }
1315       offset++;
1316     }
1317 #endif
1318   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1319     // bit subtraction
1320
1321     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1322     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1323     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1324
1325     /* here we are subtracting a bit from a char or int */
1326     if(size == 1) {
1327       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1328
1329         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1330         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1331
1332         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1333                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1334                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1335         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1336       } else {
1337
1338         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1339           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1340           emitpcode(POC_XORLW , popGetLit(1));
1341         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1342               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1343
1344           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1345
1346           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1347             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1348               if(lit & 1) {
1349                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1350                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1351               }
1352             }else{
1353               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1354               if(lit & 1) 
1355                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1356               else
1357                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1358               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1359             }
1360             goto release;
1361           } else {
1362             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1363             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1364             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1365             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1366
1367           }
1368
1369         } else {
1370           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1371           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1372           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1373         }
1374           
1375         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1376             
1377           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1378
1379         } else  {
1380           emitpcode(POC_ANDLW , popGetLit(1));
1381 /*
1382           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1383           emitSKPZ;
1384           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1385 */
1386         }
1387
1388       }
1389
1390     }
1391   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1392               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1393               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1394
1395     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1396     DEBUGpic14_emitcode ("; left is lit","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
1402     if( (size == 1) && ((lit & 0xff) == 0) ) {
1403       /* res = 0 - right */
1404       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1405         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1406         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1407       } else { 
1408         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1409         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1410         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1411       }
1412       goto release;
1413     }
1414
1415     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1416     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1417     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1418
1419
1420     offset = 1;
1421     while(--size) {
1422       lit >>= 8;
1423
1424       if(size == 1) {
1425         /* This is the last byte in a multibyte subtraction 
1426          * There are a couple of tricks we can do by not worrying about 
1427          * propogating the carry */
1428         if(lit == 0xff) {
1429           /* 0xff - x == ~x */
1430           if(same) {
1431             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1432             emitSKPC;
1433             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1434           } else {
1435             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1436             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1437             emitSKPC;
1438             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1439           }
1440         } else {
1441             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1442             emitSKPC;
1443             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1444             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1445             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1446         }
1447
1448         goto release;
1449       }
1450
1451       if(same) {
1452
1453         if(lit & 0xff) {
1454           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1455           emitSKPC;
1456           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1457           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1458         } else {
1459           emitSKPNC;
1460           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1461
1462         }
1463       } else {
1464
1465         if(lit & 0xff) {
1466           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1467           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1468         } else
1469           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1470
1471         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1472         emitSKPC;
1473         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1474         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1475       }
1476     }
1477   
1478
1479   } else {
1480
1481     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1482                    AopType(AOP_TYPE(IC_RESULT(ic))),
1483                    AopType(AOP_TYPE(IC_LEFT(ic))),
1484                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1485
1486     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1487       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1488       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1489       emitpcode(POC_SUBLW, popGetLit(0));
1490       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1491     } else {
1492
1493       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1494         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1495         emitpcode(POC_SUBLW, popGetLit(0));
1496         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1497           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1498       } else {
1499
1500         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1501         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1502           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1503
1504         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1505           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1506         else {
1507           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1508               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1509             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1510           } else {
1511             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1512           }
1513           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1514             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1515               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1516               emitSKPZ;
1517               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1518             }else
1519               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1520           }
1521         }
1522       }
1523     }
1524
1525     /*
1526       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1527
1528       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1529       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1530       } else {
1531       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1532       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1533       }
1534     */
1535     offset = 1;
1536     size--;
1537
1538     while(size--){
1539       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1540         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1541         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1542       }
1543       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1544       emitSKPC;
1545       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1546       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1547
1548       offset++;
1549     }
1550
1551   }
1552
1553
1554   //    adjustArithmeticResult(ic);
1555         
1556  release:
1557   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1558   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1559   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1560 }
1561 /*-----------------------------------------------------------------*
1562  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1563  * 
1564  * 
1565  *-----------------------------------------------------------------*/
1566 void genUMult8XLit_16 (operand *left,
1567                        operand *right,
1568                        operand *result,
1569                        pCodeOpReg *result_hi)
1570
1571 {
1572
1573   unsigned int lit;
1574   unsigned int i,have_first_bit;
1575   int same;
1576   pCodeOp *temp;
1577
1578   if (AOP_TYPE(right) != AOP_LIT){
1579     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1580     exit(1);
1581   }
1582
1583
1584   if(!result_hi) {
1585     result_hi = PCOR(popGet(AOP(result),1));
1586   }
1587
1588   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1589   lit &= 0xff;
1590   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1591
1592   same = pic14_sameRegs(AOP(left), AOP(result));
1593
1594   if(same) {
1595     switch(lit) {
1596     case 0:
1597       emitpcode(POC_CLRF,  popGet(AOP(left),0));
1598       return;
1599     case 2:
1600       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1601       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1602       return;
1603     case 3:
1604       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1605       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1606       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1607       return;
1608     case 4:
1609       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1610       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1611       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1612       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1613       return;
1614     case 5:
1615       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1616       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1617       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1618       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1619       return;
1620     case 6:
1621       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1622       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1623       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1624       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1625       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1626       return;
1627     case 7:
1628       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1629       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1630       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1631       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1632       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
1633       return;
1634     case 8:
1635       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1636       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1637       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1638       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1639       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1640       return;
1641     case 9:
1642       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1643       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1644       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1645       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1646       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1647       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1648       return;
1649     case 10:
1650       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1651       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1652       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1653       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1654       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1655       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1656       return;
1657     case 11:
1658       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1659       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1660       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1661       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1662       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1663       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
1664       return;
1665     case 12:
1666       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1667       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1668       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1669       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1670       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1671       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1672       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1673       return;
1674     case 13:
1675       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1676       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1677       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1678       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1679       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1680       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
1681       return;
1682     case 14:
1683       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1684       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1685       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1686       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1687       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1688       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
1689       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
1690       return;
1691     case 15:
1692       temp = popGetTempReg();
1693       if(!temp) {
1694         fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1695         exit(1);
1696       }
1697       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1698       emitpcode(POC_MOVWF,  temp);
1699       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1700       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1701       emitpcode(POC_SWAPFW, temp);
1702       emitpcode(POC_SUBWF,  popGet(AOP(left),0));
1703       popReleaseTempReg(temp);
1704       return;
1705     case 16:
1706       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1707       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1708       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1709       return;
1710     case 17:
1711       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1712       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1713       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1714       return;
1715     case 32:
1716       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1717       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1718       emitpcode(POC_ANDLW,  popGetLit(0xe0));
1719       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1720       return;
1721     case 64:
1722       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1723       emitpcode(POC_RLF,    popGet(AOP(left),0));
1724       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1725       emitpcode(POC_ANDLW,  popGetLit(0xc0));
1726       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1727       return;
1728     case 128:
1729       emitpcode(POC_RRFW,   popGet(AOP(left),0));
1730       emitpcode(POC_CLRF,   popGet(AOP(left),0));
1731       emitpcode(POC_RRF,    popGet(AOP(left),0));
1732       return;
1733
1734     }
1735   } else {
1736
1737     switch(lit) {
1738     case 0:
1739       emitpcode(POC_CLRF,  popGet(AOP(result),0));
1740       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1741       return;
1742     case 2:
1743       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1744       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1745       emitpcode(POC_ADDWF, popGet(AOP(result),0));
1746       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1747       emitpcode(POC_RLF,   popCopyReg(result_hi));
1748       return;
1749     }
1750
1751   }
1752
1753   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1754   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1755   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1756
1757   have_first_bit = 0;
1758   for(i=0; i<8; i++) {
1759
1760     if(lit & 1) {
1761       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1762       have_first_bit = 1;
1763     }
1764
1765     if(have_first_bit) {
1766       emitpcode(POC_RRF,   popCopyReg(result_hi));
1767       emitpcode(POC_RRF,   popGet(AOP(result),0));
1768     }
1769
1770     lit >>= 1;
1771   }
1772
1773 }
1774
1775 /*-----------------------------------------------------------------*
1776  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1777  * 
1778  * 
1779  *-----------------------------------------------------------------*/
1780 void genUMult8X8_16 (operand *left,
1781                      operand *right,
1782                      operand *result,
1783                      pCodeOpReg *result_hi)
1784
1785 {
1786
1787   int i;
1788   int looped = 1;
1789
1790   if(!result_hi) {
1791     result_hi = PCOR(popGet(AOP(result),1));
1792   }
1793
1794   if (AOP_TYPE(right) == AOP_LIT) {
1795     genUMult8XLit_16(left,right,result,result_hi);
1796     return;
1797   }
1798
1799   if(!looped) {
1800     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1801
1802     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1803     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1804     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1805     emitCLRC;
1806
1807     for(i=0; i<8; i++) {
1808       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1809       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1810       emitpcode(POC_RRF,   popCopyReg(result_hi));
1811       emitpcode(POC_RRF,   popGet(AOP(result),0));
1812     }
1813
1814
1815     /*
1816       Here's another version that does the same thing and takes the 
1817       same number of instructions. The one above is slightly better
1818       because the entry instructions have a higher probability of
1819       being optimized out.
1820     */
1821     /*
1822       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1823       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1824       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1825       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1826
1827       for(i=0; i<8; i++) {
1828       emitSKPNC;
1829       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1830       emitpcode(POC_RRF,   popCopyReg(result_hi));
1831       emitpcode(POC_RRF,   popGet(AOP(result),0));
1832       }
1833     */
1834
1835   } else {
1836     symbol  *tlbl = newiTempLabel(NULL);
1837     pCodeOp *temp;
1838
1839
1840     pic14_emitcode(";","Looped 8 X 8 multiplication");
1841
1842     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1843     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1844
1845     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1846
1847     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1848
1849     temp = popGetTempReg();
1850     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1851
1852     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1853
1854     emitpLabel(tlbl->key);
1855
1856     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1857     emitSKPNC;
1858     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1859
1860     emitpcode(POC_RRF,   popCopyReg(result_hi));
1861     emitpcode(POC_RRF,   popGet(AOP(result),0));
1862
1863     emitSKPC;
1864     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1865
1866     popReleaseTempReg(temp);
1867
1868   }
1869 }
1870
1871 /*-----------------------------------------------------------------*
1872  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1873  *
1874  *  this routine will call the unsigned multiply routine and then
1875  * post-fix the sign bit.
1876  *-----------------------------------------------------------------*/
1877 void genSMult8X8_16 (operand *left,
1878                      operand *right,
1879                      operand *result,
1880                      pCodeOpReg *result_hi)
1881 {
1882
1883   if(!result_hi) {
1884     result_hi = PCOR(popGet(AOP(result),1));
1885   }
1886
1887   genUMult8X8_16(left,right,result,result_hi);
1888
1889   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1890   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1891   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1892   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1893   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1894   
1895 }
1896
1897 /*-----------------------------------------------------------------*
1898  * genMult8X8_8 - multiplication of two 8-bit numbers
1899  *
1900  *  this routine will call the unsigned multiply 8X8=>16 routine and
1901  * then throw away the high byte of the result.
1902  *
1903  *-----------------------------------------------------------------*/
1904 void genMult8X8_8 (operand *left,
1905                    operand *right,
1906                    operand *result)
1907 {
1908   pCodeOp *result_hi = popGetTempReg();
1909
1910   if (AOP_TYPE(right) == AOP_LIT)
1911     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1912   else
1913     genUMult8X8_16(left,right,result,PCOR(result_hi));
1914
1915   popReleaseTempReg(result_hi);
1916 }
1917 #if 0
1918 /*-----------------------------------------------------------------*/
1919 /* constMult - generates code for multiplication by a constant     */
1920 /*-----------------------------------------------------------------*/
1921 void genMultConst(unsigned C)
1922 {
1923
1924   unsigned lit;
1925   unsigned sr3; // Shift right 3
1926   unsigned mask;
1927
1928   int size = 1;
1929
1930   /*
1931     Convert a string of 3 binary 1's in the lit into
1932     0111 = 1000 - 1;
1933   */
1934
1935   mask = 7 << ( (size*8) - 3);
1936   lit = C;
1937   sr3 = 0;
1938
1939   while(mask < (1<<size*8)) {
1940
1941     if( (mask & lit) == lit) {
1942       unsigned lsb;
1943
1944       /* We found 3 (or more) consecutive 1's */
1945
1946       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1947
1948       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1949
1950       lit ^= consecutive_bits;
1951
1952       mask <<= 3;
1953
1954       sr3 |= (consecutive + lsb);
1955
1956     }
1957
1958     mask >>= 1;
1959
1960   }
1961
1962 }
1963
1964 #endif