Fixed some pointer bugs. Added option to selectively enable/disable function inlining.
[fw/sdcc] / src / pic / genarith.c
1 /*-------------------------------------------------------------------------
2   genarith.c - source file for code generation - arithmetic 
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #if defined(_MSC_VER)
40 #define __FUNCTION__            __FILE__
41 #endif
42
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
45 #else
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
48 #else
49 #ifdef HAVE_ENDIAN_H
50 #include <endian.h>
51 #else
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
55 #endif
56 #endif
57 #endif
58 #endif
59
60 #include "common.h"
61 #include "SDCCpeeph.h"
62 #include "ralloc.h"
63 #include "pcode.h"
64 #include "gen.h"
65
66
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
69
70 const char *AopType(short type)
71 {
72   switch(type) {
73   case AOP_LIT:
74     return "AOP_LIT";
75     break;
76   case AOP_REG:
77     return "AOP_REG";
78     break;
79   case AOP_DIR:
80     return "AOP_DIR";
81     break;
82   case AOP_DPTR:
83     return "AOP_DPTR";
84     break;
85   case AOP_DPTR2:
86     return "AOP_DPTR2";
87     break;
88   case AOP_R0:
89     return "AOP_R0";
90     break;
91   case AOP_R1:
92     return "AOP_R1";
93     break;
94   case AOP_STK:
95     return "AOP_STK";
96     break;
97   case AOP_IMMD:
98     return "AOP_IMMD";
99     break;
100   case AOP_STR:
101     return "AOP_STR";
102     break;
103   case AOP_CRY:
104     return "AOP_CRY";
105     break;
106   case AOP_ACC:
107     return "AOP_ACC";
108     break;
109   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) && AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL)
965             poc = POC_ADDLW;
966           emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
967           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
968             emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
969         }
970       }
971     }
972
973     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
974     offset = 1;
975
976
977     while(size--){
978       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
979         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
980         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
981
982         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
983         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
984       }
985
986       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
987       emitSKPNC;
988       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
989       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
990
991       /*
992         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
993         emitSKPNC;
994         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
995         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
996       */
997
998       offset++;
999     }
1000
1001   }
1002
1003   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1004     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1005                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1006
1007
1008     /* Need to extend result to higher bytes */
1009     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1010
1011     /* First grab the carry from the lower bytes */
1012     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1013     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
1014
1015
1016     if(sign) {
1017       /* Now this is really horrid. Gotta check the sign of the addends and propogate
1018        * to the result */
1019
1020       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1021       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1022       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1023       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1024
1025       /* if chars or ints or being signed extended to longs: */
1026       if(size) {
1027         emitpcode(POC_MOVLW, popGetLit(0));
1028         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1029         emitpcode(POC_MOVLW, popGetLit(0xff));
1030       }
1031     }
1032
1033     offset++;
1034     while(size--) {
1035       
1036       if(sign)
1037         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1038       else
1039         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
1040
1041       offset++;
1042     }
1043   }
1044
1045
1046   //adjustArithmeticResult(ic);
1047
1048  release:
1049   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1050   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1051   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1052 }
1053
1054 /*-----------------------------------------------------------------*/
1055 /* genMinusDec :- does subtraction with decrement if possible     */
1056 /*-----------------------------------------------------------------*/
1057 bool genMinusDec (iCode *ic)
1058 {
1059     unsigned int icount ;
1060     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1061
1062     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1063     /* will try to generate an increment */
1064     /* if the right side is not a literal 
1065     we cannot */
1066     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1067         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1068         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1069         return FALSE ;
1070
1071     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1072
1073     /* if the literal value of the right hand side
1074     is greater than 4 then it is not worth it */
1075     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1076         return FALSE ;
1077
1078     /* if decrement 16 bits in register */
1079     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1080         (size > 1) &&
1081         (icount == 1)) {
1082
1083       if(size == 2) { 
1084         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1085         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1086         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1087         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1088
1089         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1090         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1091         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1092       } else {
1093         /* size is 3 or 4 */
1094         emitpcode(POC_MOVLW,  popGetLit(0xff));
1095         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1096         emitSKPNC;
1097         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1098         emitSKPNC;
1099         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1100
1101         pic14_emitcode("movlw","0xff");
1102         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1103
1104         emitSKPNC;
1105         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1106         emitSKPNC;
1107         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1108
1109         if(size > 3) {
1110           emitSKPNC;
1111           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1112
1113           pic14_emitcode("skpnc","");
1114           emitSKPNC;
1115           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1116         }
1117
1118       }
1119
1120       return TRUE;
1121
1122     }
1123
1124     /* if the sizes are greater than 1 then we cannot */
1125     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1126         AOP_SIZE(IC_LEFT(ic)) > 1   )
1127         return FALSE ;
1128
1129     /* we can if the aops of the left & result match or
1130     if they are in registers and the registers are the
1131     same */
1132     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1133
1134       while (icount--) 
1135         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1136
1137         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1138
1139         return TRUE ;
1140     }
1141
1142     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1143                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1144                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1145     if(size==1) {
1146
1147       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1148       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1149
1150       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1151       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1152
1153       return TRUE;
1154     }
1155
1156     return FALSE ;
1157 }
1158
1159 /*-----------------------------------------------------------------*/
1160 /* addSign - propogate sign bit to higher bytes                    */
1161 /*-----------------------------------------------------------------*/
1162 void addSign(operand *result, int offset, int sign)
1163 {
1164   int size = (pic14_getDataSize(result) - offset);
1165   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1166
1167   if(size > 0){
1168     if(sign && offset) {
1169
1170       if(size == 1) {
1171         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1172         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1173         emitpcode(POC_DECF, popGet(AOP(result),offset));
1174       } else {
1175
1176         emitpcode(POC_MOVLW, popGetLit(0));
1177         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1178         emitpcode(POC_MOVLW, popGetLit(0xff));
1179         while(size--)
1180           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1181
1182       }
1183     } else
1184       while(size--)
1185         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1186   }
1187 }
1188
1189 /*-----------------------------------------------------------------*/
1190 /* genMinusBits - generates code for subtraction  of two bits      */
1191 /*-----------------------------------------------------------------*/
1192 void genMinusBits (iCode *ic)
1193 {
1194     symbol *lbl = newiTempLabel(NULL);
1195     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1196     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1197         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1198         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1199         pic14_emitcode("cpl","c");
1200         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1201         pic14_outBitC(IC_RESULT(ic));
1202     }
1203     else{
1204         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1205         pic14_emitcode("subb","a,acc");
1206         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1207         pic14_emitcode("inc","a");
1208         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1209         aopPut(AOP(IC_RESULT(ic)),"a",0);
1210         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1211     }
1212 }
1213
1214 /*-----------------------------------------------------------------*/
1215 /* genMinus - generates code for subtraction                       */
1216 /*-----------------------------------------------------------------*/
1217 void genMinus (iCode *ic)
1218 {
1219   int size, offset = 0, same=0;
1220   unsigned long lit = 0L;
1221
1222   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1223   aopOp (IC_LEFT(ic),ic,FALSE);
1224   aopOp (IC_RIGHT(ic),ic,FALSE);
1225   aopOp (IC_RESULT(ic),ic,TRUE);
1226
1227   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1228       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1229     operand *t = IC_RIGHT(ic);
1230     IC_RIGHT(ic) = IC_LEFT(ic);
1231     IC_LEFT(ic) = t;
1232   }
1233
1234   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1235                    AopType(AOP_TYPE(IC_RESULT(ic))),
1236                    AopType(AOP_TYPE(IC_LEFT(ic))),
1237                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1238
1239   /* special cases :- */
1240   /* if both left & right are in bit space */
1241   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1242       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1243     genPlusBits (ic);
1244     goto release ;
1245   }
1246
1247   /* if I can do an decrement instead
1248      of subtract then GOOD for ME */
1249   //  if (genMinusDec (ic) == TRUE)
1250   //    goto release;   
1251
1252   size = pic14_getDataSize(IC_RESULT(ic));   
1253   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1254
1255   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1256     /* Add a literal to something else */
1257
1258     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1259     lit = - (long)lit;
1260
1261     genAddLit ( ic,  lit);
1262     
1263 #if 0
1264     /* add the first byte: */
1265     pic14_emitcode("movlw","0x%x", lit & 0xff);
1266     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1267     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1268     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1269
1270
1271     offset = 1;
1272     size--;
1273
1274     while(size-- > 0) {
1275
1276       lit >>= 8;
1277
1278       if(lit & 0xff) {
1279
1280         if((lit & 0xff) == 0xff) {
1281           emitpcode(POC_MOVLW,  popGetLit(0xff));
1282           emitSKPC;
1283           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1284         } else {
1285           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1286           emitSKPNC;
1287           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1288           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1289         }
1290
1291       } else {
1292         /* do the rlf known zero trick here */
1293         emitpcode(POC_MOVLW,  popGetLit(1));
1294         emitSKPNC;
1295         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1296       }
1297       offset++;
1298     }
1299 #endif
1300   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1301     // bit subtraction
1302
1303     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1304     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1305     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1306
1307     /* here we are subtracting a bit from a char or int */
1308     if(size == 1) {
1309       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1310
1311         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1312         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1313
1314         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1315                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1316                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1317         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1318       } else {
1319
1320         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1321           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1322           emitpcode(POC_XORLW , popGetLit(1));
1323         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1324               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1325
1326           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1327
1328           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1329             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1330               if(lit & 1) {
1331                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1332                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1333               }
1334             }else{
1335               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1336               if(lit & 1) 
1337                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1338               else
1339                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1340               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1341             }
1342             goto release;
1343           } else {
1344             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1345             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1346             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1347             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1348
1349           }
1350
1351         } else {
1352           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1353           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1354           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1355         }
1356           
1357         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1358             
1359           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1360
1361         } else  {
1362           emitpcode(POC_ANDLW , popGetLit(1));
1363 /*
1364           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1365           emitSKPZ;
1366           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1367 */
1368         }
1369
1370       }
1371
1372     }
1373   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1374               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1375               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1376
1377     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1378     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1379                    AopType(AOP_TYPE(IC_RESULT(ic))),
1380                    AopType(AOP_TYPE(IC_LEFT(ic))),
1381                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1382
1383
1384     if( (size == 1) && ((lit & 0xff) == 0) ) {
1385       /* res = 0 - right */
1386       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1387         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1388         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1389       } else { 
1390         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1391         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1392         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1393       }
1394       goto release;
1395     }
1396
1397     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1398     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1399     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1400
1401
1402     offset = 1;
1403     while(--size) {
1404       lit >>= 8;
1405
1406       if(size == 1) {
1407         /* This is the last byte in a multibyte subtraction 
1408          * There are a couple of tricks we can do by not worrying about 
1409          * propogating the carry */
1410         if(lit == 0xff) {
1411           /* 0xff - x == ~x */
1412           if(same) {
1413             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1414             emitSKPC;
1415             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1416           } else {
1417             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1418             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1419             emitSKPC;
1420             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1421           }
1422         } else {
1423             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1424             emitSKPC;
1425             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1426             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1427             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1428         }
1429
1430         goto release;
1431       }
1432
1433       if(same) {
1434
1435         if(lit & 0xff) {
1436           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1437           emitSKPC;
1438           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1439           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1440         } else {
1441           emitSKPNC;
1442           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1443
1444         }
1445       } else {
1446
1447         if(lit & 0xff) {
1448           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1449           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1450         } else
1451           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1452
1453         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1454         emitSKPC;
1455         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1456         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1457       }
1458     }
1459   
1460
1461   } else {
1462
1463     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1464                    AopType(AOP_TYPE(IC_RESULT(ic))),
1465                    AopType(AOP_TYPE(IC_LEFT(ic))),
1466                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1467
1468     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1469       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1470       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1471       emitpcode(POC_SUBLW, popGetLit(0));
1472       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1473     } else {
1474
1475       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1476         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1477         emitpcode(POC_SUBLW, popGetLit(0));
1478         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1479           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1480       } else {
1481
1482         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1483         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1484           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1485
1486         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1487           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1488         else {
1489           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1490               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1491             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1492           } else {
1493             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1494           }
1495           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1496             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1497               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1498               emitSKPZ;
1499               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1500             }else
1501               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1502           }
1503         }
1504       }
1505     }
1506
1507     /*
1508       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1509
1510       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1511       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1512       } else {
1513       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1514       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1515       }
1516     */
1517     offset = 1;
1518     size--;
1519
1520     while(size--){
1521       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1522         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1523         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1524       }
1525       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1526       emitSKPC;
1527       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1528       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1529
1530       offset++;
1531     }
1532
1533   }
1534
1535
1536   //    adjustArithmeticResult(ic);
1537         
1538  release:
1539   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1540   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1541   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1542 }
1543 /*-----------------------------------------------------------------*
1544  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1545  * 
1546  * 
1547  *-----------------------------------------------------------------*/
1548 void genUMult8XLit_16 (operand *left,
1549                        operand *right,
1550                        operand *result,
1551                        pCodeOpReg *result_hi)
1552
1553 {
1554
1555   unsigned int lit;
1556   unsigned int i,have_first_bit;
1557   int same;
1558
1559   if (AOP_TYPE(right) != AOP_LIT){
1560     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1561     exit(1);
1562   }
1563
1564
1565   if(!result_hi) {
1566     result_hi = PCOR(popGet(AOP(result),1));
1567   }
1568
1569   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1570   lit &= 0xff;
1571   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1572
1573   same = pic14_sameRegs(AOP(left), AOP(result));
1574
1575   if(same) {
1576     switch(lit) {
1577     case 0:
1578       emitpcode(POC_CLRF,  popGet(AOP(left),0));
1579       return;
1580     case 2:
1581       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1582       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1583       return;
1584     case 3:
1585       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1586       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1587       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1588       return;
1589     case 4:
1590       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1591       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1592       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1593       return;
1594     case 16:
1595       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1596       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1597       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1598       return;
1599     case 17:
1600       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1601       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1602       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1603       return;
1604
1605     }
1606   } else {
1607
1608     switch(lit) {
1609     case 0:
1610       emitpcode(POC_CLRF,  popGet(AOP(result),0));
1611       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1612       return;
1613     case 2:
1614       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1615       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1616       emitpcode(POC_ADDWF, popGet(AOP(result),0));
1617       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1618       emitpcode(POC_RLF,   popCopyReg(result_hi));
1619       return;
1620     }
1621
1622   }
1623
1624   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1625   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1626   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1627
1628   have_first_bit = 0;
1629   for(i=0; i<8; i++) {
1630
1631     if(lit & 1) {
1632       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1633       have_first_bit = 1;
1634     }
1635
1636     if(have_first_bit) {
1637       emitpcode(POC_RRF,   popCopyReg(result_hi));
1638       emitpcode(POC_RRF,   popGet(AOP(result),0));
1639     }
1640
1641     lit >>= 1;
1642   }
1643
1644 }
1645
1646 /*-----------------------------------------------------------------*
1647  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1648  * 
1649  * 
1650  *-----------------------------------------------------------------*/
1651 void genUMult8X8_16 (operand *left,
1652                      operand *right,
1653                      operand *result,
1654                      pCodeOpReg *result_hi)
1655
1656 {
1657
1658   int i;
1659   int looped = 1;
1660
1661   if(!result_hi) {
1662     result_hi = PCOR(popGet(AOP(result),1));
1663   }
1664
1665   if (AOP_TYPE(right) == AOP_LIT) {
1666     genUMult8XLit_16(left,right,result,result_hi);
1667     return;
1668   }
1669
1670   if(!looped) {
1671     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1672
1673     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1674     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1675     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1676     emitCLRC;
1677
1678     for(i=0; i<8; i++) {
1679       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1680       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1681       emitpcode(POC_RRF,   popCopyReg(result_hi));
1682       emitpcode(POC_RRF,   popGet(AOP(result),0));
1683     }
1684
1685
1686     /*
1687       Here's another version that does the same thing and takes the 
1688       same number of instructions. The one above is slightly better
1689       because the entry instructions have a higher probability of
1690       being optimized out.
1691     */
1692     /*
1693       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1694       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1695       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1696       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1697
1698       for(i=0; i<8; i++) {
1699       emitSKPNC;
1700       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1701       emitpcode(POC_RRF,   popCopyReg(result_hi));
1702       emitpcode(POC_RRF,   popGet(AOP(result),0));
1703       }
1704     */
1705
1706   } else {
1707     symbol  *tlbl = newiTempLabel(NULL);
1708     pCodeOp *temp;
1709
1710
1711     pic14_emitcode(";","Looped 8 X 8 multiplication");
1712
1713     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1714     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1715
1716     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1717
1718     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1719
1720     temp = popGetTempReg();
1721     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1722
1723     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1724
1725     emitpLabel(tlbl->key);
1726
1727     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1728     emitSKPNC;
1729     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1730
1731     emitpcode(POC_RRF,   popCopyReg(result_hi));
1732     emitpcode(POC_RRF,   popGet(AOP(result),0));
1733
1734     emitSKPC;
1735     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1736
1737     popReleaseTempReg(temp);
1738
1739   }
1740 }
1741
1742 /*-----------------------------------------------------------------*
1743  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1744  *
1745  *  this routine will call the unsigned multiply routine and then
1746  * post-fix the sign bit.
1747  *-----------------------------------------------------------------*/
1748 void genSMult8X8_16 (operand *left,
1749                      operand *right,
1750                      operand *result,
1751                      pCodeOpReg *result_hi)
1752 {
1753
1754   if(!result_hi) {
1755     result_hi = PCOR(popGet(AOP(result),1));
1756   }
1757
1758   genUMult8X8_16(left,right,result,result_hi);
1759
1760   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1761   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1762   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1763   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1764   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1765   
1766 }
1767
1768 /*-----------------------------------------------------------------*
1769  * genMult8X8_8 - multiplication of two 8-bit numbers
1770  *
1771  *  this routine will call the unsigned multiply 8X8=>16 routine and
1772  * then throw away the high byte of the result.
1773  *
1774  *-----------------------------------------------------------------*/
1775 void genMult8X8_8 (operand *left,
1776                    operand *right,
1777                    operand *result)
1778 {
1779   pCodeOp *result_hi = popGetTempReg();
1780
1781   if (AOP_TYPE(right) == AOP_LIT)
1782     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1783   else
1784     genUMult8X8_16(left,right,result,PCOR(result_hi));
1785
1786   popReleaseTempReg(result_hi);
1787 }
1788 #if 0
1789 /*-----------------------------------------------------------------*/
1790 /* constMult - generates code for multiplication by a constant     */
1791 /*-----------------------------------------------------------------*/
1792 void genMultConst(unsigned C)
1793 {
1794
1795   unsigned lit;
1796   unsigned sr3; // Shift right 3
1797   unsigned mask;
1798
1799   int size = 1;
1800
1801   /*
1802     Convert a string of 3 binary 1's in the lit into
1803     0111 = 1000 - 1;
1804   */
1805
1806   mask = 7 << ( (size*8) - 3);
1807   lit = C;
1808   sr3 = 0;
1809
1810   while(mask < (1<<size*8)) {
1811
1812     if( (mask & lit) == lit) {
1813       unsigned lsb;
1814
1815       /* We found 3 (or more) consecutive 1's */
1816
1817       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1818
1819       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1820
1821       lit ^= consecutive_bits;
1822
1823       mask <<= 3;
1824
1825       sr3 |= (consecutive + lsb);
1826
1827     }
1828
1829     mask >>= 1;
1830
1831   }
1832
1833 }
1834
1835 #endif