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