bug 568948: building with latest MSVC
[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
742       /* left is not the accumulator */
743       if(lit & 0xff) {
744         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
745         emitpcode(POC_ADDFW, popGet(AOP(left),0));
746       } else
747         emitpcode(POC_MOVFW, popGet(AOP(left),0));
748
749       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
750       emitMOVWF(result,0);
751       lit >>= 8;
752       while(--size) {
753       
754         if(lit & 0xff) {
755           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
756           //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
757           emitMOVWF(result,offset);
758           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
759           emitSKPNC;
760           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
761           emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
762         } else {
763           emitpcode(POC_CLRF,  popGet(AOP(result),offset));
764           emitpcode(POC_RLF,   popGet(AOP(result),offset));
765           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
766           emitpcode(POC_ADDWF, popGet(AOP(result),offset));
767         }
768       offset++;
769       }
770     }
771   }
772 }
773
774 /*-----------------------------------------------------------------*/
775 /* genPlus - generates code for addition                           */
776 /*-----------------------------------------------------------------*/
777 void genPlus (iCode *ic)
778 {
779   int size, offset = 0;
780
781   /* special cases :- */
782   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
783
784   aopOp (IC_LEFT(ic),ic,FALSE);
785   aopOp (IC_RIGHT(ic),ic,FALSE);
786   aopOp (IC_RESULT(ic),ic,TRUE);
787
788   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
789
790   /* if literal, literal on the right or
791      if left requires ACC or right is already
792      in ACC */
793
794   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
795     operand *t = IC_RIGHT(ic);
796     IC_RIGHT(ic) = IC_LEFT(ic);
797     IC_LEFT(ic) = t;
798   }
799
800   /* if both left & right are in bit space */
801   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
802       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
803     genPlusBits (ic);
804     goto release ;
805   }
806
807   /* if left in bit space & right literal */
808   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
809       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
810     /* if result in bit space */
811     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
812       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
813         emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
814         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
815           emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
816         emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
817       }
818     } else {
819       size = pic14_getDataSize(IC_RESULT(ic));
820       while (size--) {
821         MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
822         pic14_emitcode("addc","a,#00  ;%d",__LINE__);
823         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
824       }
825     }
826     goto release ;
827   }
828
829   /* if I can do an increment instead
830      of add then GOOD for ME */
831   if (genPlusIncr (ic) == TRUE)
832     goto release;   
833
834   size = pic14_getDataSize(IC_RESULT(ic));
835
836   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
837     /* Add a literal to something else */
838     //bool know_W=0;
839     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
840     //      unsigned l1=0;
841
842     //      offset = 0;
843     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
844
845     genAddLit (ic,  lit);
846     goto release;
847
848   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
849
850     pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
851     pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
852     pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
853
854     /* here we are adding a bit to a char or int */
855     if(size == 1) {
856       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
857
858         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
859         emitpcode(POC_INCF ,  popGet(AOP(IC_RESULT(ic)),0));
860
861         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
862                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
863                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
864         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
865       } else {
866
867         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
868           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
869           emitpcode(POC_XORLW , popGetLit(1));
870
871           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
872                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
873                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
874           pic14_emitcode(" xorlw","1");
875         } else {
876           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
877           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
878           emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
879
880           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
881           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
882                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
883                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
884           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
885         }
886           
887         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
888             
889           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
890             emitpcode(POC_ANDLW , popGetLit(1));
891             emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
892             emitSKPZ;
893             emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
894           } else {
895             emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
896             pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
897           }
898         }
899       }
900
901     } else {
902       int offset = 1;
903       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
904       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
905         emitCLRZ;
906         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
907         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
908
909         pic14_emitcode("clrz","");
910
911         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
912                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
913                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
914         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
915
916       } else {
917
918         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
919         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
920         emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
921         //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
922         emitMOVWF(IC_RIGHT(ic),0);
923
924         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
925         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
926                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
927                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
928         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
929         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
930
931       }
932
933       while(--size){
934         emitSKPZ;
935         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),offset++));
936         //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
937       }
938
939     }
940       
941   } else {
942     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
943
944     /* Add the first bytes */
945
946     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
947       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
948       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
949     } else {
950
951       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
952         emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
953         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
954           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
955       } else {
956
957         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
958
959         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
960           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
961         else {
962           PIC_OPCODE poc = POC_ADDFW;
963
964           if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
965               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
966               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
967             poc = POC_ADDLW;
968           emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
969           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
970             emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
971         }
972       }
973     }
974
975     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
976     offset = 1;
977
978
979     while(size--){
980       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
981         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
982         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
983
984         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
985         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
986       }
987
988       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
989       emitSKPNC;
990       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
991       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
992
993       /*
994         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
995         emitSKPNC;
996         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
997         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
998       */
999
1000       offset++;
1001     }
1002
1003   }
1004
1005   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1006     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1007                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1008
1009
1010     /* Need to extend result to higher bytes */
1011     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1012
1013     /* First grab the carry from the lower bytes */
1014     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1015     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
1016
1017
1018     if(sign) {
1019       /* Now this is really horrid. Gotta check the sign of the addends and propogate
1020        * to the result */
1021
1022       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1023       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1024       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1025       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1026
1027       /* if chars or ints or being signed extended to longs: */
1028       if(size) {
1029         emitpcode(POC_MOVLW, popGetLit(0));
1030         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1031         emitpcode(POC_MOVLW, popGetLit(0xff));
1032       }
1033     }
1034
1035     offset++;
1036     while(size--) {
1037       
1038       if(sign)
1039         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1040       else
1041         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
1042
1043       offset++;
1044     }
1045   }
1046
1047
1048   //adjustArithmeticResult(ic);
1049
1050  release:
1051   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1052   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1053   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1054 }
1055
1056 /*-----------------------------------------------------------------*/
1057 /* genMinusDec :- does subtraction with decrement if possible     */
1058 /*-----------------------------------------------------------------*/
1059 bool genMinusDec (iCode *ic)
1060 {
1061     unsigned int icount ;
1062     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1063
1064     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1065     /* will try to generate an increment */
1066     /* if the right side is not a literal 
1067     we cannot */
1068     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1069         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1070         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1071         return FALSE ;
1072
1073     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1074
1075     /* if the literal value of the right hand side
1076     is greater than 4 then it is not worth it */
1077     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1078         return FALSE ;
1079
1080     /* if decrement 16 bits in register */
1081     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1082         (size > 1) &&
1083         (icount == 1)) {
1084
1085       if(size == 2) { 
1086         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1087         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1088         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1089         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1090
1091         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1092         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1093         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1094       } else {
1095         /* size is 3 or 4 */
1096         emitpcode(POC_MOVLW,  popGetLit(0xff));
1097         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1098         emitSKPNC;
1099         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1100         emitSKPNC;
1101         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1102
1103         pic14_emitcode("movlw","0xff");
1104         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1105
1106         emitSKPNC;
1107         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1108         emitSKPNC;
1109         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1110
1111         if(size > 3) {
1112           emitSKPNC;
1113           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1114
1115           pic14_emitcode("skpnc","");
1116           emitSKPNC;
1117           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1118         }
1119
1120       }
1121
1122       return TRUE;
1123
1124     }
1125
1126     /* if the sizes are greater than 1 then we cannot */
1127     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1128         AOP_SIZE(IC_LEFT(ic)) > 1   )
1129         return FALSE ;
1130
1131     /* we can if the aops of the left & result match or
1132     if they are in registers and the registers are the
1133     same */
1134     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1135
1136       while (icount--) 
1137         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1138
1139         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1140
1141         return TRUE ;
1142     }
1143
1144     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1145                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1146                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1147     if(size==1) {
1148
1149       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1150       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1151
1152       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1153       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1154
1155       return TRUE;
1156     }
1157
1158     return FALSE ;
1159 }
1160
1161 /*-----------------------------------------------------------------*/
1162 /* addSign - propogate sign bit to higher bytes                    */
1163 /*-----------------------------------------------------------------*/
1164 void addSign(operand *result, int offset, int sign)
1165 {
1166   int size = (pic14_getDataSize(result) - offset);
1167   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1168
1169   if(size > 0){
1170     if(sign && offset) {
1171
1172       if(size == 1) {
1173         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1174         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1175         emitpcode(POC_DECF, popGet(AOP(result),offset));
1176       } else {
1177
1178         emitpcode(POC_MOVLW, popGetLit(0));
1179         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1180         emitpcode(POC_MOVLW, popGetLit(0xff));
1181         while(size--)
1182           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1183
1184       }
1185     } else
1186       while(size--)
1187         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1188   }
1189 }
1190
1191 /*-----------------------------------------------------------------*/
1192 /* genMinusBits - generates code for subtraction  of two bits      */
1193 /*-----------------------------------------------------------------*/
1194 void genMinusBits (iCode *ic)
1195 {
1196     symbol *lbl = newiTempLabel(NULL);
1197     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1198     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1199         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1200         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1201         pic14_emitcode("cpl","c");
1202         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1203         pic14_outBitC(IC_RESULT(ic));
1204     }
1205     else{
1206         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1207         pic14_emitcode("subb","a,acc");
1208         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1209         pic14_emitcode("inc","a");
1210         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1211         aopPut(AOP(IC_RESULT(ic)),"a",0);
1212         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1213     }
1214 }
1215
1216 /*-----------------------------------------------------------------*/
1217 /* genMinus - generates code for subtraction                       */
1218 /*-----------------------------------------------------------------*/
1219 void genMinus (iCode *ic)
1220 {
1221   int size, offset = 0, same=0;
1222   unsigned long lit = 0L;
1223
1224   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1225   aopOp (IC_LEFT(ic),ic,FALSE);
1226   aopOp (IC_RIGHT(ic),ic,FALSE);
1227   aopOp (IC_RESULT(ic),ic,TRUE);
1228
1229   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1230       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1231     operand *t = IC_RIGHT(ic);
1232     IC_RIGHT(ic) = IC_LEFT(ic);
1233     IC_LEFT(ic) = t;
1234   }
1235
1236   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1237                    AopType(AOP_TYPE(IC_RESULT(ic))),
1238                    AopType(AOP_TYPE(IC_LEFT(ic))),
1239                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1240
1241   /* special cases :- */
1242   /* if both left & right are in bit space */
1243   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1244       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1245     genPlusBits (ic);
1246     goto release ;
1247   }
1248
1249   /* if I can do an decrement instead
1250      of subtract then GOOD for ME */
1251   //  if (genMinusDec (ic) == TRUE)
1252   //    goto release;   
1253
1254   size = pic14_getDataSize(IC_RESULT(ic));   
1255   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1256
1257   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1258     /* Add a literal to something else */
1259
1260     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1261     lit = - (long)lit;
1262
1263     genAddLit ( ic,  lit);
1264     
1265 #if 0
1266     /* add the first byte: */
1267     pic14_emitcode("movlw","0x%x", lit & 0xff);
1268     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1269     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1270     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1271
1272
1273     offset = 1;
1274     size--;
1275
1276     while(size-- > 0) {
1277
1278       lit >>= 8;
1279
1280       if(lit & 0xff) {
1281
1282         if((lit & 0xff) == 0xff) {
1283           emitpcode(POC_MOVLW,  popGetLit(0xff));
1284           emitSKPC;
1285           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1286         } else {
1287           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1288           emitSKPNC;
1289           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1290           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1291         }
1292
1293       } else {
1294         /* do the rlf known zero trick here */
1295         emitpcode(POC_MOVLW,  popGetLit(1));
1296         emitSKPNC;
1297         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1298       }
1299       offset++;
1300     }
1301 #endif
1302   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1303     // bit subtraction
1304
1305     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1306     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1307     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1308
1309     /* here we are subtracting a bit from a char or int */
1310     if(size == 1) {
1311       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1312
1313         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1314         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1315
1316         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1317                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1318                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1319         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1320       } else {
1321
1322         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1323           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1324           emitpcode(POC_XORLW , popGetLit(1));
1325         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1326               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1327
1328           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1329
1330           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1331             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1332               if(lit & 1) {
1333                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1334                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1335               }
1336             }else{
1337               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1338               if(lit & 1) 
1339                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1340               else
1341                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1342               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1343             }
1344             goto release;
1345           } else {
1346             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1347             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1348             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1349             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1350
1351           }
1352
1353         } else {
1354           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1355           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1356           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1357         }
1358           
1359         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1360             
1361           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1362
1363         } else  {
1364           emitpcode(POC_ANDLW , popGetLit(1));
1365 /*
1366           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1367           emitSKPZ;
1368           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1369 */
1370         }
1371
1372       }
1373
1374     }
1375   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1376               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1377               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1378
1379     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1380     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1381                    AopType(AOP_TYPE(IC_RESULT(ic))),
1382                    AopType(AOP_TYPE(IC_LEFT(ic))),
1383                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1384
1385
1386     if( (size == 1) && ((lit & 0xff) == 0) ) {
1387       /* res = 0 - right */
1388       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1389         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1390         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1391       } else { 
1392         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1393         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1394         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1395       }
1396       goto release;
1397     }
1398
1399     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1400     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1401     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1402
1403
1404     offset = 1;
1405     while(--size) {
1406       lit >>= 8;
1407
1408       if(size == 1) {
1409         /* This is the last byte in a multibyte subtraction 
1410          * There are a couple of tricks we can do by not worrying about 
1411          * propogating the carry */
1412         if(lit == 0xff) {
1413           /* 0xff - x == ~x */
1414           if(same) {
1415             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1416             emitSKPC;
1417             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1418           } else {
1419             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1420             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1421             emitSKPC;
1422             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1423           }
1424         } else {
1425             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1426             emitSKPC;
1427             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1428             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1429             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1430         }
1431
1432         goto release;
1433       }
1434
1435       if(same) {
1436
1437         if(lit & 0xff) {
1438           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1439           emitSKPC;
1440           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1441           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1442         } else {
1443           emitSKPNC;
1444           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1445
1446         }
1447       } else {
1448
1449         if(lit & 0xff) {
1450           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1451           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1452         } else
1453           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1454
1455         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1456         emitSKPC;
1457         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1458         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1459       }
1460     }
1461   
1462
1463   } else {
1464
1465     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1466                    AopType(AOP_TYPE(IC_RESULT(ic))),
1467                    AopType(AOP_TYPE(IC_LEFT(ic))),
1468                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1469
1470     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1471       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1472       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1473       emitpcode(POC_SUBLW, popGetLit(0));
1474       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1475     } else {
1476
1477       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1478         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1479         emitpcode(POC_SUBLW, popGetLit(0));
1480         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1481           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1482       } else {
1483
1484         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1485         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1486           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1487
1488         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1489           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1490         else {
1491           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1492               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1493             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1494           } else {
1495             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1496           }
1497           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1498             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1499               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1500               emitSKPZ;
1501               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1502             }else
1503               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1504           }
1505         }
1506       }
1507     }
1508
1509     /*
1510       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1511
1512       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1513       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1514       } else {
1515       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1516       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1517       }
1518     */
1519     offset = 1;
1520     size--;
1521
1522     while(size--){
1523       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1524         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1525         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1526       }
1527       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1528       emitSKPC;
1529       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1530       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1531
1532       offset++;
1533     }
1534
1535   }
1536
1537
1538   //    adjustArithmeticResult(ic);
1539         
1540  release:
1541   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1542   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1543   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1544 }
1545 /*-----------------------------------------------------------------*
1546  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1547  * 
1548  * 
1549  *-----------------------------------------------------------------*/
1550 void genUMult8XLit_16 (operand *left,
1551                        operand *right,
1552                        operand *result,
1553                        pCodeOpReg *result_hi)
1554
1555 {
1556
1557   unsigned int lit;
1558   unsigned int i,have_first_bit;
1559   int same;
1560   pCodeOp *temp;
1561
1562   if (AOP_TYPE(right) != AOP_LIT){
1563     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1564     exit(1);
1565   }
1566
1567
1568   if(!result_hi) {
1569     result_hi = PCOR(popGet(AOP(result),1));
1570   }
1571
1572   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1573   lit &= 0xff;
1574   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1575
1576   same = pic14_sameRegs(AOP(left), AOP(result));
1577
1578   if(same) {
1579     switch(lit) {
1580     case 0:
1581       emitpcode(POC_CLRF,  popGet(AOP(left),0));
1582       return;
1583     case 2:
1584       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1585       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1586       return;
1587     case 3:
1588       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1589       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1590       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1591       return;
1592     case 4:
1593       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1594       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1595       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1596       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1597       return;
1598     case 5:
1599       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1600       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1601       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1602       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1603       return;
1604     case 6:
1605       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1606       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1607       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1608       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1609       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1610       return;
1611     case 7:
1612       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1613       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1614       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1615       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1616       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
1617       return;
1618     case 8:
1619       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1620       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1621       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1622       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1623       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1624       return;
1625     case 9:
1626       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1627       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1628       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1629       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1630       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1631       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1632       return;
1633     case 10:
1634       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1635       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1636       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1637       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1638       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1639       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1640       return;
1641     case 11:
1642       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1643       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1644       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1645       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1646       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1647       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
1648       return;
1649     case 12:
1650       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1651       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1652       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1653       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1654       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1655       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1656       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1657       return;
1658     case 13:
1659       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1660       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1661       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1662       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1663       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1664       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
1665       return;
1666     case 14:
1667       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1668       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1669       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1670       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1671       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1672       emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
1673       emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
1674       return;
1675     case 15:
1676       temp = popGetTempReg();
1677       if(!temp) {
1678         fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1679         exit(1);
1680       }
1681       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1682       emitpcode(POC_MOVWF,  temp);
1683       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1684       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1685       emitpcode(POC_SWAPFW, temp);
1686       emitpcode(POC_SUBWF,  popGet(AOP(left),0));
1687       popReleaseTempReg(temp);
1688       return;
1689     case 16:
1690       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1691       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1692       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1693       return;
1694     case 17:
1695       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1696       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1697       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1698       return;
1699     case 32:
1700       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1701       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1702       emitpcode(POC_ANDLW,  popGetLit(0xe0));
1703       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1704       return;
1705     case 64:
1706       emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1707       emitpcode(POC_RLF,    popGet(AOP(left),0));
1708       emitpcode(POC_RLFW,   popGet(AOP(left),0));
1709       emitpcode(POC_ANDLW,  popGetLit(0xc0));
1710       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1711       return;
1712     case 128:
1713       emitpcode(POC_RRFW,   popGet(AOP(left),0));
1714       emitpcode(POC_CLRF,   popGet(AOP(left),0));
1715       emitpcode(POC_RRF,    popGet(AOP(left),0));
1716       return;
1717
1718     }
1719   } else {
1720
1721     switch(lit) {
1722     case 0:
1723       emitpcode(POC_CLRF,  popGet(AOP(result),0));
1724       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1725       return;
1726     case 2:
1727       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1728       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1729       emitpcode(POC_ADDWF, popGet(AOP(result),0));
1730       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1731       emitpcode(POC_RLF,   popCopyReg(result_hi));
1732       return;
1733     }
1734
1735   }
1736
1737   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1738   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1739   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1740
1741   have_first_bit = 0;
1742   for(i=0; i<8; i++) {
1743
1744     if(lit & 1) {
1745       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1746       have_first_bit = 1;
1747     }
1748
1749     if(have_first_bit) {
1750       emitpcode(POC_RRF,   popCopyReg(result_hi));
1751       emitpcode(POC_RRF,   popGet(AOP(result),0));
1752     }
1753
1754     lit >>= 1;
1755   }
1756
1757 }
1758
1759 /*-----------------------------------------------------------------*
1760  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1761  * 
1762  * 
1763  *-----------------------------------------------------------------*/
1764 void genUMult8X8_16 (operand *left,
1765                      operand *right,
1766                      operand *result,
1767                      pCodeOpReg *result_hi)
1768
1769 {
1770
1771   int i;
1772   int looped = 1;
1773
1774   if(!result_hi) {
1775     result_hi = PCOR(popGet(AOP(result),1));
1776   }
1777
1778   if (AOP_TYPE(right) == AOP_LIT) {
1779     genUMult8XLit_16(left,right,result,result_hi);
1780     return;
1781   }
1782
1783   if(!looped) {
1784     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1785
1786     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1787     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1788     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1789     emitCLRC;
1790
1791     for(i=0; i<8; i++) {
1792       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1793       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1794       emitpcode(POC_RRF,   popCopyReg(result_hi));
1795       emitpcode(POC_RRF,   popGet(AOP(result),0));
1796     }
1797
1798
1799     /*
1800       Here's another version that does the same thing and takes the 
1801       same number of instructions. The one above is slightly better
1802       because the entry instructions have a higher probability of
1803       being optimized out.
1804     */
1805     /*
1806       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1807       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1808       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1809       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1810
1811       for(i=0; i<8; i++) {
1812       emitSKPNC;
1813       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1814       emitpcode(POC_RRF,   popCopyReg(result_hi));
1815       emitpcode(POC_RRF,   popGet(AOP(result),0));
1816       }
1817     */
1818
1819   } else {
1820     symbol  *tlbl = newiTempLabel(NULL);
1821     pCodeOp *temp;
1822
1823
1824     pic14_emitcode(";","Looped 8 X 8 multiplication");
1825
1826     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1827     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1828
1829     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1830
1831     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1832
1833     temp = popGetTempReg();
1834     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1835
1836     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1837
1838     emitpLabel(tlbl->key);
1839
1840     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1841     emitSKPNC;
1842     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1843
1844     emitpcode(POC_RRF,   popCopyReg(result_hi));
1845     emitpcode(POC_RRF,   popGet(AOP(result),0));
1846
1847     emitSKPC;
1848     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1849
1850     popReleaseTempReg(temp);
1851
1852   }
1853 }
1854
1855 /*-----------------------------------------------------------------*
1856  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1857  *
1858  *  this routine will call the unsigned multiply routine and then
1859  * post-fix the sign bit.
1860  *-----------------------------------------------------------------*/
1861 void genSMult8X8_16 (operand *left,
1862                      operand *right,
1863                      operand *result,
1864                      pCodeOpReg *result_hi)
1865 {
1866
1867   if(!result_hi) {
1868     result_hi = PCOR(popGet(AOP(result),1));
1869   }
1870
1871   genUMult8X8_16(left,right,result,result_hi);
1872
1873   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1874   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1875   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1876   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1877   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1878   
1879 }
1880
1881 /*-----------------------------------------------------------------*
1882  * genMult8X8_8 - multiplication of two 8-bit numbers
1883  *
1884  *  this routine will call the unsigned multiply 8X8=>16 routine and
1885  * then throw away the high byte of the result.
1886  *
1887  *-----------------------------------------------------------------*/
1888 void genMult8X8_8 (operand *left,
1889                    operand *right,
1890                    operand *result)
1891 {
1892   pCodeOp *result_hi = popGetTempReg();
1893
1894   if (AOP_TYPE(right) == AOP_LIT)
1895     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1896   else
1897     genUMult8X8_16(left,right,result,PCOR(result_hi));
1898
1899   popReleaseTempReg(result_hi);
1900 }
1901 #if 0
1902 /*-----------------------------------------------------------------*/
1903 /* constMult - generates code for multiplication by a constant     */
1904 /*-----------------------------------------------------------------*/
1905 void genMultConst(unsigned C)
1906 {
1907
1908   unsigned lit;
1909   unsigned sr3; // Shift right 3
1910   unsigned mask;
1911
1912   int size = 1;
1913
1914   /*
1915     Convert a string of 3 binary 1's in the lit into
1916     0111 = 1000 - 1;
1917   */
1918
1919   mask = 7 << ( (size*8) - 3);
1920   lit = C;
1921   sr3 = 0;
1922
1923   while(mask < (1<<size*8)) {
1924
1925     if( (mask & lit) == lit) {
1926       unsigned lsb;
1927
1928       /* We found 3 (or more) consecutive 1's */
1929
1930       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1931
1932       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1933
1934       lit ^= consecutive_bits;
1935
1936       mask <<= 3;
1937
1938       sr3 |= (consecutive + lsb);
1939
1940     }
1941
1942     mask >>= 1;
1943
1944   }
1945
1946 }
1947
1948 #endif