* device/lib/Makefile.in: fixed bug in target objects-pic16,
[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 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
172 {
173
174   if(pcop && (pcop->type == PO_GPR_BIT)) {
175
176     switch(PCORB(pcop)->subtype) {
177
178     case  PO_NONE:
179       return "PO_NONE";
180     case  PO_W:
181       return  "PO_W";
182     case  PO_WREG:
183       return  "PO_WREG";
184     case  PO_STATUS:
185       return  "PO_STATUS";
186     case  PO_BSR:
187       return  "PO_BSR";
188     case  PO_FSR0:
189       return  "PO_FSR0";
190     case  PO_INDF0:
191       return  "PO_INDF0";
192     case  PO_INTCON:
193       return  "PO_INTCON";
194     case  PO_GPR_REGISTER:
195       return  "PO_GPR_REGISTER";
196     case  PO_GPR_BIT:
197       return  "PO_GPR_BIT";
198     case  PO_GPR_TEMP:
199       return  "PO_GPR_TEMP";
200     case  PO_SFR_REGISTER:
201       return  "PO_SFR_REGISTER";
202     case  PO_PCL:
203       return  "PO_PCL";
204     case  PO_PCLATH:
205       return  "PO_PCLATH";
206     case  PO_PCLATU:
207       return  "PO_PCLATU";
208     case  PO_PRODL:
209       return  "PO_PRODL";
210     case  PO_PRODH:
211       return  "PO_PRODH";
212     case PO_LITERAL:
213       return  "PO_LITERAL";
214     case PO_REL_ADDR:
215       return "PO_REL_ADDR";
216     case  PO_IMMEDIATE:
217       return  "PO_IMMEDIATE";
218     case  PO_DIR:
219       return  "PO_DIR";
220     case  PO_CRY:
221       return  "PO_CRY";
222     case  PO_BIT:
223       return  "PO_BIT";
224     case  PO_STR:
225       return  "PO_STR";
226     case  PO_LABEL:
227       return  "PO_LABEL";
228     case  PO_WILD:
229       return  "PO_WILD";
230     }
231   }
232
233   return "BAD PO_TYPE";
234 }
235
236 /*-----------------------------------------------------------------*/
237 /* pic16_genPlusIncr :- does addition with increment if possible         */
238 /*-----------------------------------------------------------------*/
239 bool pic16_genPlusIncr (iCode *ic)
240 {
241     unsigned int icount ;
242     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
243
244     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
245     DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
246                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
247                          pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
248                          pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
249
250     /* will try to generate an increment */
251     /* if the right side is not a literal 
252        we cannot */
253     if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
254         return FALSE ;
255     
256     DEBUGpic16_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
257     /* if the literal value of the right hand side
258        is greater than 2 then it is faster to add */
259     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
260         return FALSE ;
261     
262     /* if increment 16 bits in register */
263     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
264         (icount == 1)) {
265
266       int offset = MSB16;
267
268       pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
269       //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
270
271       while(--size) {
272         emitSKPNZ;
273         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
274         //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
275       }
276
277       return TRUE;
278     }
279     
280     DEBUGpic16_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
281     /* if left is in accumulator  - probably a bit operation*/                          // VR - why this is a bit operation?!
282     if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
283         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
284       
285       pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
286       pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
287                AOP(IC_RESULT(ic))->aopu.aop_dir,
288                AOP(IC_RESULT(ic))->aopu.aop_dir);
289       if(icount)
290         pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
291       //pic16_emitcode("xorlw","1");
292       else
293         pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
294       //pic16_emitcode("andlw","1");
295
296       emitSKPZ;
297       pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
298       pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
299                AOP(IC_RESULT(ic))->aopu.aop_dir,
300                AOP(IC_RESULT(ic))->aopu.aop_dir);
301
302       return TRUE;
303     }
304
305
306     /* if the sizes are greater than 1 then we cannot */
307     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
308         AOP_SIZE(IC_LEFT(ic)) > 1   )
309         return FALSE ;
310     
311     /* If we are incrementing the same register by two: */
312
313     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
314         
315       while (icount--) 
316         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
317       //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
318         
319       return TRUE ;
320     }
321     
322     DEBUGpic16_emitcode ("; ","couldn't increment ");
323
324     return FALSE ;
325 }
326
327 /*-----------------------------------------------------------------*/
328 /* pic16_outBitAcc - output a bit in acc                                 */
329 /*-----------------------------------------------------------------*/
330 void pic16_outBitAcc(operand *result)
331 {
332     symbol *tlbl = newiTempLabel(NULL);
333     /* if the result is a bit */
334     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
335
336     if (AOP_TYPE(result) == AOP_CRY){
337         pic16_aopPut(AOP(result),"a",0);
338     }
339     else {
340         pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
341         pic16_emitcode("mov","a,#01");
342         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
343         pic16_outAcc(result);
344     }
345 }
346
347 /*-----------------------------------------------------------------*/
348 /* pic16_genPlusBits - generates code for addition of two bits           */
349 /*-----------------------------------------------------------------*/
350 void pic16_genPlusBits (iCode *ic)
351 {
352
353   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
354
355   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
356                        pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
357                        pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
358                        pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
359   /*
360     The following block of code will add two bits. 
361     Note that it'll even work if the destination is
362     the carry (C in the status register).
363     It won't work if the 'Z' bit is a source or destination.
364   */
365
366   /* If the result is stored in the accumulator (w) */
367   //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
368   switch(AOP_TYPE(IC_RESULT(ic))) {
369   case AOP_ACC:
370     pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
371     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
372     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
373     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
374     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
375
376     pic16_emitcode("clrw","");
377     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
378                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
379                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
380     pic16_emitcode("xorlw","1");
381     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
382                    AOP(IC_LEFT(ic))->aopu.aop_dir,
383                    AOP(IC_LEFT(ic))->aopu.aop_dir);
384     pic16_emitcode("xorlw","1");
385     break;
386   case AOP_REG:
387     pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
388     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
389     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
390     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
391     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
392     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
393     break;
394   default:
395     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
396     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
397     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
398     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
399     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
400     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
401
402     pic16_emitcode("movlw","(1 << (%s & 7))",
403                    AOP(IC_RESULT(ic))->aopu.aop_dir,
404                    AOP(IC_RESULT(ic))->aopu.aop_dir);
405     pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
406                    AOP(IC_RESULT(ic))->aopu.aop_dir,
407                    AOP(IC_RESULT(ic))->aopu.aop_dir);
408     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
409                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
410                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
411     pic16_emitcode("xorwf","(%s >>3),f",
412                    AOP(IC_RESULT(ic))->aopu.aop_dir);
413     pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
414                    AOP(IC_LEFT(ic))->aopu.aop_dir,
415                    AOP(IC_LEFT(ic))->aopu.aop_dir);
416     pic16_emitcode("xorwf","(%s>>3),f",
417                    AOP(IC_RESULT(ic))->aopu.aop_dir);
418     break;
419   }
420
421 }
422
423 #if 0
424 /* This is the original version of this code.
425  *
426  * This is being kept around for reference, 
427  * because I am not entirely sure I got it right...
428  */
429 static void adjustArithmeticResult(iCode *ic)
430 {
431     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
432         AOP_SIZE(IC_LEFT(ic)) == 3   &&
433         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
434         pic16_aopPut(AOP(IC_RESULT(ic)),
435                pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
436                2);
437
438     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
439         AOP_SIZE(IC_RIGHT(ic)) == 3   &&
440         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
441         pic16_aopPut(AOP(IC_RESULT(ic)),
442                pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
443                2);
444     
445     if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
446         AOP_SIZE(IC_LEFT(ic)) < 3    &&
447         AOP_SIZE(IC_RIGHT(ic)) < 3   &&
448         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
449         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
450         char buffer[5];
451         sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
452         pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
453     }
454 }
455 //#else
456 /* This is the pure and virtuous version of this code.
457  * I'm pretty certain it's right, but not enough to toss the old 
458  * code just yet...
459  */
460 static void adjustArithmeticResult(iCode *ic)
461 {
462     if (opIsGptr(IC_RESULT(ic)) &&
463         opIsGptr(IC_LEFT(ic))   &&
464         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
465     {
466         pic16_aopPut(AOP(IC_RESULT(ic)),
467                pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
468                GPTRSIZE - 1);
469     }
470
471     if (opIsGptr(IC_RESULT(ic)) &&
472         opIsGptr(IC_RIGHT(ic))   &&
473         !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
474     {
475         pic16_aopPut(AOP(IC_RESULT(ic)),
476                pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
477                GPTRSIZE - 1);
478     }
479
480     if (opIsGptr(IC_RESULT(ic))            &&
481         AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
482         AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
483          !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
484          !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
485          char buffer[5];
486          sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
487          pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
488      }
489 }
490 #endif
491
492 /*-----------------------------------------------------------------*/
493 /* genAddlit - generates code for addition                         */
494 /*-----------------------------------------------------------------*/
495 static void genAddLit2byte (operand *result, int offr, int lit)
496 {
497
498   switch(lit & 0xff) {
499   case 0:
500     break;
501   case 1:
502     pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
503     break;
504   case 0xff:
505     pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
506     break;
507   default:
508     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
509     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
510   }
511
512 }
513
514 static void emitMOVWF(operand *reg, int offset)
515 {
516   if(!reg)
517     return;
518
519   if (AOP_TYPE(reg) == AOP_ACC) {
520     DEBUGpic16_emitcode ("; ***","%s  %d ignoring mov into W",__FUNCTION__,__LINE__);
521     return;
522   }
523
524   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
525
526 }
527
528 static void genAddLit (iCode *ic, int lit)
529 {
530
531   int size,same;
532   int lo;
533
534   operand *result;
535   operand *left;
536
537   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
538
539
540   left = IC_LEFT(ic);
541   result = IC_RESULT(ic);
542   same = pic16_sameRegs(AOP(left), AOP(result));
543   size = pic16_getDataSize(result);
544
545   if(same) {
546
547     /* Handle special cases first */
548     if(size == 1) 
549       genAddLit2byte (result, 0, lit);
550      
551     else if(size == 2) {
552       int hi = 0xff & (lit >> 8);
553       lo = lit & 0xff;
554
555       switch(hi) {
556       case 0: 
557
558         /* lit = 0x00LL */
559         DEBUGpic16_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
560         switch(lo) {
561         case 0:
562           break;
563         case 1:
564           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
565           emitSKPNZ;
566           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
567           break;
568         case 0xff:
569           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
570           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
571           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
572
573           break;
574         default:
575           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
576           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
577           emitSKPNC;
578           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
579
580
581         }
582         break;
583
584       case 1:
585         /* lit = 0x01LL */
586         DEBUGpic16_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
587         switch(lo) {
588         case 0:  /* 0x0100 */
589           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
590           break;
591         case 1:  /* 0x0101  */
592           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
593           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
594           emitSKPNZ;
595           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
596           break;
597         case 0xff: /* 0x01ff */
598           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
599           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
600           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
601           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
602         }         
603         break;
604
605       case 0xff:
606         DEBUGpic16_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
607         /* lit = 0xffLL */
608         switch(lo) {
609         case 0:  /* 0xff00 */
610           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
611           break;
612         case 1:  /*0xff01 */
613           pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
614           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
615           break;
616 /*      case 0xff: * 0xffff *
617           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
618           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
619           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
620           break;
621 */
622         default:
623           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
624           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
625           emitSKPC;
626           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
627           
628         }
629
630         break;
631         
632       default:
633         DEBUGpic16_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
634
635         /* lit = 0xHHLL */
636         switch(lo) {
637         case 0:  /* 0xHH00 */
638           genAddLit2byte (result, MSB16, hi);
639           break;
640         case 1:  /* 0xHH01 */
641           pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
642           pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
643           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
644           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
645           break;
646 /*      case 0xff: * 0xHHff *
647           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
648           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
649           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
650           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
651           break;
652 */      default:  /* 0xHHLL */
653           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
654           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
655           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
656           emitSKPNC;
657           pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
658           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
659           break;
660         }
661
662       }
663     } else {
664       int carry_info = 0;
665       int offset = 0;
666       /* size > 2 */
667       DEBUGpic16_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
668
669       while(size--) {
670         lo = BYTEofLONG(lit,0);
671
672         if(carry_info) {
673           switch(lo) {
674           case 0:
675             switch(carry_info) {
676             case 1:
677               emitSKPNZ;
678               pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
679               break;
680             case 2:
681               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
682               pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
683               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
684               break;
685             default: /* carry_info = 3  */
686               emitSKPNC;
687               pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
688               carry_info = 1;
689               break;
690             }
691             break;
692           case 0xff:
693             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
694             if(carry_info==1) 
695               emitSKPZ;
696             else
697               emitSKPC;
698             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
699             break;
700           default:
701             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
702             if(carry_info==1) 
703               emitSKPNZ;
704             else
705               emitSKPNC;
706             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
707             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
708             carry_info=2;
709             break;
710           }
711         }else {
712           /* no carry info from previous step */
713           /* this means this is the first time to add */
714           switch(lo) {
715           case 0:
716             break;
717           case 1:
718             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
719             carry_info=1;
720             break;
721           default:
722             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
723             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
724             if(lit <0x100) 
725               carry_info = 3;  /* Were adding only one byte and propogating the carry */
726             else
727               carry_info = 2;
728             break;
729           }
730         }
731         offset++;
732         lit >>= 8;
733       }
734     
735 /*
736       lo = BYTEofLONG(lit,0);
737
738       if(lit < 0x100) {
739         if(lo) {
740           if(lo == 1) {
741             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
742             emitSKPNZ;
743           } else {
744             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
745             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
746             emitSKPNC;
747           }
748           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
749           emitSKPNZ;
750           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
751           emitSKPNZ;
752           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
753
754         } 
755       } 
756     }
757
758 */
759     }
760   } else {
761     int offset = 1;
762     DEBUGpic16_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
763
764     if(size == 1) {
765
766       if(AOP_TYPE(left) == AOP_ACC) {
767         /* left addend is already in accumulator */
768         switch(lit & 0xff) {
769         case 0:
770           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
771           emitMOVWF(result,0);
772           break;
773         default:
774           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
775           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
776           emitMOVWF(result,0);
777         }
778       } else {
779         /* left addend is in a register */
780         switch(lit & 0xff) {
781         case 0:
782           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
783           emitMOVWF(result, 0);
784           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
785           emitMOVWF(result,0);
786           break;
787         case 1:
788           pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
789           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
790           emitMOVWF(result,0);
791           break;
792         case 0xff:
793           pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
794           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
795           emitMOVWF(result,0);
796           break;
797         default:
798           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
799           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
800           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
801           emitMOVWF(result,0);
802         }
803       }
804
805     } else {
806       int clear_carry=0;
807
808       /* left is not the accumulator */
809       if(lit & 0xff) {
810         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
811         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
812       } else {
813         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
814         /* We don't know the state of the carry bit at this point */
815         clear_carry = 1;
816       }
817       //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
818       emitMOVWF(result,0);
819       while(--size) {
820       
821         lit >>= 8;
822         if(lit & 0xff) {
823           if(clear_carry) {
824             /* The ls byte of the lit must've been zero - that 
825                means we don't have to deal with carry */
826
827             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
828             pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(left),offset));
829             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
830
831             clear_carry = 0;
832
833           } else {
834             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
835             //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
836             emitMOVWF(result,offset);
837             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
838             emitSKPNC;
839             pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
840             pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),offset));
841           }
842
843         } else {
844           pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
845           pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offset));
846           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
847           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
848         }
849         offset++;
850       }
851     }
852   }
853 }
854
855 /*-----------------------------------------------------------------*/
856 /* pic16_genPlus - generates code for addition                     */
857 /*-----------------------------------------------------------------*/
858 void pic16_genPlus (iCode *ic)
859 {
860         int i, size, offset = 0;
861         operand *result, *left, *right;
862
863         /* special cases :- */
864         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
865
866
867         result = IC_RESULT(ic);
868         left = IC_LEFT(ic);
869         right = IC_RIGHT(ic);
870         pic16_aopOp (left,ic,FALSE);
871         pic16_aopOp (right,ic,FALSE);
872         pic16_aopOp (result,ic,TRUE);
873         DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
874         // pic16_DumpOp("(left)",left);
875
876         /* if literal, literal on the right or
877         if left requires ACC or right is already
878         in ACC */
879
880         if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
881                 operand *t = right;
882                 right = left;
883                 left = t;
884         }
885
886         /* if both left & right are in bit space */
887         if (AOP_TYPE(left) == AOP_CRY &&
888                 AOP_TYPE(right) == AOP_CRY) {
889                 pic16_genPlusBits (ic);
890                 goto release ;
891         }
892
893         /* if left in bit space & right literal */
894         if (AOP_TYPE(left) == AOP_CRY &&
895                 AOP_TYPE(right) == AOP_LIT) {
896                 /* if result in bit space */
897                 if(AOP_TYPE(result) == AOP_CRY){
898                         if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
899                                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
900                                 if (!pic16_sameRegs(AOP(left), AOP(result)) )
901                                         pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
902                                 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
903                         }
904                 } else {
905                         size = pic16_getDataSize(result);
906                         while (size--) {
907                                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));  
908                                 pic16_emitcode("addc","a,#00  ;%d",__LINE__);
909                                 pic16_aopPut(AOP(result),"a",offset++);
910                         }
911                 }
912         goto release ;
913         } // left == CRY
914
915         /* if I can do an increment instead
916         of add then GOOD for ME */
917         if (pic16_genPlusIncr (ic) == TRUE)
918                 goto release;   
919
920         size = pic16_getDataSize(IC_RESULT(ic));
921
922         if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
923                 /* Add a literal to something else */
924                 //bool know_W=0;
925                 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
926                 //unsigned l1=0;
927
928                 //offset = 0;
929                 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
930
931                 genAddLit (ic,  lit);
932                 goto release;
933
934         } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
935
936                 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
937                 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
938                 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
939
940                 /* here we are adding a bit to a char or int */
941                 if(size == 1) {
942                         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
943
944                                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
945                                 pic16_emitpcode(POC_INCF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
946
947                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
948                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir,
949                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir);
950                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
951                         } else { // not same
952
953                                 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
954                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
955                                         pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
956
957                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
958                                         AOP(IC_RIGHT(ic))->aopu.aop_dir,
959                                         AOP(IC_RIGHT(ic))->aopu.aop_dir);
960                                         pic16_emitcode(" xorlw","1");
961                                 } else {
962                                         pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
963                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
964                                         pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
965
966                                         pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
967                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
968                                         AOP(IC_RIGHT(ic))->aopu.aop_dir,
969                                         AOP(IC_RIGHT(ic))->aopu.aop_dir);
970                                         pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
971                                 }
972           
973                                 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
974             
975                                         if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
976                                                 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
977                                                 pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
978                                                 emitSKPZ;
979                                                 pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
980                                         } else {
981                                                 pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
982                                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
983                                         }
984                                 }
985                         }
986
987                 } else {
988                         int offset = 1;
989                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
990                         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
991                                 emitCLRZ;
992                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
993                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
994
995                                 pic16_emitcode("clrz","");
996
997                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
998                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir,
999                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1000                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1001
1002                         } else {
1003
1004                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1005                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1006                                 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1007                                 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1008                                 emitMOVWF(IC_RIGHT(ic),0);
1009
1010                                 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1011                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1012                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1013                                                 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1014                                 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1015                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1016
1017                         }
1018
1019                         while(--size){
1020                                 emitSKPZ;
1021                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset++));
1022                                 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
1023                         }
1024
1025                 }
1026       
1027         } else {
1028                 // add bytes
1029
1030                 // Note: the following is an example of WISC code, eg.
1031                 // it's supposed to run on a Weird Instruction Set Computer :o)
1032
1033                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1034
1035                 if ( AOP_TYPE(left) == AOP_ACC) {
1036                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1037                         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1038                         if ( AOP_TYPE(result) != AOP_ACC)
1039                                 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1040                         goto release; // we're done, since WREG is 1 byte
1041                 }
1042
1043
1044                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1045
1046                 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1047                 size = min( size, AOP_SIZE(left) );
1048                 offset = 0;
1049
1050                 if(pic16_debug_verbose) {
1051 //                      fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1052 //                              AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1053 //                      fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1054                 }
1055
1056
1057
1058                 if ((AOP_TYPE(left) == AOP_PCODE) && (
1059                                 (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
1060 //                              (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
1061                                 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1062                 {
1063                         // add to literal operand
1064
1065                         // add first bytes
1066                         for(i=0; i<size; i++) {
1067                                 if (AOP_TYPE(right) == AOP_ACC) {
1068                                         pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1069                                 } else {
1070                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1071                                         if(i) { // add with carry
1072                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1073                                         } else { // add without
1074                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1075                                         }
1076                                 }
1077                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1078                         }
1079
1080                         // add leftover bytes
1081                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1082                                 // right is unsigned
1083                                 for(i=size; i< AOP_SIZE(result); i++) {
1084                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1085                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1086                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1087                                 }
1088
1089                         } else {
1090                                 // right is signed, oh dear ...
1091                                 for(i=size; i< AOP_SIZE(result); i++) {
1092                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1093                                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1094                                         pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1095                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1096                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1097                                 }
1098
1099                         }
1100                         goto release;
1101
1102                 } else {
1103                         // add regs
1104
1105                         // add first bytes
1106                         for(i=0; i<size; i++) {
1107                                 if (AOP_TYPE(right) != AOP_ACC)
1108                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1109                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1110                                 {
1111                                         if(i) { // add with carry
1112                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1113                                         } else { // add without
1114                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1115                                         }
1116                                 } else { // not same
1117                                         if(i) { // add with carry
1118                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1119                                         } else { // add without
1120                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1121                                         }
1122                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1123                                 }
1124                         }
1125
1126                         // add leftover bytes
1127                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1128                                 // right is unsigned
1129                                 for(i=size; i< AOP_SIZE(result); i++) {
1130                                         if (pic16_sameRegs(AOP(left), AOP(result)))
1131                                         {
1132                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1133                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1134                                         } else { // not same
1135                                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1136                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1137                                         }
1138                                 }
1139                         } else {
1140                                 // right is signed
1141                                 for(i=size; i< AOP_SIZE(result); i++) {
1142                                         if(size < AOP_SIZE(left)) {
1143                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1144                                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1145                                                 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1146                                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1147                                                 {
1148                                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1149                                                 } else { // not same
1150                                                         pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1151                                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1152                                                 }
1153                                         } else {
1154                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1155                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1156                                         }
1157                                 }
1158                         }
1159                         goto release;
1160                 }
1161
1162         }
1163
1164         // TODO:        anything from here to before "release:" is probably obsolete and should be removed
1165         //              when the regression tests are stable
1166
1167         if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1168                 int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1169                                 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1170
1171
1172                 /* Need to extend result to higher bytes */
1173                 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1174
1175                 /* First grab the carry from the lower bytes */
1176                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1177                 pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1178
1179
1180                 if(sign) {
1181                         /* Now this is really horrid. Gotta check the sign of the addends and propogate
1182                         * to the result */
1183
1184                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1185                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1186                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1187                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1188
1189                         /* if chars or ints or being signed extended to longs: */
1190                         if(size) {
1191                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1192                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1193                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1194                         }
1195                 }
1196
1197                 offset++;
1198                 while(size--) {
1199       
1200                         if(sign)
1201                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1202                         else
1203                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1204
1205                         offset++;
1206                 }
1207         }
1208
1209
1210         //adjustArithmeticResult(ic);
1211
1212         release:
1213         pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1214         pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1215         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1216 }
1217
1218 /*-----------------------------------------------------------------*/
1219 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1220 /*-----------------------------------------------------------------*/
1221 bool pic16_genMinusDec (iCode *ic)
1222 {
1223     unsigned int icount ;
1224     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1225
1226     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1227     /* will try to generate an increment */
1228     /* if the right side is not a literal 
1229     we cannot */
1230     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1231         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1232         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1233         return FALSE ;
1234
1235     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1236
1237     /* if the literal value of the right hand side
1238     is greater than 4 then it is not worth it */
1239     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1240         return FALSE ;
1241
1242     /* if decrement 16 bits in register */
1243     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1244         (size > 1) &&
1245         (icount == 1)) {
1246
1247       if(size == 2) { 
1248         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1249         pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1250         pic16_emitpcode(POC_INCF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1251         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1252
1253         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1254         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1255         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1256       } else {
1257         /* size is 3 or 4 */
1258         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1259         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1260         emitSKPNC;
1261         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1262         emitSKPNC;
1263         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1264
1265         pic16_emitcode("movlw","0xff");
1266         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1267
1268         emitSKPNC;
1269         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1270         emitSKPNC;
1271         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1272
1273         if(size > 3) {
1274           emitSKPNC;
1275           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1276
1277           pic16_emitcode("skpnc","");
1278           emitSKPNC;
1279           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1280         }
1281
1282       }
1283
1284       return TRUE;
1285
1286     }
1287
1288     /* if the sizes are greater than 1 then we cannot */
1289     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1290         AOP_SIZE(IC_LEFT(ic)) > 1   )
1291         return FALSE ;
1292
1293     /* we can if the aops of the left & result match or
1294     if they are in registers and the registers are the
1295     same */
1296     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1297
1298       while (icount--) 
1299         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1300
1301         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1302
1303         return TRUE ;
1304     }
1305
1306     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1307                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1308                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1309     if(size==1) {
1310
1311       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1312       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1313
1314       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1315       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1316
1317       return TRUE;
1318     }
1319
1320     return FALSE ;
1321 }
1322
1323 /*-----------------------------------------------------------------*/
1324 /* pic16_addSign - propogate sign bit to higher bytes                    */
1325 /*-----------------------------------------------------------------*/
1326 void pic16_addSign(operand *result, int offset, int sign)
1327 {
1328   int size = (pic16_getDataSize(result) - offset);
1329   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1330
1331   if(size > 0){
1332     if(sign && offset) {
1333
1334       if(size == 1) {
1335         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1336         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1337         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1338       } else {
1339
1340         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1341         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1342         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1343         while(size--)
1344           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1345
1346       }
1347     } else
1348       while(size--)
1349         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1350   }
1351 }
1352
1353 /*-----------------------------------------------------------------*/
1354 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1355 /*-----------------------------------------------------------------*/
1356 void pic16_genMinusBits (iCode *ic)
1357 {
1358     symbol *lbl = newiTempLabel(NULL);
1359     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1360     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1361         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1362         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1363         pic16_emitcode("cpl","c");
1364         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1365         pic16_outBitC(IC_RESULT(ic));
1366     }
1367     else{
1368         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1369         pic16_emitcode("subb","a,acc");
1370         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1371         pic16_emitcode("inc","a");
1372         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1373         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1374         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1375     }
1376 }
1377
1378 /*-----------------------------------------------------------------*/
1379 /* pic16_genMinus - generates code for subtraction                       */
1380 /*-----------------------------------------------------------------*/
1381 void pic16_genMinus (iCode *ic)
1382 {
1383   int size, offset = 0, same=0;
1384   unsigned long lit = 0L;
1385
1386   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1387   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1388   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1389   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1390
1391   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1392       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1393     operand *t = IC_RIGHT(ic);
1394     IC_RIGHT(ic) = IC_LEFT(ic);
1395     IC_LEFT(ic) = t;
1396   }
1397
1398   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1399                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1400                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1401                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1402
1403   /* special cases :- */
1404   /* if both left & right are in bit space */
1405   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1406       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1407     pic16_genPlusBits (ic);
1408     goto release ;
1409   }
1410
1411   /* if I can do an decrement instead
1412      of subtract then GOOD for ME */
1413 //  if (pic16_genMinusDec (ic) == TRUE)
1414 //    goto release;   
1415
1416   size = pic16_getDataSize(IC_RESULT(ic));   
1417   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1418
1419   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1420     /* Add a literal to something else */
1421
1422     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1423     lit = - (long)lit;
1424
1425     genAddLit ( ic,  lit);
1426     
1427 #if 0
1428     /* add the first byte: */
1429     pic16_emitcode("movlw","0x%x", lit & 0xff);
1430     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1431     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1432     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1433
1434
1435     offset = 1;
1436     size--;
1437
1438     while(size-- > 0) {
1439
1440       lit >>= 8;
1441
1442       if(lit & 0xff) {
1443
1444         if((lit & 0xff) == 0xff) {
1445           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1446           emitSKPC;
1447           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1448         } else {
1449           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1450           emitSKPNC;
1451           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1452           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1453         }
1454
1455       } else {
1456         /* do the rlf known zero trick here */
1457         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1458         emitSKPNC;
1459         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1460       }
1461       offset++;
1462     }
1463 #endif
1464   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1465     // bit subtraction
1466
1467     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1468     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1469     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1470
1471     /* here we are subtracting a bit from a char or int */
1472     if(size == 1) {
1473       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1474
1475         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1476         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1477
1478         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1479                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1480                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1481         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1482       } else {
1483
1484         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1485           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1486           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1487         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1488               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1489
1490           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1491
1492           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1493             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1494               if(lit & 1) {
1495                 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1496                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1497               }
1498             }else{
1499               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1500               if(lit & 1) 
1501                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1502               else
1503                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1504               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1505             }
1506             goto release;
1507           } else {
1508             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1509             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1510             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1511             pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1512
1513           }
1514
1515         } else {
1516           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1517           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1518           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1519         }
1520           
1521         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1522             
1523           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1524
1525         } else  {
1526           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1527 /*
1528           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1529           emitSKPZ;
1530           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1531 */
1532         }
1533
1534       }
1535
1536     }
1537   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1538               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1539               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1540
1541     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1542     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1543                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1544                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1545                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1546
1547
1548     if( (size == 1) && ((lit & 0xff) == 0) ) {
1549       /* res = 0 - right */
1550       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1551         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1552         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1553       } else { 
1554         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1555         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1556         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1557       }
1558       goto release;
1559     }
1560
1561     pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1562     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1563     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1564
1565
1566     offset = 1;
1567     while(--size) {
1568       lit >>= 8;
1569
1570       if(size == 1) {
1571         /* This is the last byte in a multibyte subtraction 
1572          * There are a couple of tricks we can do by not worrying about 
1573          * propogating the carry */
1574         if(lit == 0xff) {
1575           /* 0xff - x == ~x */
1576           if(same) {
1577             pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1578             emitSKPC;
1579             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1580           } else {
1581             pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1582             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1583             emitSKPC;
1584             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1585           }
1586         } else {
1587             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1588             emitSKPC;
1589             pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1590             pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1591             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1592         }
1593
1594         goto release;
1595       }
1596
1597       if(same) {
1598
1599         if(lit & 0xff) {
1600           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1601           emitSKPC;
1602           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1603           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1604         } else {
1605           emitSKPNC;
1606           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1607
1608         }
1609       } else {
1610
1611         if(lit & 0xff) {
1612           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1613           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1614         } else
1615           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1616
1617         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1618         emitSKPC;
1619         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1620         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1621       }
1622     }
1623   
1624
1625   } else {
1626
1627     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1628                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1629                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1630                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1631
1632     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1633       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1634       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1635       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1636       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1637     } else {
1638
1639       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1640         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1641         pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1642         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1643           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1644       } else {
1645
1646         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1647         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1648           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1649
1650         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1651           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1652         else {
1653           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1654               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1655             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1656           } else {
1657             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1658           }
1659           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1660             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1661               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1662               emitSKPZ;
1663               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1664             }else
1665               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1666           }
1667         }
1668       }
1669     }
1670
1671     /*
1672       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1673
1674       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1675       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1676       } else {
1677       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1678       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1679       }
1680     */
1681     offset = 1;
1682     size--;
1683
1684     while(size--){
1685       if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1686         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1687         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1688       }
1689       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1690       emitSKPC;
1691       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1692       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1693
1694       offset++;
1695     }
1696
1697   }
1698
1699
1700   //    adjustArithmeticResult(ic);
1701         
1702  release:
1703   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1704   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1705   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1706 }
1707
1708
1709 /*-----------------------------------------------------------------*
1710  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1711  * 
1712  * 
1713  *-----------------------------------------------------------------*/
1714 void pic16_genUMult8XLit_8 (operand *left,
1715                              operand *right,
1716                              operand *result)
1717 {
1718   unsigned int lit;
1719   int same;
1720
1721
1722         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1723
1724         if (AOP_TYPE(right) != AOP_LIT){
1725                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1726                 exit(1);
1727         }
1728
1729         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1730         lit &= 0xff;
1731         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1732         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1733         
1734         same = pic16_sameRegs(AOP(left), AOP(result));
1735         if(same) {
1736                 switch(lit) {
1737                         case 0:
1738                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1739                                 return;
1740                         case 2:
1741                                 // its faster to left shift
1742                                 emitCLRC;
1743                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1744                                 return;
1745
1746                         default:
1747                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1748                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1749                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1750                                         pic16_popGet(AOP(result), 0)));
1751                                 return;
1752                 }
1753         } else {
1754                 // operands different
1755                 switch(lit) {
1756                         case 0:
1757                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1758                                 return;
1759                         case 2:
1760                                 emitCLRC;
1761                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1762                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1763                                 return;
1764                         default:
1765                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1766                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1767                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1768                                         pic16_popGet(AOP(result), 0)));
1769                                 return;
1770                 }
1771         }
1772 }
1773
1774 /*-----------------------------------------------------------------------*
1775  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1776  *-----------------------------------------------------------------------*/
1777 void pic16_genUMult16XLit_16 (operand *left,
1778                              operand *right,
1779                              operand *result)
1780 {
1781   pCodeOp *pct1, *pct2, *pct3, *pct4;
1782   unsigned int lit;
1783   int same;
1784
1785
1786         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1787
1788         if (AOP_TYPE(right) != AOP_LIT){
1789                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1790                 exit(1);
1791         }
1792
1793         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1794         lit &= 0xffff;
1795
1796         same = pic16_sameRegs(AOP(left), AOP(result));
1797         if(same) {
1798                 switch(lit) {
1799                         case 0:
1800                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1801                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1802                                 return;
1803                         case 2:
1804                                 // its faster to left shift
1805                                 emitCLRC;
1806                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1807                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1808                                 return;
1809
1810                         default: {
1811                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1812
1813                                 pct1 = pic16_popGetTempReg();
1814                                 pct2 = pic16_popGetTempReg();
1815                                 pct3 = pic16_popGetTempReg();
1816                                 pct4 = pic16_popGetTempReg();
1817
1818                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1819                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1820                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1821                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1822                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1823                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1824                                         
1825                                 /* WREG still holds the low literal */
1826                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1827                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1828                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1829                                         
1830                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1831                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1832                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1833                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1834                                         
1835                                 /* load result */
1836                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1837                                         pct1, pic16_popGet(AOP(result), 0)));
1838                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1839                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1840                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1841                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1842
1843                                 pic16_popReleaseTempReg( pct4 );
1844                                 pic16_popReleaseTempReg( pct3 );
1845                                 pic16_popReleaseTempReg( pct2 );
1846                                 pic16_popReleaseTempReg( pct1 );
1847                         }; return;
1848                 }
1849         } else {
1850                 // operands different
1851                 switch(lit) {
1852                         case 0:
1853                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1854                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1855                                 return;
1856                         case 2:
1857                                 emitCLRC;
1858                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1859                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1860                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1861                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1862                                 return;
1863                         default: {
1864                                         
1865                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1866                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1867                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1868                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1869                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1870                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1871                                         
1872                                 /* WREG still holds the low literal */
1873                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1874                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1875                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1876                                         
1877                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1878                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1879                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1880                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1881
1882                         }; return;
1883                 }
1884         }
1885 }
1886
1887
1888 /*-----------------------------------------------------------------*
1889  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1890  * 
1891  * 
1892  *-----------------------------------------------------------------*/
1893 void pic16_genUMult8X8_8 (operand *left,
1894                            operand *right,
1895                            operand *result)
1896
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                 W = A x B
1910                 W = W x B       W = B x W
1911         */
1912         /* if result == right then exchange left and right */
1913         if(pic16_sameRegs(AOP(result), AOP(right))) {
1914           operand *tmp;
1915                 tmp = left;
1916                 left = right;
1917                 right = tmp;
1918         }
1919                 
1920         if(AOP_TYPE(left) != AOP_ACC) {
1921                 // left is not WREG
1922                 if(AOP_TYPE(right) != AOP_ACC) {
1923                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1924                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1925                 } else {
1926                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1927                 }
1928         } else {
1929                 // left is WREG, right cannot be WREG (or can?!)
1930                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1931         }
1932         
1933         /* result is in PRODL:PRODH */
1934         if(AOP_TYPE(result) != AOP_ACC) {
1935                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1936                         pic16_popGet(AOP(result), 0)));
1937
1938
1939                 if(AOP_SIZE(result)>1) {
1940                   int i;
1941
1942                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1943                         pic16_popGet(AOP(result), 1)));
1944                         
1945                         for(i=2;i<AOP_SIZE(result);i++)
1946                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1947                 }
1948         } else {
1949                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1950         }
1951 }
1952
1953 /*------------------------------------------------------------------*
1954  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1955  *------------------------------------------------------------------*/
1956 void pic16_genUMult16X16_16 (operand *left,
1957                            operand *right,
1958                            operand *result)
1959
1960 {
1961   pCodeOp *pct1, *pct2, *pct3, *pct4;
1962
1963         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1964
1965
1966         if (AOP_TYPE(right) == AOP_LIT) {
1967                 pic16_genUMult8XLit_8(left,right,result);
1968           return;
1969         }
1970
1971         /* cases:
1972                 A = A x B       B = A x B
1973                 A = B x C
1974         */
1975         /* if result == right then exchange left and right */
1976         if(pic16_sameRegs(AOP(result), AOP(right))) {
1977           operand *tmp;
1978                 tmp = left;
1979                 left = right;
1980                 right = tmp;
1981         }
1982
1983
1984         if(pic16_sameRegs(AOP(result), AOP(left))) {
1985
1986                 pct1 = pic16_popGetTempReg();
1987                 pct2 = pic16_popGetTempReg();
1988                 pct3 = pic16_popGetTempReg();
1989                 pct4 = pic16_popGetTempReg();
1990
1991                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1992                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1993                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1994                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1995                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1996                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1997                                         
1998                 /* WREG still holds the lower left */
1999                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2000                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2001                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2002                 
2003                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2004                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2005                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2006                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2007                                         
2008                 /* load result */
2009                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2010                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2011                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2012                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2013                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2014                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2015
2016                 pic16_popReleaseTempReg( pct4 );
2017                 pic16_popReleaseTempReg( pct3 );
2018                 pic16_popReleaseTempReg( pct2 );
2019                 pic16_popReleaseTempReg( pct1 );
2020
2021         } else {
2022
2023                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2024                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2025                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2026                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2027                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2028                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2029
2030                 /* WREG still holds the lower left */
2031                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2032                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2033                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2034                 
2035                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2036                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2037                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2038                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2039         }       
2040 }
2041
2042
2043 void pic16_genSMult16X16_16(operand *left,
2044                         operand *right,
2045                         operand *result)
2046 {
2047
2048 }
2049
2050 #if 0
2051 /*-----------------------------------------------------------------*
2052  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2053  *
2054  *  this routine will call the unsigned multiply routine and then
2055  * post-fix the sign bit.
2056  *-----------------------------------------------------------------*/
2057 void pic16_genSMult8X8_8 (operand *left,
2058                            operand *right,
2059                            operand *result,
2060                            pCodeOpReg *result_hi)
2061 {
2062         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2063
2064
2065   if(!result_hi) {
2066     result_hi = PCOR(pic16_popGet(AOP(result),1));
2067   }
2068
2069
2070   pic16_genUMult8X8_8(left,right,result);
2071
2072   
2073 #if 0
2074   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2075   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2076   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2077   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2078   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2079 #endif
2080 }
2081 #endif
2082
2083 /*-----------------------------------------------------------------*
2084  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2085  *-----------------------------------------------------------------*/
2086 void pic16_genMult8X8_8 (operand *left,
2087                          operand *right,
2088                          operand *result)
2089 {
2090         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2091
2092         if(AOP_TYPE(right) == AOP_LIT)
2093                 pic16_genUMult8XLit_8(left,right,result);
2094         else
2095                 pic16_genUMult8X8_8(left,right,result);
2096 }
2097
2098
2099 /*-----------------------------------------------------------------*
2100  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2101  *-----------------------------------------------------------------*/
2102 void pic16_genMult16X16_16 (operand *left,
2103                          operand *right,
2104                          operand *result)
2105 {
2106         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2107
2108         if (AOP_TYPE(right) == AOP_LIT)
2109                 pic16_genUMult16XLit_16(left,right,result);
2110         else
2111                 pic16_genUMult16X16_16(left,right,result);
2112
2113 }
2114
2115
2116
2117
2118 /*-----------------------------------------------------------------------*
2119  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2120  *-----------------------------------------------------------------------*/
2121 void pic16_genUMult32XLit_32 (operand *left,
2122                              operand *right,
2123                              operand *result)
2124 {
2125   pCodeOp *pct1, *pct2, *pct3, *pct4;
2126   unsigned int lit;
2127   int same;
2128
2129
2130         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2131
2132         if (AOP_TYPE(right) != AOP_LIT){
2133                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2134                 exit(1);
2135         }
2136
2137         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2138         lit &= 0xffff;
2139
2140         same = pic16_sameRegs(AOP(left), AOP(result));
2141         if(same) {
2142                 switch(lit) {
2143                         case 0:
2144                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2145                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2146                                 return;
2147                         case 2:
2148                                 // its faster to left shift
2149                                 emitCLRC;
2150                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2151                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2152                                 return;
2153
2154                         default: {
2155                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2156
2157                                 pct1 = pic16_popGetTempReg();
2158                                 pct2 = pic16_popGetTempReg();
2159                                 pct3 = pic16_popGetTempReg();
2160                                 pct4 = pic16_popGetTempReg();
2161
2162                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2163                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2164                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2165                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2166                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2167                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2168                                         
2169                                 /* WREG still holds the low literal */
2170                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2171                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2172                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2173                                         
2174                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2175                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2176                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2177                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2178                                         
2179                                 /* load result */
2180                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2181                                         pct1, pic16_popGet(AOP(result), 0)));
2182                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2183                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2184                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2185                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2186
2187                                 pic16_popReleaseTempReg( pct4 );
2188                                 pic16_popReleaseTempReg( pct3 );
2189                                 pic16_popReleaseTempReg( pct2 );
2190                                 pic16_popReleaseTempReg( pct1 );
2191                         }; return;
2192                 }
2193         } else {
2194                 // operands different
2195                 switch(lit) {
2196                         case 0:
2197                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2198                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2199                                 return;
2200                         case 2:
2201                                 emitCLRC;
2202                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2203                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2204                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2205                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2206                                 return;
2207                         default: {
2208                                         
2209                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2210                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2211                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2212                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2213                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2214                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2215                                         
2216                                 /* WREG still holds the low literal */
2217                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2218                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2219                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2220                                         
2221                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2222                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2223                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2224                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2225
2226                         }; return;
2227                 }
2228         }
2229 }
2230
2231
2232 /*------------------------------------------------------------------*
2233  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2234  *------------------------------------------------------------------*/
2235 void pic16_genUMult32X32_32 (operand *left,
2236                            operand *right,
2237                            operand *result)
2238
2239 {
2240   pCodeOp *pct1, *pct2, *pct3, *pct4;
2241
2242         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2243
2244
2245         if (AOP_TYPE(right) == AOP_LIT) {
2246                 pic16_genUMult8XLit_8(left,right,result);
2247           return;
2248         }
2249
2250         /* cases:
2251                 A = A x B       B = A x B
2252                 A = B x C
2253         */
2254         /* if result == right then exchange left and right */
2255         if(pic16_sameRegs(AOP(result), AOP(right))) {
2256           operand *tmp;
2257                 tmp = left;
2258                 left = right;
2259                 right = tmp;
2260         }
2261
2262
2263         if(pic16_sameRegs(AOP(result), AOP(left))) {
2264
2265                 pct1 = pic16_popGetTempReg();
2266                 pct2 = pic16_popGetTempReg();
2267                 pct3 = pic16_popGetTempReg();
2268                 pct4 = pic16_popGetTempReg();
2269
2270                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2271                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2272                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2273                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2274                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2275                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2276                                         
2277                 /* WREG still holds the lower left */
2278                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2279                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2280                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2281                 
2282                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2283                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2284                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2285                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2286                                         
2287                 /* load result */
2288                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2289                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2290                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2291                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2292                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2293                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2294
2295                 pic16_popReleaseTempReg( pct4 );
2296                 pic16_popReleaseTempReg( pct3 );
2297                 pic16_popReleaseTempReg( pct2 );
2298                 pic16_popReleaseTempReg( pct1 );
2299
2300         } else {
2301
2302                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2303                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2304                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2305                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2306                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2307                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2308
2309                 /* WREG still holds the lower left */
2310                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2311                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2312                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2313                 
2314                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2315                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2316                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2317                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2318         }       
2319 }
2320
2321
2322 /*-----------------------------------------------------------------*
2323  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2324  *-----------------------------------------------------------------*/
2325 void pic16_genMult32X32_32 (operand *left,
2326                          operand *right,
2327                          operand *result)
2328 {
2329         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2330
2331         if (AOP_TYPE(right) == AOP_LIT)
2332                 pic16_genUMult32XLit_32(left,right,result);
2333         else
2334                 pic16_genUMult32X32_32(left,right,result);
2335
2336 }
2337
2338
2339
2340
2341
2342
2343
2344 #if 0
2345 /*-----------------------------------------------------------------*/
2346 /* constMult - generates code for multiplication by a constant     */
2347 /*-----------------------------------------------------------------*/
2348 void genMultConst(unsigned C)
2349 {
2350
2351   unsigned lit;
2352   unsigned sr3; // Shift right 3
2353   unsigned mask;
2354
2355   int size = 1;
2356
2357   /*
2358     Convert a string of 3 binary 1's in the lit into
2359     0111 = 1000 - 1;
2360   */
2361
2362   mask = 7 << ( (size*8) - 3);
2363   lit = C;
2364   sr3 = 0;
2365
2366   while(mask < (1<<size*8)) {
2367
2368     if( (mask & lit) == lit) {
2369       unsigned lsb;
2370
2371       /* We found 3 (or more) consecutive 1's */
2372
2373       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2374
2375       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2376
2377       lit ^= consecutive_bits;
2378
2379       mask <<= 3;
2380
2381       sr3 |= (consecutive + lsb);
2382
2383     }
2384
2385     mask >>= 1;
2386
2387   }
2388
2389 }
2390
2391 #endif