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