* src/pic16/gen.c (pic16_storeForReturn): fragile fix for
[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   } else {
661     int offset = 1;
662     DEBUGpic16_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
663
664     if(size == 1) {
665
666       if(AOP_TYPE(left) == AOP_ACC) {
667         /* left addend is already in accumulator */
668         switch(lit & 0xff) {
669         case 0:
670           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
671           emitMOVWF(result,0);
672           break;
673         default:
674           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
675           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
676           emitMOVWF(result,0);
677         }
678       } else {
679         /* left addend is in a register */
680         switch(lit & 0xff) {
681         case 0:
682           pic16_mov2w(AOP(left),0);
683           emitMOVWF(result, 0);
684           break;
685         case 1:
686           pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
687           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
688           emitMOVWF(result,0);
689           break;
690         case 0xff:
691           pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
692           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
693           emitMOVWF(result,0);
694           break;
695         default:
696           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
697           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
698           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
699           emitMOVWF(result,0);
700         }
701       }
702
703     } else {
704       int clear_carry=0;
705
706       /* left is not the accumulator */
707       if(lit & 0xff) {
708         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
709         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
710       } else {
711         pic16_mov2w(AOP(left),0);
712         /* We don't know the state of the carry bit at this point */
713         clear_carry = 1;
714       }
715       //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
716       emitMOVWF(result,0);
717       while(--size) {
718         lit >>= 8;
719         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
720         if (offset < AOP_SIZE(left)) {
721           pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
722           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
723         } else {
724           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
725           if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
726             /* sign-extend left (in result) */
727             pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
728             pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
729           }
730           pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
731         }
732         clear_carry = 0;
733         offset++;
734       }
735     }
736   }
737 }
738
739 #else
740     /* this fails when result is an SFR because value is written there
741      * during addition and not at the end */
742      
743 static void genAddLit (iCode *ic, int lit)
744 {
745
746   int size,sizeL,same;
747   int i, llit;
748
749   operand *result;
750   operand *left;
751   sym_link *lleft;
752
753     FENTRY;
754
755
756   left = IC_LEFT(ic);
757   lleft = operandType (left);
758   result = IC_RESULT(ic);
759   same = pic16_sameRegs(AOP(left), AOP(result));
760   size = pic16_getDataSize(result);
761   sizeL = pic16_getDataSize(left);
762   llit = lit;
763
764 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
765   /* move left to result -- possibly sign extend */
766   for (i=0; i < MIN(size, sizeL); i++) {
767     pic16_mov2f (AOP(result), AOP(left), i);
768   } // for i
769 #undef MIN
770
771   /* extend to result size */
772   if (IS_UNSIGNED(lleft)) {
773     /* zero-extend */
774     for (i = sizeL; i < size; i++) {
775       pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
776     } // for i
777   } else {
778     /* sign-extend */
779     if (size == sizeL + 1) {
780       pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
781       pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
782       pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
783     } else {
784       pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
785       pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
786       pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
787       
788       for (i=sizeL; i < size; i++) {
789         pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
790       } // for i
791     } // if
792   } // if (SIGNED)
793
794   /* special cases */
795   if (lit == 0) {
796     /* nothing to do */
797   } else if (lit == 1) {
798     switch (size) {
799     case 1:
800       /* handled below */
801       break;
802     case 2:
803       pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
804       break;
805     default:
806       assert (size > 2);
807       pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
808       for (i=1; i < size-1; i++) {
809         emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
810         pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
811       } // for i
812       emitSKPNC;
813       break;
814     } // switch
815     
816     pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
817   } else {
818     /* general case */
819
820     /* add literal to result */
821     for (i=0; i < size; i++) {
822       pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
823       llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
824       pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
825         pic16_popGet (AOP(result), i));
826     }
827   }
828
829 #if 0
830
831   if(same) {
832
833     /* Handle special cases first */
834     if(size == 1) 
835       genAddLit2byte (result, 0, lit);
836      
837     else if(size == 2) {
838       int hi = 0xff & (lit >> 8);
839       lo = lit & 0xff;
840
841       switch(hi) {
842       case 0: 
843
844         /* lit = 0x00LL */
845         DEBUGpic16_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
846         switch(lo) {
847         case 0:
848           break;
849         case 1:
850           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
851           emitSKPNZ;
852           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
853           break;
854         case 0xff:
855           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
856           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
857           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
858
859           break;
860         default:
861           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
862           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
863           emitSKPNC;
864           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
865
866
867         }
868         break;
869
870       case 1:
871         /* lit = 0x01LL */
872         DEBUGpic16_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
873         switch(lo) {
874         case 0:  /* 0x0100 */
875           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
876           break;
877         case 1:  /* 0x0101  */
878           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
879           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
880           emitSKPNZ;
881           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
882           break;
883         case 0xff: /* 0x01ff */
884           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
885           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
886           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
887           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
888           break;
889         default: /* 0x01LL */
890           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
891           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
892           emitSKPNC;
893           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
894           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
895         }         
896         break;
897
898       case 0xff:
899         DEBUGpic16_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
900         /* lit = 0xffLL */
901         switch(lo) {
902         case 0:  /* 0xff00 */
903           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
904           break;
905         case 1:  /*0xff01 */
906           pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
907           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
908           break;
909 /*      case 0xff: * 0xffff *
910           pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
911           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
912           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
913           break;
914 */
915         default:
916           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
917           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
918           emitSKPC;
919           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
920           
921         }
922
923         break;
924         
925       default:
926         DEBUGpic16_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
927
928         /* lit = 0xHHLL */
929         switch(lo) {
930         case 0:  /* 0xHH00 */
931           genAddLit2byte (result, MSB16, hi);
932           break;
933         case 1:  /* 0xHH01 */
934           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
935           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
936           pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
937           break;
938 /*      case 0xff: * 0xHHff *
939           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
940           pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
941           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
942           pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
943           break;
944 */      default:  /* 0xHHLL */
945           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
946           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
947           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
948           pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
949           break;
950         }
951
952       }
953     } else {
954       int carry_info = 0;
955       int offset = 0;
956       /* size > 2 */
957       DEBUGpic16_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
958
959       while(size--) {
960         lo = BYTEofLONG(lit,0);
961
962         if(carry_info) {
963           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
964           pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
965         }else {
966           /* no carry info from previous step */
967           /* this means this is the first time to add */
968           switch(lo) {
969           case 0:
970             break;
971           case 1:
972             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
973             carry_info=1;
974             break;
975           default:
976             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
977             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
978             if(lit <0x100) 
979               carry_info = 3;  /* Were adding only one byte and propogating the carry */
980             else
981               carry_info = 2;
982             break;
983           }
984         }
985         offset++;
986         lit >>= 8;
987       }
988     
989 /*
990       lo = BYTEofLONG(lit,0);
991
992       if(lit < 0x100) {
993         if(lo) {
994           if(lo == 1) {
995             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
996             emitSKPNZ;
997           } else {
998             pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
999             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1000             emitSKPNC;
1001           }
1002           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
1003           emitSKPNZ;
1004           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
1005           emitSKPNZ;
1006           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
1007
1008         } 
1009       } 
1010
1011 */
1012     }
1013   } else {
1014     int offset = 1;
1015     DEBUGpic16_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
1016
1017     if(size == 1) {
1018
1019       if(AOP_TYPE(left) == AOP_ACC) {
1020         /* left addend is already in accumulator */
1021         switch(lit & 0xff) {
1022         case 0:
1023           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1024           emitMOVWF(result,0);
1025           break;
1026         default:
1027           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1028           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1029           emitMOVWF(result,0);
1030         }
1031       } else {
1032         /* left addend is in a register */
1033         switch(lit & 0xff) {
1034         case 0:
1035           pic16_mov2w(AOP(left),0);
1036           emitMOVWF(result, 0);
1037           break;
1038         case 1:
1039           pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1040           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1041           emitMOVWF(result,0);
1042           break;
1043         case 0xff:
1044           pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1045           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1046           emitMOVWF(result,0);
1047           break;
1048         default:
1049           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1050           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1051           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1052           emitMOVWF(result,0);
1053         }
1054       }
1055
1056     } else {
1057       int clear_carry=0;
1058
1059       /* left is not the accumulator */
1060       if(lit & 0xff) {
1061         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1062         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1063       } else {
1064         pic16_mov2w(AOP(left),0);
1065         /* We don't know the state of the carry bit at this point */
1066         clear_carry = 1;
1067       }
1068       //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1069       emitMOVWF(result,0);
1070       while(--size) {
1071       
1072         lit >>= 8;
1073         if(lit & 0xff) {
1074           if(clear_carry) {
1075             /* The ls byte of the lit must've been zero - that 
1076                means we don't have to deal with carry */
1077
1078             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1079             pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(left),offset));
1080             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1081
1082             clear_carry = 0;
1083
1084           } else {
1085             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1086             pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1087             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1088           }
1089
1090         } else {
1091           pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
1092           pic16_mov2w(AOP(left),offset);
1093           pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1094         }
1095         offset++;
1096       }
1097     }
1098   }
1099 #endif
1100 }
1101
1102 #endif
1103
1104 /*-----------------------------------------------------------------*/
1105 /* pic16_genPlus - generates code for addition                     */
1106 /*-----------------------------------------------------------------*/
1107 void pic16_genPlus (iCode *ic)
1108 {
1109   int i, size, offset = 0;
1110   operand *result, *left, *right;
1111
1112     FENTRY;
1113     
1114     /* special cases :- */
1115         result = IC_RESULT(ic);
1116         left = IC_LEFT(ic);
1117         right = IC_RIGHT(ic);
1118         pic16_aopOp (left,ic,FALSE);
1119         pic16_aopOp (right,ic,FALSE);
1120         pic16_aopOp (result,ic,TRUE);
1121         DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1122         // pic16_DumpOp("(left)",left);
1123
1124         /* if literal, literal on the right or
1125         if left requires ACC or right is already
1126         in ACC */
1127
1128         if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1129                 operand *t = right;
1130                 right = IC_RIGHT(ic) = left;
1131                 left = IC_LEFT(ic) = t;
1132         }
1133
1134         /* if both left & right are in bit space */
1135         if (AOP_TYPE(left) == AOP_CRY &&
1136                 AOP_TYPE(right) == AOP_CRY) {
1137                 pic16_genPlusBits (ic);
1138                 goto release ;
1139         }
1140
1141         /* if left in bit space & right literal */
1142         if (AOP_TYPE(left) == AOP_CRY &&
1143                 AOP_TYPE(right) == AOP_LIT) {
1144                 /* if result in bit space */
1145                 if(AOP_TYPE(result) == AOP_CRY){
1146                         if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
1147                                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1148                                 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1149                                         pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1150                                 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1151                         }
1152                 } else {
1153                         unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
1154                         size = pic16_getDataSize(result);
1155                         while (size--) {
1156                                 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1157                                 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1158                                 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1159                                 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));  
1160                                 //pic16_emitcode("addc","a,#00  ;%d",__LINE__);
1161                                 //pic16_aopPut(AOP(result),"a",offset++);
1162                         }
1163                 }
1164         goto release ;
1165         } // left == CRY
1166
1167         /* if I can do an increment instead
1168         of add then GOOD for ME */
1169         if (pic16_genPlusIncr (ic) == TRUE)
1170                 goto release;   
1171
1172         size = pic16_getDataSize(result);
1173
1174         if(AOP(right)->type == AOP_LIT) {
1175                 /* Add a literal to something else */
1176                 //bool know_W=0;
1177                 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
1178                 //unsigned l1=0;
1179
1180                 //offset = 0;
1181                 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1182
1183                 genAddLit (ic,  lit);
1184                 goto release;
1185
1186         } else if(AOP_TYPE(right) == AOP_CRY) {
1187
1188                 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1189                 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1190                 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1191
1192                 /* here we are adding a bit to a char or int */
1193                 if(size == 1) {
1194                         if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1195
1196                                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1197                                 pic16_emitpcode(POC_INCF ,  pic16_popGet(AOP(result),0));
1198
1199                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1200                                                 AOP(right)->aopu.aop_dir,
1201                                                 AOP(right)->aopu.aop_dir);
1202                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1203                         } else { // not same
1204
1205                                 if(AOP_TYPE(left) == AOP_ACC) {
1206                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1207                                         pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1208
1209                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1210                                         AOP(right)->aopu.aop_dir,
1211                                         AOP(right)->aopu.aop_dir);
1212                                         pic16_emitcode(" xorlw","1");
1213                                 } else {
1214                                         pic16_mov2w(AOP(left),0);
1215                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1216                                         pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1217
1218                                         pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1219                                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1220                                         AOP(right)->aopu.aop_dir,
1221                                         AOP(right)->aopu.aop_dir);
1222                                         pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1223                                 }
1224           
1225                                 if(AOP_TYPE(result) != AOP_ACC) {
1226             
1227                                         if(AOP_TYPE(result) == AOP_CRY) {
1228                                                 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1229                                                 pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(result),0));
1230                                                 emitSKPZ;
1231                                                 pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(result),0));
1232                                         } else {
1233                                                 pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(result),0));
1234                                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1235                                         }
1236                                 }
1237                         }
1238
1239                 } else {
1240                         int offset = 1;
1241                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1242                         if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1243                                 emitCLRZ;
1244                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1245                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),0));
1246
1247                                 pic16_emitcode("clrz","");
1248
1249                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1250                                                 AOP(right)->aopu.aop_dir,
1251                                                 AOP(right)->aopu.aop_dir);
1252                                 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1253
1254                         } else {
1255                                 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1256                                 pic16_mov2w(AOP(left),0);
1257                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1258                                 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1259                                 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1260                                 emitMOVWF(right,0);
1261
1262                                 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1263                                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1264                                                 AOP(right)->aopu.aop_dir,
1265                                                 AOP(right)->aopu.aop_dir);
1266                                 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1267                                 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1268
1269                         }
1270
1271                         while(--size){
1272                                 emitSKPZ;
1273                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),offset++));
1274                                 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1275                         }
1276
1277                 }
1278       
1279         } else {
1280                 // add bytes
1281
1282                 // Note: the following is an example of WISC code, eg.
1283                 // it's supposed to run on a Weird Instruction Set Computer :o)
1284
1285                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1286
1287                 if ( AOP_TYPE(left) == AOP_ACC) {
1288                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1289                         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1290                         if ( AOP_TYPE(result) != AOP_ACC)
1291                                 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1292                         goto release; // we're done, since WREG is 1 byte
1293                 }
1294
1295
1296                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
1297
1298                 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1299                 size = min( size, AOP_SIZE(left) );
1300                 offset = 0;
1301
1302                 if(pic16_debug_verbose) {
1303 //                      fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1304 //                              AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1305 //                      fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1306                 }
1307
1308
1309
1310                 if ((AOP_TYPE(left) == AOP_PCODE) && (
1311                                 (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
1312 //                              (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
1313                                 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1314                 {
1315                         // add to literal operand
1316
1317                         // add first bytes
1318                         for(i=0; i<size; i++) {
1319                                 if (AOP_TYPE(right) == AOP_ACC) {
1320                                         pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1321                                 } else {
1322                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1323                                         if(i) { // add with carry
1324                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1325                                         } else { // add without
1326                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1327                                         }
1328                                 }
1329                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1330                         }
1331                         
1332                         DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1333
1334                         // add leftover bytes
1335                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1336                                 // right is unsigned
1337                                 for(i=size; i< AOP_SIZE(result); i++) {
1338                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1339                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1340                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1341                                 }
1342
1343                         } else {
1344                                 // right is signed, oh dear ...
1345                                 for(i=size; i< AOP_SIZE(result); i++) {
1346                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1347                                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1348                                         pic16_emitpcode(POC_SETF, 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                         }
1354                         goto release;
1355
1356                 } else {
1357                         // add regs
1358
1359                         // add first bytes
1360                         for(i=0; i<size; i++) {
1361                                 if (AOP_TYPE(right) != AOP_ACC)
1362                                   pic16_mov2w(AOP(right),i);
1363                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1364                                 {
1365                                         if(i) { // add with carry
1366                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1367                                         } else { // add without
1368                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1369                                         }
1370                                 } else { // not same
1371                                         if(i) { // add with carry
1372                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1373                                         } else { // add without
1374                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1375                                         }
1376                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1377                                 }
1378                         }
1379
1380                         // add leftover bytes
1381                         // either left or right is too short
1382                         for (i=size; i < AOP_SIZE(result); i++) {
1383                           // get right operand into WREG
1384                           if (i < AOP_SIZE(right)) {
1385                             pic16_mov2w (AOP(right), i);
1386                           } else {
1387                             // right is too short
1388                             pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1389                             if (!SPEC_USIGN(getSpec(operandType(right)))) {
1390                               // right operand is signed
1391                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1392                               pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1393                             }
1394                           }
1395
1396                           // get left+WREG+CARRY into result
1397                           if (i < AOP_SIZE(left)) {
1398                             if (pic16_sameRegs (AOP(left), AOP(result))) {
1399                               pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1400                             } else {
1401                               pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1402                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1403                             }
1404                           } else {
1405                             // left is too short
1406                             pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1407                             if (!SPEC_USIGN(getSpec(operandType(left)))) {
1408                               // left operand is signed
1409                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1410                               pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1411                             }
1412                             pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1413                           }
1414                         } // for i
1415                         goto release;
1416                 }
1417
1418         }
1419
1420         assert( 0 );
1421         
1422 release:
1423         pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1424         pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1425         pic16_freeAsmop(result,NULL,ic,TRUE);
1426 }
1427
1428 /*-----------------------------------------------------------------*/
1429 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1430 /*-----------------------------------------------------------------*/
1431 bool pic16_genMinusDec (iCode *ic)
1432 {
1433     unsigned int icount ;
1434     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1435
1436     FENTRY;
1437     /* will try to generate an increment */
1438     /* if the right side is not a literal 
1439     we cannot */
1440     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1441         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1442         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1443         return FALSE ;
1444
1445     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1446
1447     /* if the literal value of the right hand side
1448     is greater than 4 then it is not worth it */
1449     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1450         return FALSE ;
1451
1452     /* if decrement 16 bits in register */
1453     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1454         (size > 1) &&
1455         (icount == 1)) {
1456
1457       if(size == 2) { 
1458         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1459         emitSKPC;
1460         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1461
1462         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1463         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1464         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1465       } else {
1466         /* size is 3 or 4 */
1467         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1468         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_wreg));
1469         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1470         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1471
1472         pic16_emitcode("movlw","0xff");
1473         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1474
1475         //emitSKPNC;
1476         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1477         //emitSKPNC;
1478         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1479
1480         if(size > 3) {
1481           pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1482
1483           pic16_emitcode("skpnc","");
1484           //emitSKPNC;
1485           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1486         }
1487
1488       }
1489
1490       return TRUE;
1491
1492     }
1493
1494     /* if the sizes are greater than 1 then we cannot */
1495     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1496         AOP_SIZE(IC_LEFT(ic)) > 1   )
1497         return FALSE ;
1498
1499     /* we can if the aops of the left & result match or
1500     if they are in registers and the registers are the
1501     same */
1502     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1503
1504       while (icount--) 
1505         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1506
1507         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1508
1509         return TRUE ;
1510     }
1511
1512     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1513                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1514                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1515     if(size==1) {
1516
1517       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1518       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1519
1520       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1521       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1522
1523       return TRUE;
1524     }
1525
1526     return FALSE ;
1527 }
1528
1529 /*-----------------------------------------------------------------*/
1530 /* pic16_addSign - propogate sign bit to higher bytes                    */
1531 /*-----------------------------------------------------------------*/
1532 void pic16_addSign(operand *result, int offset, int sign)
1533 {
1534   int size = (pic16_getDataSize(result) - offset);
1535   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1536
1537   if(size > 0){
1538     if(sign && offset) {
1539
1540       if(size == 1) {
1541         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1542         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1543         pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1544       } else {
1545
1546         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1547         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1548         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1549         while(size--)
1550           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1551
1552       }
1553     } else
1554       while(size--)
1555         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1556   }
1557 }
1558
1559 /*-----------------------------------------------------------------*/
1560 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1561 /*-----------------------------------------------------------------*/
1562 void pic16_genMinusBits (iCode *ic)
1563 {
1564     symbol *lbl = newiTempLabel(NULL);
1565
1566     FENTRY;
1567     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1568         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1569         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1570         pic16_emitcode("cpl","c");
1571         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1572         pic16_outBitC(IC_RESULT(ic));
1573     }
1574     else{
1575         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1576         pic16_emitcode("subb","a,acc");
1577         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1578         pic16_emitcode("inc","a");
1579         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1580         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1581         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1582     }
1583 }
1584
1585 /*-----------------------------------------------------------------*/
1586 /* pic16_genMinus - generates code for subtraction                       */
1587 /*-----------------------------------------------------------------*/
1588 void pic16_genMinus (iCode *ic)
1589 {
1590   int size, offset = 0, same=0;
1591   unsigned long lit = 0L;
1592
1593     FENTRY;
1594   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1595   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1596   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1597
1598   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1599       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1600     operand *t = IC_RIGHT(ic);
1601     IC_RIGHT(ic) = IC_LEFT(ic);
1602     IC_LEFT(ic) = t;
1603   }
1604
1605   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1606                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1607                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1608                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1609
1610   /* special cases :- */
1611   /* if both left & right are in bit space */
1612   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1613       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1614     pic16_genPlusBits (ic);
1615     goto release ;
1616   }
1617
1618   /* if I can do an decrement instead
1619      of subtract then GOOD for ME */
1620 //  if (pic16_genMinusDec (ic) == TRUE)
1621 //    goto release;   
1622
1623   size = pic16_getDataSize(IC_RESULT(ic));   
1624   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1625
1626   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1627     /* Add a literal to something else */
1628
1629     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1630     lit = - (long)lit;
1631
1632     genAddLit ( ic,  lit);
1633     
1634 #if 0
1635     /* add the first byte: */
1636     pic16_emitcode("movlw","0x%x", lit & 0xff);
1637     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1638     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1639     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1640
1641
1642     offset = 1;
1643     size--;
1644
1645     while(size-- > 0) {
1646
1647       lit >>= 8;
1648
1649       if(lit & 0xff) {
1650
1651         if((lit & 0xff) == 0xff) {
1652           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1653           emitSKPC;
1654           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1655         } else {
1656           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1657           emitSKPNC;
1658           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1659           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1660         }
1661
1662       } else {
1663         /* do the rlf known zero trick here */
1664         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1665         emitSKPNC;
1666         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1667       }
1668       offset++;
1669     }
1670 #endif
1671   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1672     // bit subtraction
1673
1674     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1675     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1676     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1677
1678     /* here we are subtracting a bit from a char or int */
1679     if(size == 1) {
1680       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1681
1682         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1683         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1684
1685         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1686                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1687                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1688         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1689       } else {
1690
1691         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1692           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1693           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1694         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1695               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1696
1697           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1698
1699           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1700             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1701               if(lit & 1) {
1702                 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1703                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1704               }
1705             }else{
1706               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1707               if(lit & 1) 
1708                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1709               else
1710                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1711               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1712             }
1713             goto release;
1714           } else {
1715             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1716             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1717             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1718             //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1719
1720           }
1721
1722         } else {
1723           pic16_mov2w(AOP(IC_LEFT(ic)),0);
1724           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1725           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1726         }
1727           
1728         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1729             
1730           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1731
1732         } else  {
1733           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1734 /*
1735           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1736           emitSKPZ;
1737           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1738 */
1739         }
1740
1741       }
1742
1743     }
1744   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1745               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1746               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1747
1748     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1749     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1750                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1751                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1752                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1753
1754
1755     if( (size == 1) && ((lit & 0xff) == 0) ) {
1756       /* res = 0 - right */
1757       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1758         pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1759       } else { 
1760         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1761         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1762         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1763       }
1764       goto release;
1765     }
1766
1767     pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1768     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1769     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1770
1771
1772     offset = 0;
1773     while(--size) {
1774       lit >>= 8;
1775       offset++;
1776       if(same) {
1777         // here we have x = lit - x   for sizeof(x)>1
1778         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1779         pic16_emitpcode(POC_SUBFWB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1780       } else {
1781         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1782         pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1783         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1784       }
1785     }
1786   
1787
1788   } else {
1789
1790     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1791                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1792                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1793                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1794
1795     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1796       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1797       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1798       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1799       if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1800         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1801     } else {
1802
1803         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1804         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1805           pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1806
1807         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1808           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1809         else {
1810           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1811               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1812             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1813           } else {
1814             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1815           }
1816           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1817             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1818               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1819               emitSKPZ;
1820               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1821             }else
1822               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1823           }
1824         }
1825     }
1826
1827     /*
1828       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1829
1830       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1831       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1832       } else {
1833       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1834       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1835       }
1836     */
1837     offset = 1;
1838     size--;
1839
1840     while(size--){
1841       if (offset < AOP_SIZE(IC_RIGHT(ic)))
1842         pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1843       else {
1844         pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1845         if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1846           // signed -- sign extend the right operand
1847           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));
1848           pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1849         }
1850       }
1851       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1852         pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1853       } else {
1854         if (offset < AOP_SIZE(IC_LEFT(ic))) {
1855           pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1856           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1857         } else {
1858           // zero extend the left operand
1859           pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1860           if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1861             // signed -- sign extend the left operand
1862             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));
1863             pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1864           }
1865           pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1866         }
1867       } 
1868       offset++;
1869     }
1870
1871   }
1872
1873
1874   //    adjustArithmeticResult(ic);
1875         
1876  release:
1877   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1878   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1879   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1880 }
1881
1882
1883 /*-----------------------------------------------------------------*
1884  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1885  * 
1886  * 
1887  *-----------------------------------------------------------------*/
1888 void pic16_genUMult8XLit_8 (operand *left,
1889                              operand *right,
1890                              operand *result)
1891 {
1892   unsigned int lit;
1893   int same;
1894   int size = AOP_SIZE(result);
1895   int i;
1896
1897     FENTRY;
1898         DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1899
1900         if (AOP_TYPE(right) != AOP_LIT){
1901                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1902                 exit(1);
1903         }
1904
1905         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1906         lit &= 0xff;
1907         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1908         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1909         
1910         same = pic16_sameRegs(AOP(left), AOP(result));
1911         if(same) {
1912                 switch(lit) {
1913                         case 0:
1914                                 while (size--) {
1915                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1916                                 } // while
1917                                 return;
1918                         case 2:
1919                                 // its faster to left shift
1920                                 for (i=1; i < size; i++) {
1921                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1922                                 } // for
1923                                 emitCLRC;
1924                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1925                                 if (size > 1)
1926                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1927                                 return;
1928
1929                         default:
1930                                 if(AOP_TYPE(left) != AOP_ACC)
1931                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1932                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1933                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1934                                         pic16_popGet(AOP(result), 0)));
1935                                 if (size > 1) {
1936                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1937                                                                             pic16_popGet(AOP(result), 1)));
1938                                   for (i=2; i < size; i++) {
1939                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1940                                   } // for
1941                                 } // if
1942                                 return;
1943                 }
1944         } else {
1945                 // operands different
1946                 switch(lit) {
1947                         case 0:
1948                                 while (size--) {
1949                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1950                                 } // while
1951                                 return;
1952                         case 2:
1953                                 for (i=1; i < size; i++) {
1954                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1955                                 } // for
1956                                 emitCLRC;
1957                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1958                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1959                                 if (size > 1)
1960                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1961                                 return;
1962                         default:
1963                                 if(AOP_TYPE(left) != AOP_ACC)
1964                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1965                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1966                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1967                                         pic16_popGet(AOP(result), 0)));
1968
1969                                 if (size > 1) {
1970                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1971                                                                             pic16_popGet(AOP(result), 1)));
1972                                   for (i=2; i < size; i++) {
1973                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1974                                   } // for
1975                                 } // if
1976                                 return;
1977                 }
1978         }
1979 }
1980
1981 /*-----------------------------------------------------------------------*
1982  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1983  *-----------------------------------------------------------------------*/
1984 void pic16_genUMult16XLit_16 (operand *left,
1985                              operand *right,
1986                              operand *result)
1987 {
1988   pCodeOp *pct1, *pct2, *pct3, *pct4;
1989   unsigned int lit;
1990   int same;
1991
1992
1993     FENTRY;
1994     
1995         if (AOP_TYPE(right) != AOP_LIT){
1996                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1997                 exit(1);
1998         }
1999
2000         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2001         lit &= 0xffff;
2002
2003         same = pic16_sameRegs(AOP(left), AOP(result));
2004         if(same) {
2005                 switch(lit) {
2006                         case 0:
2007                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2008                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2009                                 return;
2010                         case 2:
2011                                 // its faster to left shift
2012                                 emitCLRC;
2013                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2014                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2015                                 return;
2016
2017                         default: {
2018                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2019
2020                                 pct1 = pic16_popGetTempReg(1);
2021                                 pct2 = pic16_popGetTempReg(1);
2022                                 pct3 = pic16_popGetTempReg(1);
2023                                 pct4 = pic16_popGetTempReg(1);
2024
2025                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2026                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2027                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2028                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2029                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2030                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2031                                         
2032                                 /* WREG still holds the low literal */
2033                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2034                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2035                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2036                                         
2037                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2038                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2039                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2040                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2041                                         
2042                                 /* load result */
2043                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2044                                         pct1, pic16_popGet(AOP(result), 0)));
2045                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2046                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2047                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2048                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2049
2050                                 pic16_popReleaseTempReg(pct4,1);
2051                                 pic16_popReleaseTempReg(pct3,1);
2052                                 pic16_popReleaseTempReg(pct2,1);
2053                                 pic16_popReleaseTempReg(pct1,1);
2054                         }; return;
2055                 }
2056         } else {
2057                 // operands different
2058                 switch(lit) {
2059                         case 0:
2060                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2061                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2062                                 return;
2063                         case 2:
2064                                 emitCLRC;
2065                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2066                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2067                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2068                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2069                                 return;
2070                         default: {
2071                                         
2072                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2073                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2074                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2075                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2076                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2077                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2078                                         
2079                                 /* WREG still holds the low literal */
2080                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2081                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2082                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2083                                         
2084                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2085                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2086                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2087                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2088
2089                         }; return;
2090                 }
2091         }
2092 }
2093
2094
2095 /*-----------------------------------------------------------------*
2096  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
2097  * 
2098  * 
2099  *-----------------------------------------------------------------*/
2100 void pic16_genUMult8X8_8 (operand *left,
2101                            operand *right,
2102                            operand *result)
2103
2104 {
2105   FENTRY;
2106   
2107
2108         if (AOP_TYPE(right) == AOP_LIT) {
2109                 pic16_genUMult8XLit_8(left,right,result);
2110           return;
2111         }
2112
2113         /* cases:
2114                 A = A x B       B = A x B
2115                 A = B x C
2116                 W = A x B
2117                 W = W x B       W = B x W
2118         */
2119         /* if result == right then exchange left and right */
2120         if(pic16_sameRegs(AOP(result), AOP(right))) {
2121           operand *tmp;
2122                 tmp = left;
2123                 left = right;
2124                 right = tmp;
2125         }
2126                 
2127         if(AOP_TYPE(left) != AOP_ACC) {
2128                 // left is not WREG
2129                 if(AOP_TYPE(right) != AOP_ACC) {
2130                         pic16_mov2w(AOP(left), 0);
2131                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2132                 } else {
2133                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2134                 }
2135         } else {
2136                 // left is WREG, right cannot be WREG (or can?!)
2137                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2138         }
2139         
2140         /* result is in PRODL:PRODH */
2141         if(AOP_TYPE(result) != AOP_ACC) {
2142                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
2143                         pic16_popGet(AOP(result), 0)));
2144
2145
2146                 if(AOP_SIZE(result)>1) {
2147                   int i;
2148
2149                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
2150                         pic16_popGet(AOP(result), 1)));
2151                         
2152                         for(i=2;i<AOP_SIZE(result);i++)
2153                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2154                 }
2155         } else {
2156                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2157         }
2158 }
2159
2160 /*------------------------------------------------------------------*
2161  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2162  *------------------------------------------------------------------*/
2163 void pic16_genUMult16X16_16 (operand *left,
2164                            operand *right,
2165                            operand *result)
2166
2167 {
2168   pCodeOp *pct1, *pct2, *pct3, *pct4;
2169
2170     FENTRY;
2171
2172
2173         if (AOP_TYPE(right) == AOP_LIT) {
2174                 pic16_genUMult8XLit_8(left,right,result);
2175           return;
2176         }
2177
2178         /* cases:
2179                 A = A x B       B = A x B
2180                 A = B x C
2181         */
2182         /* if result == right then exchange left and right */
2183         if(pic16_sameRegs(AOP(result), AOP(right))) {
2184           operand *tmp;
2185                 tmp = left;
2186                 left = right;
2187                 right = tmp;
2188         }
2189
2190
2191         if(pic16_sameRegs(AOP(result), AOP(left))) {
2192
2193                 pct1 = pic16_popGetTempReg(1);
2194                 pct2 = pic16_popGetTempReg(1);
2195                 pct3 = pic16_popGetTempReg(1);
2196                 pct4 = pic16_popGetTempReg(1);
2197
2198                 pic16_mov2w(AOP(left), 0);
2199                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2200                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2201                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2202                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2204                                         
2205                 /* WREG still holds the lower left */
2206                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2207                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2209                 
2210                 pic16_mov2w(AOP(left), 1);
2211                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2212                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2213                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2214                                         
2215                 /* load result */
2216                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2218                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2219                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2220                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2221                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2222
2223                 pic16_popReleaseTempReg( pct4, 1 );
2224                 pic16_popReleaseTempReg( pct3, 1 );
2225                 pic16_popReleaseTempReg( pct2, 1 );
2226                 pic16_popReleaseTempReg( pct1, 1 );
2227
2228         } else {
2229
2230                 pic16_mov2w(AOP(left), 0);
2231                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2232                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2233                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2234                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2236
2237                 /* WREG still holds the lower left */
2238                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2239                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2240                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2241                 
2242                 pic16_mov2w(AOP(left), 1);
2243                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2244                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2245                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2246         }       
2247 }
2248
2249
2250 void pic16_genSMult16X16_16(operand *left,
2251                         operand *right,
2252                         operand *result)
2253 {
2254
2255 }
2256
2257 #if 0
2258 /*-----------------------------------------------------------------*
2259  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2260  *
2261  *  this routine will call the unsigned multiply routine and then
2262  * post-fix the sign bit.
2263  *-----------------------------------------------------------------*/
2264 void pic16_genSMult8X8_8 (operand *left,
2265                            operand *right,
2266                            operand *result,
2267                            pCodeOpReg *result_hi)
2268 {
2269         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2270
2271
2272   if(!result_hi) {
2273     result_hi = PCOR(pic16_popGet(AOP(result),1));
2274   }
2275
2276
2277   pic16_genUMult8X8_8(left,right,result);
2278
2279   
2280 #if 0
2281   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2282   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2283   pic16_mov2w(AOP(left),0);
2284   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2285   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2286 #endif
2287 }
2288 #endif
2289
2290 /*-----------------------------------------------------------------*
2291  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2292  *-----------------------------------------------------------------*/
2293 void pic16_genMult8X8_8 (operand *left,
2294                          operand *right,
2295                          operand *result)
2296 {
2297   FENTRY;
2298   
2299   if(AOP_TYPE(right) == AOP_LIT)
2300     pic16_genUMult8XLit_8(left,right,result);
2301   else
2302     pic16_genUMult8X8_8(left,right,result);
2303 }
2304
2305
2306 /*-----------------------------------------------------------------*
2307  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2308  *-----------------------------------------------------------------*/
2309 void pic16_genMult16X16_16 (operand *left,
2310                          operand *right,
2311                          operand *result)
2312 {
2313   FENTRY;
2314   
2315   if (AOP_TYPE(right) == AOP_LIT)
2316     pic16_genUMult16XLit_16(left,right,result);
2317   else
2318     pic16_genUMult16X16_16(left,right,result);
2319 }
2320
2321
2322
2323
2324 /*-----------------------------------------------------------------------*
2325  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2326  *-----------------------------------------------------------------------*/
2327 void pic16_genUMult32XLit_32 (operand *left,
2328                              operand *right,
2329                              operand *result)
2330 {
2331   pCodeOp *pct1, *pct2, *pct3, *pct4;
2332   unsigned int lit;
2333   int same;
2334
2335
2336     FENTRY;
2337     
2338         if (AOP_TYPE(right) != AOP_LIT){
2339                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2340                 exit(1);
2341         }
2342
2343         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2344         lit &= 0xffff;
2345
2346         same = pic16_sameRegs(AOP(left), AOP(result));
2347         if(same) {
2348                 switch(lit) {
2349                         case 0:
2350                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2351                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2352                                 return;
2353                         case 2:
2354                                 // its faster to left shift
2355                                 emitCLRC;
2356                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2357                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2358                                 return;
2359
2360                         default: {
2361                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2362
2363                                 pct1 = pic16_popGetTempReg(1);
2364                                 pct2 = pic16_popGetTempReg(1);
2365                                 pct3 = pic16_popGetTempReg(1);
2366                                 pct4 = pic16_popGetTempReg(1);
2367
2368                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2369                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2370                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2371                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2372                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2373                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2374                                         
2375                                 /* WREG still holds the low literal */
2376                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2377                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2378                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2379                                         
2380                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2381                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2382                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2383                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2384                                         
2385                                 /* load result */
2386                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2387                                         pct1, pic16_popGet(AOP(result), 0)));
2388                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2389                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2390                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2391                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2392
2393                                 pic16_popReleaseTempReg( pct4, 1 );
2394                                 pic16_popReleaseTempReg( pct3, 1 );
2395                                 pic16_popReleaseTempReg( pct2, 1 );
2396                                 pic16_popReleaseTempReg( pct1, 1 );
2397                         }; return;
2398                 }
2399         } else {
2400                 // operands different
2401                 switch(lit) {
2402                         case 0:
2403                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2404                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2405                                 return;
2406                         case 2:
2407                                 emitCLRC;
2408                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2409                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2410                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2411                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2412                                 return;
2413                         default: {
2414                                         
2415                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2416                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2417                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2418                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2419                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2420                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2421                                         
2422                                 /* WREG still holds the low literal */
2423                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2424                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2425                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2426                                         
2427                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2428                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2429                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2430                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2431
2432                         }; return;
2433                 }
2434         }
2435 }
2436
2437
2438 /*------------------------------------------------------------------*
2439  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2440  *------------------------------------------------------------------*/
2441 void pic16_genUMult32X32_32 (operand *left,
2442                            operand *right,
2443                            operand *result)
2444
2445 {
2446   pCodeOp *pct1, *pct2, *pct3, *pct4;
2447
2448     FENTRY;
2449     
2450         if (AOP_TYPE(right) == AOP_LIT) {
2451                 pic16_genUMult8XLit_8(left,right,result);
2452           return;
2453         }
2454
2455         /* cases:
2456                 A = A x B       B = A x B
2457                 A = B x C
2458         */
2459         /* if result == right then exchange left and right */
2460         if(pic16_sameRegs(AOP(result), AOP(right))) {
2461           operand *tmp;
2462                 tmp = left;
2463                 left = right;
2464                 right = tmp;
2465         }
2466
2467
2468         if(pic16_sameRegs(AOP(result), AOP(left))) {
2469
2470                 pct1 = pic16_popGetTempReg(1);
2471                 pct2 = pic16_popGetTempReg(1);
2472                 pct3 = pic16_popGetTempReg(1);
2473                 pct4 = pic16_popGetTempReg(1);
2474
2475                 pic16_mov2w(AOP(left), 0);
2476                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2477                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2478                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2479                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2480                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2481                                         
2482                 /* WREG still holds the lower left */
2483                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2484                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2485                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2486                 
2487                 pic16_mov2w(AOP(left), 1);
2488                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2489                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2490                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2491                                         
2492                 /* load result */
2493                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2494                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2495                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2496                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2497                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2498                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2499
2500                 pic16_popReleaseTempReg( pct4, 1 );
2501                 pic16_popReleaseTempReg( pct3, 1 );
2502                 pic16_popReleaseTempReg( pct2, 1 );
2503                 pic16_popReleaseTempReg( pct1, 1 );
2504
2505         } else {
2506
2507                 pic16_mov2w(AOP(left), 0);
2508                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2509                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2510                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2511                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2512                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2513
2514                 /* WREG still holds the lower left */
2515                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2516                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2517                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2518                 
2519                 pic16_mov2w(AOP(left), 1);
2520                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2521                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2522                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2523         }       
2524 }
2525
2526
2527 /*-----------------------------------------------------------------*
2528  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2529  *-----------------------------------------------------------------*/
2530 void pic16_genMult32X32_32 (operand *left,
2531                          operand *right,
2532                          operand *result)
2533 {
2534   FENTRY;
2535   
2536   if (AOP_TYPE(right) == AOP_LIT)
2537     pic16_genUMult32XLit_32(left,right,result);
2538   else
2539     pic16_genUMult32X32_32(left,right,result);
2540 }
2541
2542
2543
2544
2545
2546
2547
2548 #if 0
2549 /*-----------------------------------------------------------------*/
2550 /* constMult - generates code for multiplication by a constant     */
2551 /*-----------------------------------------------------------------*/
2552 void genMultConst(unsigned C)
2553 {
2554
2555   unsigned lit;
2556   unsigned sr3; // Shift right 3
2557   unsigned mask;
2558
2559   int size = 1;
2560
2561   /*
2562     Convert a string of 3 binary 1's in the lit into
2563     0111 = 1000 - 1;
2564   */
2565
2566   mask = 7 << ( (size*8) - 3);
2567   lit = C;
2568   sr3 = 0;
2569
2570   while(mask < (1<<size*8)) {
2571
2572     if( (mask & lit) == lit) {
2573       unsigned lsb;
2574
2575       /* We found 3 (or more) consecutive 1's */
2576
2577       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2578
2579       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2580
2581       lit ^= consecutive_bits;
2582
2583       mask <<= 3;
2584
2585       sr3 |= (consecutive + lsb);
2586
2587     }
2588
2589     mask >>= 1;
2590
2591   }
2592
2593 }
2594
2595 #endif