d6e5d7968b29617e066bb14461c9799ea969c073
[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) && (
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
1561   if (AOP_TYPE(right) != AOP_LIT){
1562     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1563     exit(1);
1564   }
1565
1566
1567   if(!result_hi) {
1568     result_hi = PCOR(popGet(AOP(result),1));
1569   }
1570
1571   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1572   lit &= 0xff;
1573   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1574
1575   same = pic14_sameRegs(AOP(left), AOP(result));
1576
1577   if(same) {
1578     switch(lit) {
1579     case 0:
1580       emitpcode(POC_CLRF,  popGet(AOP(left),0));
1581       return;
1582     case 2:
1583       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1584       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1585       return;
1586     case 3:
1587       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1588       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1589       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1590       return;
1591     case 4:
1592       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1593       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1594       emitpcode(POC_ADDWF, popGet(AOP(left),0));
1595       return;
1596     case 16:
1597       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1598       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1599       emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1600       return;
1601     case 17:
1602       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1603       emitpcode(POC_ANDLW,  popGetLit(0xf0));
1604       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1605       return;
1606
1607     }
1608   } else {
1609
1610     switch(lit) {
1611     case 0:
1612       emitpcode(POC_CLRF,  popGet(AOP(result),0));
1613       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1614       return;
1615     case 2:
1616       emitpcode(POC_MOVFW, popGet(AOP(left),0));
1617       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1618       emitpcode(POC_ADDWF, popGet(AOP(result),0));
1619       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1620       emitpcode(POC_RLF,   popCopyReg(result_hi));
1621       return;
1622     }
1623
1624   }
1625
1626   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1627   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1628   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1629
1630   have_first_bit = 0;
1631   for(i=0; i<8; i++) {
1632
1633     if(lit & 1) {
1634       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1635       have_first_bit = 1;
1636     }
1637
1638     if(have_first_bit) {
1639       emitpcode(POC_RRF,   popCopyReg(result_hi));
1640       emitpcode(POC_RRF,   popGet(AOP(result),0));
1641     }
1642
1643     lit >>= 1;
1644   }
1645
1646 }
1647
1648 /*-----------------------------------------------------------------*
1649  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1650  * 
1651  * 
1652  *-----------------------------------------------------------------*/
1653 void genUMult8X8_16 (operand *left,
1654                      operand *right,
1655                      operand *result,
1656                      pCodeOpReg *result_hi)
1657
1658 {
1659
1660   int i;
1661   int looped = 1;
1662
1663   if(!result_hi) {
1664     result_hi = PCOR(popGet(AOP(result),1));
1665   }
1666
1667   if (AOP_TYPE(right) == AOP_LIT) {
1668     genUMult8XLit_16(left,right,result,result_hi);
1669     return;
1670   }
1671
1672   if(!looped) {
1673     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1674
1675     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1676     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1677     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1678     emitCLRC;
1679
1680     for(i=0; i<8; i++) {
1681       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1682       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1683       emitpcode(POC_RRF,   popCopyReg(result_hi));
1684       emitpcode(POC_RRF,   popGet(AOP(result),0));
1685     }
1686
1687
1688     /*
1689       Here's another version that does the same thing and takes the 
1690       same number of instructions. The one above is slightly better
1691       because the entry instructions have a higher probability of
1692       being optimized out.
1693     */
1694     /*
1695       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1696       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1697       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1698       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1699
1700       for(i=0; i<8; i++) {
1701       emitSKPNC;
1702       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1703       emitpcode(POC_RRF,   popCopyReg(result_hi));
1704       emitpcode(POC_RRF,   popGet(AOP(result),0));
1705       }
1706     */
1707
1708   } else {
1709     symbol  *tlbl = newiTempLabel(NULL);
1710     pCodeOp *temp;
1711
1712
1713     pic14_emitcode(";","Looped 8 X 8 multiplication");
1714
1715     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1716     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1717
1718     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1719
1720     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1721
1722     temp = popGetTempReg();
1723     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1724
1725     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1726
1727     emitpLabel(tlbl->key);
1728
1729     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1730     emitSKPNC;
1731     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1732
1733     emitpcode(POC_RRF,   popCopyReg(result_hi));
1734     emitpcode(POC_RRF,   popGet(AOP(result),0));
1735
1736     emitSKPC;
1737     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1738
1739     popReleaseTempReg(temp);
1740
1741   }
1742 }
1743
1744 /*-----------------------------------------------------------------*
1745  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1746  *
1747  *  this routine will call the unsigned multiply routine and then
1748  * post-fix the sign bit.
1749  *-----------------------------------------------------------------*/
1750 void genSMult8X8_16 (operand *left,
1751                      operand *right,
1752                      operand *result,
1753                      pCodeOpReg *result_hi)
1754 {
1755
1756   if(!result_hi) {
1757     result_hi = PCOR(popGet(AOP(result),1));
1758   }
1759
1760   genUMult8X8_16(left,right,result,result_hi);
1761
1762   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1763   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1764   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1765   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1766   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1767   
1768 }
1769
1770 /*-----------------------------------------------------------------*
1771  * genMult8X8_8 - multiplication of two 8-bit numbers
1772  *
1773  *  this routine will call the unsigned multiply 8X8=>16 routine and
1774  * then throw away the high byte of the result.
1775  *
1776  *-----------------------------------------------------------------*/
1777 void genMult8X8_8 (operand *left,
1778                    operand *right,
1779                    operand *result)
1780 {
1781   pCodeOp *result_hi = popGetTempReg();
1782
1783   if (AOP_TYPE(right) == AOP_LIT)
1784     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1785   else
1786     genUMult8X8_16(left,right,result,PCOR(result_hi));
1787
1788   popReleaseTempReg(result_hi);
1789 }
1790 #if 0
1791 /*-----------------------------------------------------------------*/
1792 /* constMult - generates code for multiplication by a constant     */
1793 /*-----------------------------------------------------------------*/
1794 void genMultConst(unsigned C)
1795 {
1796
1797   unsigned lit;
1798   unsigned sr3; // Shift right 3
1799   unsigned mask;
1800
1801   int size = 1;
1802
1803   /*
1804     Convert a string of 3 binary 1's in the lit into
1805     0111 = 1000 - 1;
1806   */
1807
1808   mask = 7 << ( (size*8) - 3);
1809   lit = C;
1810   sr3 = 0;
1811
1812   while(mask < (1<<size*8)) {
1813
1814     if( (mask & lit) == lit) {
1815       unsigned lsb;
1816
1817       /* We found 3 (or more) consecutive 1's */
1818
1819       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1820
1821       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1822
1823       lit ^= consecutive_bits;
1824
1825       mask <<= 3;
1826
1827       sr3 |= (consecutive + lsb);
1828
1829     }
1830
1831     mask >>= 1;
1832
1833   }
1834
1835 }
1836
1837 #endif