* src/port.h (PORT structure): added hook initPaths, now each
[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                 size = min( size, AOP_SIZE(left) );
983                 offset = 0;
984
985                 if(pic16_debug_verbose) {
986 //                      fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
987 //                              AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
988 //                      fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
989                 }
990
991
992
993                 if ((AOP_TYPE(left) == AOP_PCODE) && (
994                                 (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
995 //                              (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
996                                 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
997                 {
998                         // add to literal operand
999
1000                         // add first bytes
1001                         for(i=0; i<size; i++) {
1002                                 if (AOP_TYPE(right) == AOP_ACC) {
1003                                         pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1004                                 } else {
1005                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1006                                         if(i) { // add with carry
1007                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1008                                         } else { // add without
1009                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1010                                         }
1011                                 }
1012                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1013                         }
1014
1015                         // add leftover bytes
1016                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1017                                 // right is unsigned
1018                                 for(i=size; i< AOP_SIZE(result); i++) {
1019                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1020                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1021                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1022                                 }
1023
1024                         } else {
1025                                 // right is signed, oh dear ...
1026                                 for(i=size; i< AOP_SIZE(result); i++) {
1027                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1028                                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0));
1029                                         pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1030                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1031                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1032                                 }
1033
1034                         }
1035                         goto release;
1036
1037                 } else {
1038                         // add regs
1039
1040                         // add first bytes
1041                         for(i=0; i<size; i++) {
1042                                 if (AOP_TYPE(right) != AOP_ACC)
1043                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1044                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1045                                 {
1046                                         if(i) { // add with carry
1047                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1048                                         } else { // add without
1049                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1050                                         }
1051                                 } else { // not same
1052                                         if(i) { // add with carry
1053                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1054                                         } else { // add without
1055                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1056                                         }
1057                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1058                                 }
1059                         }
1060
1061                         // add leftover bytes
1062                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1063                                 // right is unsigned
1064                                 for(i=size; i< AOP_SIZE(result); i++) {
1065                                         if (pic16_sameRegs(AOP(left), AOP(result)))
1066                                         {
1067                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1068                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1069                                         } else { // not same
1070                                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1071                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1072                                         }
1073                                 }
1074                         } else {
1075                                 // right is signed
1076                                 for(i=size; i< AOP_SIZE(result); i++) {
1077                                         if(size < AOP_SIZE(left)) {
1078                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1079                                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
1080                                                 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1081                                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1082                                                 {
1083                                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1084                                                 } else { // not same
1085                                                         pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1086                                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1087                                                 }
1088                                         } else {
1089                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1090                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1091                                         }
1092                                 }
1093                         }
1094                         goto release;
1095                 }
1096
1097         }
1098
1099         // TODO:        anything from here to before "release:" is probably obsolete and should be removed
1100         //              when the regression tests are stable
1101
1102         if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1103                 int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1104                                 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1105
1106
1107                 /* Need to extend result to higher bytes */
1108                 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1109
1110                 /* First grab the carry from the lower bytes */
1111                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1112                 pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1113
1114
1115                 if(sign) {
1116                         /* Now this is really horrid. Gotta check the sign of the addends and propogate
1117                         * to the result */
1118
1119                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1120                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1121                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1122                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1123
1124                         /* if chars or ints or being signed extended to longs: */
1125                         if(size) {
1126                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1127                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1128                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1129                         }
1130                 }
1131
1132                 offset++;
1133                 while(size--) {
1134       
1135                         if(sign)
1136                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1137                         else
1138                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1139
1140                         offset++;
1141                 }
1142         }
1143
1144
1145         //adjustArithmeticResult(ic);
1146
1147         release:
1148         pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1149         pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1150         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1151 }
1152
1153 /*-----------------------------------------------------------------*/
1154 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1155 /*-----------------------------------------------------------------*/
1156 bool pic16_genMinusDec (iCode *ic)
1157 {
1158     unsigned int icount ;
1159     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1160
1161     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1162     /* will try to generate an increment */
1163     /* if the right side is not a literal 
1164     we cannot */
1165     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1166         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1167         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1168         return FALSE ;
1169
1170     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1171
1172     /* if the literal value of the right hand side
1173     is greater than 4 then it is not worth it */
1174     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1175         return FALSE ;
1176
1177     /* if decrement 16 bits in register */
1178     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1179         (size > 1) &&
1180         (icount == 1)) {
1181
1182       if(size == 2) { 
1183         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1184         pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1185         pic16_emitpcode(POC_INCF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1186         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1187
1188         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1189         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1190         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1191       } else {
1192         /* size is 3 or 4 */
1193         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1194         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1195         emitSKPNC;
1196         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1197         emitSKPNC;
1198         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1199
1200         pic16_emitcode("movlw","0xff");
1201         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1202
1203         emitSKPNC;
1204         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1205         emitSKPNC;
1206         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1207
1208         if(size > 3) {
1209           emitSKPNC;
1210           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1211
1212           pic16_emitcode("skpnc","");
1213           emitSKPNC;
1214           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1215         }
1216
1217       }
1218
1219       return TRUE;
1220
1221     }
1222
1223     /* if the sizes are greater than 1 then we cannot */
1224     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1225         AOP_SIZE(IC_LEFT(ic)) > 1   )
1226         return FALSE ;
1227
1228     /* we can if the aops of the left & result match or
1229     if they are in registers and the registers are the
1230     same */
1231     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1232
1233       while (icount--) 
1234         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1235
1236         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1237
1238         return TRUE ;
1239     }
1240
1241     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1242                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1243                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1244     if(size==1) {
1245
1246       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1247       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1248
1249       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1250       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1251
1252       return TRUE;
1253     }
1254
1255     return FALSE ;
1256 }
1257
1258 /*-----------------------------------------------------------------*/
1259 /* pic16_addSign - propogate sign bit to higher bytes                    */
1260 /*-----------------------------------------------------------------*/
1261 void pic16_addSign(operand *result, int offset, int sign)
1262 {
1263   int size = (pic16_getDataSize(result) - offset);
1264   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1265
1266   if(size > 0){
1267     if(sign && offset) {
1268
1269       if(size == 1) {
1270         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1271         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1272         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1273       } else {
1274
1275         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1276         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1277         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1278         while(size--)
1279           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1280
1281       }
1282     } else
1283       while(size--)
1284         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1285   }
1286 }
1287
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1290 /*-----------------------------------------------------------------*/
1291 void pic16_genMinusBits (iCode *ic)
1292 {
1293     symbol *lbl = newiTempLabel(NULL);
1294     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1295     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1296         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1297         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1298         pic16_emitcode("cpl","c");
1299         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1300         pic16_outBitC(IC_RESULT(ic));
1301     }
1302     else{
1303         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1304         pic16_emitcode("subb","a,acc");
1305         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1306         pic16_emitcode("inc","a");
1307         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1308         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1309         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1310     }
1311 }
1312
1313 /*-----------------------------------------------------------------*/
1314 /* pic16_genMinus - generates code for subtraction                       */
1315 /*-----------------------------------------------------------------*/
1316 void pic16_genMinus (iCode *ic)
1317 {
1318   int size, offset = 0, same=0;
1319   unsigned long lit = 0L;
1320
1321   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1322   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1323   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1324   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1325
1326   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1327       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1328     operand *t = IC_RIGHT(ic);
1329     IC_RIGHT(ic) = IC_LEFT(ic);
1330     IC_LEFT(ic) = t;
1331   }
1332
1333   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1334                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1335                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1336                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1337
1338   /* special cases :- */
1339   /* if both left & right are in bit space */
1340   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1341       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1342     pic16_genPlusBits (ic);
1343     goto release ;
1344   }
1345
1346   /* if I can do an decrement instead
1347      of subtract then GOOD for ME */
1348   //  if (pic16_genMinusDec (ic) == TRUE)
1349   //    goto release;   
1350
1351   size = pic16_getDataSize(IC_RESULT(ic));   
1352   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1353
1354   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1355     /* Add a literal to something else */
1356
1357     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1358     lit = - (long)lit;
1359
1360     genAddLit ( ic,  lit);
1361     
1362 #if 0
1363     /* add the first byte: */
1364     pic16_emitcode("movlw","0x%x", lit & 0xff);
1365     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1366     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1367     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1368
1369
1370     offset = 1;
1371     size--;
1372
1373     while(size-- > 0) {
1374
1375       lit >>= 8;
1376
1377       if(lit & 0xff) {
1378
1379         if((lit & 0xff) == 0xff) {
1380           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1381           emitSKPC;
1382           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1383         } else {
1384           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1385           emitSKPNC;
1386           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1387           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1388         }
1389
1390       } else {
1391         /* do the rlf known zero trick here */
1392         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1393         emitSKPNC;
1394         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1395       }
1396       offset++;
1397     }
1398 #endif
1399   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1400     // bit subtraction
1401
1402     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1403     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1404     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1405
1406     /* here we are subtracting a bit from a char or int */
1407     if(size == 1) {
1408       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1409
1410         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1412
1413         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1414                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1415                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1416         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1417       } else {
1418
1419         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1420           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1421           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1422         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1423               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1424
1425           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1426
1427           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1428             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1429               if(lit & 1) {
1430                 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1432               }
1433             }else{
1434               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1435               if(lit & 1) 
1436                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1437               else
1438                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1439               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1440             }
1441             goto release;
1442           } else {
1443             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1444             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1445             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1446             pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1447
1448           }
1449
1450         } else {
1451           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1452           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1453           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1454         }
1455           
1456         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1457             
1458           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1459
1460         } else  {
1461           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1462 /*
1463           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1464           emitSKPZ;
1465           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1466 */
1467         }
1468
1469       }
1470
1471     }
1472   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1473               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1474               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1475
1476     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1477     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1478                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1479                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1480                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1481
1482
1483     if( (size == 1) && ((lit & 0xff) == 0) ) {
1484       /* res = 0 - right */
1485       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1486         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1487         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1488       } else { 
1489         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1490         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1491         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1492       }
1493       goto release;
1494     }
1495
1496     pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1497     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1498     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1499
1500
1501     offset = 1;
1502     while(--size) {
1503       lit >>= 8;
1504
1505       if(size == 1) {
1506         /* This is the last byte in a multibyte subtraction 
1507          * There are a couple of tricks we can do by not worrying about 
1508          * propogating the carry */
1509         if(lit == 0xff) {
1510           /* 0xff - x == ~x */
1511           if(same) {
1512             pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1513             emitSKPC;
1514             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1515           } else {
1516             pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1517             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1518             emitSKPC;
1519             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1520           }
1521         } else {
1522             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1523             emitSKPC;
1524             pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1525             pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1526             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1527         }
1528
1529         goto release;
1530       }
1531
1532       if(same) {
1533
1534         if(lit & 0xff) {
1535           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1536           emitSKPC;
1537           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1538           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1539         } else {
1540           emitSKPNC;
1541           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1542
1543         }
1544       } else {
1545
1546         if(lit & 0xff) {
1547           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1548           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1549         } else
1550           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1551
1552         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1553         emitSKPC;
1554         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1555         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1556       }
1557     }
1558   
1559
1560   } else {
1561
1562     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1563                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1564                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1565                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1566
1567     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1568       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1569       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1570       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1571       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1572     } else {
1573
1574       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1575         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1576         pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1577         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1578           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1579       } else {
1580
1581         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1582         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1583           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1584
1585         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1586           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1587         else {
1588           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1589               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1590             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1591           } else {
1592             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1593           }
1594           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1595             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1596               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1597               emitSKPZ;
1598               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1599             }else
1600               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1601           }
1602         }
1603       }
1604     }
1605
1606     /*
1607       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1608
1609       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1610       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1611       } else {
1612       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1613       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1614       }
1615     */
1616     offset = 1;
1617     size--;
1618
1619     while(size--){
1620       if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1621         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1622         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1623       }
1624       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1625       emitSKPC;
1626       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1627       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1628
1629       offset++;
1630     }
1631
1632   }
1633
1634
1635   //    adjustArithmeticResult(ic);
1636         
1637  release:
1638   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1639   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1640   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1641 }
1642
1643
1644 /*-----------------------------------------------------------------*
1645  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1646  * 
1647  * 
1648  *-----------------------------------------------------------------*/
1649 void pic16_genUMult8XLit_8 (operand *left,
1650                              operand *right,
1651                              operand *result)
1652 {
1653   unsigned int lit;
1654   int same;
1655
1656
1657         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1658
1659         if (AOP_TYPE(right) != AOP_LIT){
1660                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1661                 exit(1);
1662         }
1663
1664         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1665         lit &= 0xff;
1666         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1667         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1668         
1669         same = pic16_sameRegs(AOP(left), AOP(result));
1670         if(same) {
1671                 switch(lit) {
1672                         case 0:
1673                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1674                                 return;
1675                         case 2:
1676                                 // its faster to left shift
1677                                 emitCLRC;
1678                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1679                                 return;
1680
1681                         default:
1682                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1683                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1684                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1685                                         pic16_popGet(AOP(result), 0)));
1686                                 return;
1687                 }
1688         } else {
1689                 // operands different
1690                 switch(lit) {
1691                         case 0:
1692                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1693                                 return;
1694                         case 2:
1695                                 emitCLRC;
1696                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1697                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1698                                 return;
1699                         default:
1700                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1701                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1702                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1703                                         pic16_popGet(AOP(result), 0)));
1704                                 return;
1705                 }
1706         }
1707 }
1708
1709 /*-----------------------------------------------------------------------*
1710  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1711  *-----------------------------------------------------------------------*/
1712 void pic16_genUMult16XLit_16 (operand *left,
1713                              operand *right,
1714                              operand *result)
1715 {
1716   pCodeOp *pct1, *pct2, *pct3, *pct4;
1717   unsigned int lit;
1718   int same;
1719
1720
1721         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1722
1723         if (AOP_TYPE(right) != AOP_LIT){
1724                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1725                 exit(1);
1726         }
1727
1728         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1729         lit &= 0xffff;
1730
1731         same = pic16_sameRegs(AOP(left), AOP(result));
1732         if(same) {
1733                 switch(lit) {
1734                         case 0:
1735                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1736                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1737                                 return;
1738                         case 2:
1739                                 // its faster to left shift
1740                                 emitCLRC;
1741                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1742                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1743                                 return;
1744
1745                         default: {
1746                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1747
1748                                 pct1 = pic16_popGetTempReg();
1749                                 pct2 = pic16_popGetTempReg();
1750                                 pct3 = pic16_popGetTempReg();
1751                                 pct4 = pic16_popGetTempReg();
1752
1753                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1754                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1755                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1756                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1757                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1758                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1759                                         
1760                                 /* WREG still holds the low literal */
1761                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1762                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1763                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1764                                         
1765                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1766                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1767                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1768                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1769                                         
1770                                 /* load result */
1771                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1772                                         pct1, pic16_popGet(AOP(result), 0)));
1773                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1774                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1775                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1776                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1777
1778                                 pic16_popReleaseTempReg( pct4 );
1779                                 pic16_popReleaseTempReg( pct3 );
1780                                 pic16_popReleaseTempReg( pct2 );
1781                                 pic16_popReleaseTempReg( pct1 );
1782                         }; return;
1783                 }
1784         } else {
1785                 // operands different
1786                 switch(lit) {
1787                         case 0:
1788                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1789                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1790                                 return;
1791                         case 2:
1792                                 emitCLRC;
1793                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1794                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1795                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1796                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1797                                 return;
1798                         default: {
1799                                         
1800                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1801                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1802                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1803                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1804                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1805                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1806                                         
1807                                 /* WREG still holds the low literal */
1808                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1809                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1810                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1811                                         
1812                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1813                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1814                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1815                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1816
1817                         }; return;
1818                 }
1819         }
1820 }
1821
1822
1823 /*-----------------------------------------------------------------*
1824  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1825  * 
1826  * 
1827  *-----------------------------------------------------------------*/
1828 void pic16_genUMult8X8_8 (operand *left,
1829                            operand *right,
1830                            operand *result)
1831
1832 {
1833         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1834
1835
1836         if (AOP_TYPE(right) == AOP_LIT) {
1837                 pic16_genUMult8XLit_8(left,right,result);
1838           return;
1839         }
1840
1841         /* cases:
1842                 A = A x B       B = A x B
1843                 A = B x C
1844                 W = A x B
1845                 W = W x B       W = B x W
1846         */
1847         /* if result == right then exchange left and right */
1848         if(pic16_sameRegs(AOP(result), AOP(right))) {
1849           operand *tmp;
1850                 tmp = left;
1851                 left = right;
1852                 right = tmp;
1853         }
1854                 
1855         if(AOP_TYPE(left) != AOP_ACC) {
1856                 // left is not WREG
1857                 if(AOP_TYPE(right) != AOP_ACC) {
1858                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1859                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1860                 } else {
1861                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1862                 }
1863         } else {
1864                 // left is WREG, right cannot be WREG (or can?!)
1865                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1866         }
1867         
1868         /* result is in PRODL:PRODH */
1869         if(AOP_TYPE(result) != AOP_ACC) {
1870                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1871                         pic16_popGet(AOP(result), 0)));
1872
1873
1874                 if(AOP_SIZE(result)>1) {
1875                   int i;
1876
1877                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1878                         pic16_popGet(AOP(result), 1)));
1879                         
1880                         for(i=2;i<AOP_SIZE(result);i++)
1881                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1882                 }
1883         } else {
1884                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1885         }
1886 }
1887
1888 /*------------------------------------------------------------------*
1889  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1890  *------------------------------------------------------------------*/
1891 void pic16_genUMult16X16_16 (operand *left,
1892                            operand *right,
1893                            operand *result)
1894
1895 {
1896   pCodeOp *pct1, *pct2, *pct3, *pct4;
1897
1898         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1899
1900
1901         if (AOP_TYPE(right) == AOP_LIT) {
1902                 pic16_genUMult8XLit_8(left,right,result);
1903           return;
1904         }
1905
1906         /* cases:
1907                 A = A x B       B = A x B
1908                 A = B x C
1909         */
1910         /* if result == right then exchange left and right */
1911         if(pic16_sameRegs(AOP(result), AOP(right))) {
1912           operand *tmp;
1913                 tmp = left;
1914                 left = right;
1915                 right = tmp;
1916         }
1917
1918
1919         if(pic16_sameRegs(AOP(result), AOP(left))) {
1920
1921                 pct1 = pic16_popGetTempReg();
1922                 pct2 = pic16_popGetTempReg();
1923                 pct3 = pic16_popGetTempReg();
1924                 pct4 = pic16_popGetTempReg();
1925
1926                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1927                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1928                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1929                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1930                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1931                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1932                                         
1933                 /* WREG still holds the lower left */
1934                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1935                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1936                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1937                 
1938                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1939                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1940                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1941                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1942                                         
1943                 /* load result */
1944                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1945                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1946                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1947                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1948                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1949                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1950
1951                 pic16_popReleaseTempReg( pct4 );
1952                 pic16_popReleaseTempReg( pct3 );
1953                 pic16_popReleaseTempReg( pct2 );
1954                 pic16_popReleaseTempReg( pct1 );
1955
1956         } else {
1957
1958                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1959                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1960                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1961                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1962                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1963                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1964
1965                 /* WREG still holds the lower left */
1966                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1967                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1968                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1969                 
1970                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1971                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1972                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1973                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1974         }       
1975 }
1976
1977
1978 void pic16_genSMult16X16_16(operand *left,
1979                         operand *right,
1980                         operand *result)
1981 {
1982
1983 }
1984
1985 #if 0
1986 /*-----------------------------------------------------------------*
1987  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1988  *
1989  *  this routine will call the unsigned multiply routine and then
1990  * post-fix the sign bit.
1991  *-----------------------------------------------------------------*/
1992 void pic16_genSMult8X8_8 (operand *left,
1993                            operand *right,
1994                            operand *result,
1995                            pCodeOpReg *result_hi)
1996 {
1997         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1998
1999
2000   if(!result_hi) {
2001     result_hi = PCOR(pic16_popGet(AOP(result),1));
2002   }
2003
2004
2005   pic16_genUMult8X8_8(left,right,result);
2006
2007   
2008 #if 0
2009   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
2010   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2011   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2012   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
2013   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2014 #endif
2015 }
2016 #endif
2017
2018 /*-----------------------------------------------------------------*
2019  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2020  *-----------------------------------------------------------------*/
2021 void pic16_genMult8X8_8 (operand *left,
2022                          operand *right,
2023                          operand *result)
2024 {
2025         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2026
2027         if(AOP_TYPE(right) == AOP_LIT)
2028                 pic16_genUMult8XLit_8(left,right,result);
2029         else
2030                 pic16_genUMult8X8_8(left,right,result);
2031 }
2032
2033
2034 /*-----------------------------------------------------------------*
2035  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2036  *-----------------------------------------------------------------*/
2037 void pic16_genMult16X16_16 (operand *left,
2038                          operand *right,
2039                          operand *result)
2040 {
2041         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2042
2043         if (AOP_TYPE(right) == AOP_LIT)
2044                 pic16_genUMult16XLit_16(left,right,result);
2045         else
2046                 pic16_genUMult16X16_16(left,right,result);
2047
2048 }
2049
2050
2051
2052
2053 /*-----------------------------------------------------------------------*
2054  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2055  *-----------------------------------------------------------------------*/
2056 void pic16_genUMult32XLit_32 (operand *left,
2057                              operand *right,
2058                              operand *result)
2059 {
2060   pCodeOp *pct1, *pct2, *pct3, *pct4;
2061   unsigned int lit;
2062   int same;
2063
2064
2065         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2066
2067         if (AOP_TYPE(right) != AOP_LIT){
2068                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2069                 exit(1);
2070         }
2071
2072         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2073         lit &= 0xffff;
2074
2075         same = pic16_sameRegs(AOP(left), AOP(result));
2076         if(same) {
2077                 switch(lit) {
2078                         case 0:
2079                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2080                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2081                                 return;
2082                         case 2:
2083                                 // its faster to left shift
2084                                 emitCLRC;
2085                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2086                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2087                                 return;
2088
2089                         default: {
2090                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2091
2092                                 pct1 = pic16_popGetTempReg();
2093                                 pct2 = pic16_popGetTempReg();
2094                                 pct3 = pic16_popGetTempReg();
2095                                 pct4 = pic16_popGetTempReg();
2096
2097                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2098                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2099                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2101                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2102                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2103                                         
2104                                 /* WREG still holds the low literal */
2105                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2106                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2107                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2108                                         
2109                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2110                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2111                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2112                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2113                                         
2114                                 /* load result */
2115                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2116                                         pct1, pic16_popGet(AOP(result), 0)));
2117                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2118                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2119                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2120                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2121
2122                                 pic16_popReleaseTempReg( pct4 );
2123                                 pic16_popReleaseTempReg( pct3 );
2124                                 pic16_popReleaseTempReg( pct2 );
2125                                 pic16_popReleaseTempReg( pct1 );
2126                         }; return;
2127                 }
2128         } else {
2129                 // operands different
2130                 switch(lit) {
2131                         case 0:
2132                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2133                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2134                                 return;
2135                         case 2:
2136                                 emitCLRC;
2137                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2138                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2139                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2140                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2141                                 return;
2142                         default: {
2143                                         
2144                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2145                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2146                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2147                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2148                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2149                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2150                                         
2151                                 /* WREG still holds the low literal */
2152                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2153                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2154                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2155                                         
2156                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2157                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2158                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2159                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2160
2161                         }; return;
2162                 }
2163         }
2164 }
2165
2166
2167 /*------------------------------------------------------------------*
2168  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2169  *------------------------------------------------------------------*/
2170 void pic16_genUMult32X32_32 (operand *left,
2171                            operand *right,
2172                            operand *result)
2173
2174 {
2175   pCodeOp *pct1, *pct2, *pct3, *pct4;
2176
2177         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2178
2179
2180         if (AOP_TYPE(right) == AOP_LIT) {
2181                 pic16_genUMult8XLit_8(left,right,result);
2182           return;
2183         }
2184
2185         /* cases:
2186                 A = A x B       B = A x B
2187                 A = B x C
2188         */
2189         /* if result == right then exchange left and right */
2190         if(pic16_sameRegs(AOP(result), AOP(right))) {
2191           operand *tmp;
2192                 tmp = left;
2193                 left = right;
2194                 right = tmp;
2195         }
2196
2197
2198         if(pic16_sameRegs(AOP(result), AOP(left))) {
2199
2200                 pct1 = pic16_popGetTempReg();
2201                 pct2 = pic16_popGetTempReg();
2202                 pct3 = pic16_popGetTempReg();
2203                 pct4 = pic16_popGetTempReg();
2204
2205                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2206                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2207                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2209                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2210                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2211                                         
2212                 /* WREG still holds the lower left */
2213                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2214                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2216                 
2217                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2218                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2219                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2220                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2221                                         
2222                 /* load result */
2223                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2224                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2225                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2226                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2227                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2228                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2229
2230                 pic16_popReleaseTempReg( pct4 );
2231                 pic16_popReleaseTempReg( pct3 );
2232                 pic16_popReleaseTempReg( pct2 );
2233                 pic16_popReleaseTempReg( pct1 );
2234
2235         } else {
2236
2237                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2238                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2239                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2240                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2241                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2242                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2243
2244                 /* WREG still holds the lower left */
2245                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2246                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2247                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2248                 
2249                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2250                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2251                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2252                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2253         }       
2254 }
2255
2256
2257 /*-----------------------------------------------------------------*
2258  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2259  *-----------------------------------------------------------------*/
2260 void pic16_genMult32X32_32 (operand *left,
2261                          operand *right,
2262                          operand *result)
2263 {
2264         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2265
2266         if (AOP_TYPE(right) == AOP_LIT)
2267                 pic16_genUMult32XLit_32(left,right,result);
2268         else
2269                 pic16_genUMult32X32_32(left,right,result);
2270
2271 }
2272
2273
2274
2275
2276
2277
2278
2279 #if 0
2280 /*-----------------------------------------------------------------*/
2281 /* constMult - generates code for multiplication by a constant     */
2282 /*-----------------------------------------------------------------*/
2283 void genMultConst(unsigned C)
2284 {
2285
2286   unsigned lit;
2287   unsigned sr3; // Shift right 3
2288   unsigned mask;
2289
2290   int size = 1;
2291
2292   /*
2293     Convert a string of 3 binary 1's in the lit into
2294     0111 = 1000 - 1;
2295   */
2296
2297   mask = 7 << ( (size*8) - 3);
2298   lit = C;
2299   sr3 = 0;
2300
2301   while(mask < (1<<size*8)) {
2302
2303     if( (mask & lit) == lit) {
2304       unsigned lsb;
2305
2306       /* We found 3 (or more) consecutive 1's */
2307
2308       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2309
2310       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2311
2312       lit ^= consecutive_bits;
2313
2314       mask <<= 3;
2315
2316       sr3 |= (consecutive + lsb);
2317
2318     }
2319
2320     mask >>= 1;
2321
2322   }
2323
2324 }
2325
2326 #endif