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