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