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