* src/SDCCval.c, src/SDCCval.h:
[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) ulFromVal (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(ulFromVal (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 = ulFromVal (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) ulFromVal (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                         if (pic16_sameRegs(AOP(left), AOP(result))
1340                             && (AOP_SIZE(left) < AOP_SIZE(result)))
1341                         {
1342                             // extend left operand, sign-bit still intact
1343                             pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left))));
1344                         }
1345
1346                         // add first bytes
1347                         for(i=0; i<size; i++) {
1348                                 if (AOP_TYPE(right) != AOP_ACC)
1349                                   pic16_mov2w(AOP(right),i);
1350                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1351                                 {
1352                                         if(i) { // add with carry
1353                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1354                                         } else { // add without
1355                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1356                                         }
1357                                 } else { // not same
1358                                         if(i) { // add with carry
1359                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1360                                         } else { // add without
1361                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1362                                         }
1363                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1364                                 }
1365                         }
1366
1367                         // add leftover bytes
1368                         // either left or right is too short
1369                         for (i=size; i < AOP_SIZE(result); i++) {
1370                           // get right operand into WREG
1371                           if (i < AOP_SIZE(right)) {
1372                             pic16_mov2w (AOP(right), i);
1373                           } else {
1374                             // right is too short, not overwritten with result
1375                             pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1376                             if (!SPEC_USIGN(getSpec(operandType(right)))) {
1377                               // right operand is signed
1378                               // Make sure that right's sign is not yet overwritten
1379                               assert (!pic16_sameRegs (AOP(right), AOP(result)));
1380                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1381                               pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1382                             }
1383                           }
1384
1385                           // get left+WREG+CARRY into result
1386                           if (pic16_sameRegs (AOP(left), AOP(result))) {
1387                             // left might have been extended in result above
1388                             pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1389                           } else if (i < AOP_SIZE(left)) {
1390                             pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1391                             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1392                           } else {
1393                             // left is too short, not overwritten with result
1394                             pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1395                             if (!SPEC_USIGN(getSpec(operandType(left)))) {
1396                               // left operand is signed
1397                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1398                               pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1399                             }
1400                             pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1401                           }
1402                         } // for i
1403                         goto release;
1404                 }
1405
1406         }
1407
1408         assert( 0 );
1409
1410 release:
1411         pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1412         pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1413         pic16_freeAsmop(result,NULL,ic,TRUE);
1414 }
1415
1416 /*-----------------------------------------------------------------*/
1417 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1418 /*-----------------------------------------------------------------*/
1419 bool pic16_genMinusDec (iCode *ic)
1420 {
1421     unsigned int icount ;
1422     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1423
1424     FENTRY;
1425     /* will try to generate an increment */
1426     /* if the right side is not a literal
1427     we cannot */
1428     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1429         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1430         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1431         return FALSE ;
1432
1433     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1434
1435     /* if the literal value of the right hand side
1436     is greater than 4 then it is not worth it */
1437     if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1438         return FALSE ;
1439
1440     /* if decrement 16 bits in register */
1441     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1442         (size > 1) &&
1443         (icount == 1)) {
1444
1445       if(size == 2) {
1446         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1447         emitSKPC;
1448         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1449
1450         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1451         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1452         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1453       } else {
1454         /* size is 3 or 4 */
1455         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1456         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_wreg));
1457         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1458         pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1459
1460         pic16_emitcode("movlw","0xff");
1461         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1462
1463         //emitSKPNC;
1464         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1465         //emitSKPNC;
1466         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1467
1468         if(size > 3) {
1469           pic16_emitpcode(POC_SUBWFB_D1,   pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1470
1471           pic16_emitcode("skpnc","");
1472           //emitSKPNC;
1473           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1474         }
1475
1476       }
1477
1478       return TRUE;
1479
1480     }
1481
1482     /* if the sizes are greater than 1 then we cannot */
1483     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1484         AOP_SIZE(IC_LEFT(ic)) > 1   )
1485         return FALSE ;
1486
1487     /* we can if the aops of the left & result match or
1488     if they are in registers and the registers are the
1489     same */
1490     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1491
1492       while (icount--)
1493         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1494
1495         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1496
1497         return TRUE ;
1498     }
1499
1500     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1501                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1502                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1503     if(size==1) {
1504
1505       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1506       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1507
1508       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1509       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1510
1511       return TRUE;
1512     }
1513
1514     return FALSE ;
1515 }
1516
1517 /*-----------------------------------------------------------------*/
1518 /* pic16_addSign - propogate sign bit to higher bytes                    */
1519 /*-----------------------------------------------------------------*/
1520 void pic16_addSign(operand *result, int offset, int sign)
1521 {
1522   int size = (pic16_getDataSize(result) - offset);
1523   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1524
1525   if(size > 0){
1526     if(sign && offset) {
1527
1528       if(size == 1) {
1529         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1530         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1531         pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1532       } else {
1533
1534         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1535         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1536         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1537         while(size--)
1538           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1539
1540       }
1541     } else
1542       while(size--)
1543         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1544   }
1545 }
1546
1547 /*-----------------------------------------------------------------*/
1548 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1549 /*-----------------------------------------------------------------*/
1550 void pic16_genMinusBits (iCode *ic)
1551 {
1552     symbol *lbl = newiTempLabel(NULL);
1553
1554     FENTRY;
1555     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1556         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1557         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1558         pic16_emitcode("cpl","c");
1559         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1560         pic16_outBitC(IC_RESULT(ic));
1561     }
1562     else{
1563         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1564         pic16_emitcode("subb","a,acc");
1565         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1566         pic16_emitcode("inc","a");
1567         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1568         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1569         pic16_addSign(IC_RESULT(ic), MSB16, !IS_UNSIGNED(operandType(IC_RESULT(ic))));
1570     }
1571 }
1572
1573 /*-----------------------------------------------------------------*/
1574 /* pic16_genMinus - generates code for subtraction                       */
1575 /*-----------------------------------------------------------------*/
1576 void pic16_genMinus (iCode *ic)
1577 {
1578   int size, offset = 0, same=0;
1579   unsigned long lit = 0L;
1580
1581     FENTRY;
1582   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1583   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1584   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1585
1586   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1587       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1588     operand *t = IC_RIGHT(ic);
1589     IC_RIGHT(ic) = IC_LEFT(ic);
1590     IC_LEFT(ic) = t;
1591   }
1592
1593   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1594                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1595                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1596                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1597
1598   /* special cases :- */
1599   /* if both left & right are in bit space */
1600   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1601       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1602     pic16_genPlusBits (ic);
1603     goto release ;
1604   }
1605
1606   /* if I can do an decrement instead
1607      of subtract then GOOD for ME */
1608 //  if (pic16_genMinusDec (ic) == TRUE)
1609 //    goto release;
1610
1611   size = pic16_getDataSize(IC_RESULT(ic));
1612   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1613
1614   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1615     /* Add a literal to something else */
1616
1617     lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
1618     lit = - (long)lit;
1619
1620     genAddLit ( ic,  lit);
1621   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1622     // bit subtraction
1623
1624     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1625     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1626     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1627
1628     /* here we are subtracting a bit from a char or int */
1629     if(size == 1) {
1630       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1631
1632         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1633         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1634
1635         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1636                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1637                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1638         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1639       } else {
1640
1641         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1642           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1643           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1644         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1645               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1646
1647           lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1648
1649           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1650             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1651               if(lit & 1) {
1652                 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1653                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1654               }
1655             }else{
1656               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1657               if(lit & 1)
1658                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1659               else
1660                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1661               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1662             }
1663             goto release;
1664           } else {
1665             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1666             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1667             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1668             //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1669
1670           }
1671
1672         } else {
1673           pic16_mov2w(AOP(IC_LEFT(ic)),0);
1674           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1675           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1676         }
1677
1678         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1679
1680           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1681
1682         } else  {
1683           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1684 /*
1685           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1686           emitSKPZ;
1687           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1688 */
1689         }
1690
1691       }
1692
1693     }
1694   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1695               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1696               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1697
1698     lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1699     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1700                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1701                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1702                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1703
1704
1705     if( (size == 1) && ((lit & 0xff) == 0) ) {
1706       /* res = 0 - right */
1707       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1708         pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1709       } else {
1710         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1711         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1712         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1713       }
1714       goto release;
1715     }
1716
1717     pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1718     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1719     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1720
1721
1722     offset = 0;
1723     while(--size) {
1724       lit >>= 8;
1725       offset++;
1726       if(same) {
1727         // here we have x = lit - x   for sizeof(x)>1
1728         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1729         pic16_emitpcode(POC_SUBFWB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1730       } else {
1731         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1732         pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1733         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1734       }
1735     }
1736
1737
1738   } else {
1739
1740     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1741                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1742                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1743                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1744
1745     if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1746             && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1747         // extend left in result
1748         pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))));
1749     }
1750
1751     if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1752             && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1753         // extend right in result---fails if left resides in result as well...
1754         assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
1755         pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))));
1756     }
1757
1758     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1759       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1760       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1761       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1762       if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1763         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1764     } else {
1765
1766         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1767         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1768           pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1769
1770         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1771           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1772         else {
1773           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1774               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1775             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1776           } else {
1777             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1778           }
1779           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1780             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1781               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1782               emitSKPZ;
1783               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1784             }else
1785               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1786           }
1787         }
1788     }
1789
1790     /*
1791       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1792
1793       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1794       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1795       } else {
1796       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1797       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1798       }
1799     */
1800     offset = 1;
1801     size--;
1802
1803     while (size--) {
1804       if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1805         pic16_mov2w (AOP(IC_RESULT(ic)), offset);
1806       } else if (offset < AOP_SIZE(IC_RIGHT(ic)))
1807         pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1808       else {
1809         // right operand is too short, not overwritten with result
1810         pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1811         if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1812           // signed -- sign extend the right operand
1813           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));
1814           pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1815         }
1816       }
1817       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1818         pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1819       } else if (offset < AOP_SIZE(IC_LEFT(ic))) {
1820         pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1821         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1822       } else {
1823         // left operand is too short, not overwritten with result
1824         pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1825         if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1826           // signed -- sign extend the left operand
1827           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));
1828           pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1829         }
1830         pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1831       }
1832       offset++;
1833     }
1834   }
1835
1836   //    adjustArithmeticResult(ic);
1837
1838  release:
1839   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1840   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1841   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1842 }
1843
1844
1845 /*-----------------------------------------------------------------*
1846  * pic_genMult8XLit_n - multiplication of two 8-bit numbers.
1847  *
1848  *
1849  *-----------------------------------------------------------------*/
1850 void pic16_genMult8XLit_n (operand *left,
1851     operand *right,
1852     operand *result)
1853 {
1854   int lit;
1855   int same;
1856   int size = AOP_SIZE(result);
1857   int i;
1858
1859   FENTRY;
1860   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1861
1862   if (AOP_TYPE(right) != AOP_LIT){
1863     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1864     exit(1);
1865   }
1866
1867   lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
1868   assert( (lit >= -128) && (lit < 256) );
1869   pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1870   pic16_emitpcomment("FIXME: the function does not support result==WREG");
1871
1872   same = pic16_sameRegs(AOP(left), AOP(result));
1873   if(same) {
1874     switch(lit & 0x00ff) {
1875       case 0:
1876         while (size--) {
1877           pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1878         } // while
1879         return;
1880
1881       case 2:
1882         /* sign extend left in result */
1883         pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
1884         // its faster to left shift
1885         emitCLRC;
1886         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1887         if (size > 1)
1888           pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1889         return;
1890
1891       default:
1892         if(AOP_TYPE(left) != AOP_ACC)
1893           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1894         pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
1895         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1896                 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1897         /* Adjust result's high bytes below! */
1898     }
1899   } else {
1900     // operands different
1901     switch(lit & 0x00ff) {
1902       case 0:
1903         while (size--) {
1904           pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1905         } // while
1906         return;
1907
1908       case 2:
1909         if (IS_UNSIGNED(operandType(result))) {
1910           for (i=1; i < size; i++) {
1911             pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1912           } // for
1913         } else {
1914           /* sign extend left to result */
1915           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1916           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1917           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1918           for (i=1; i < size; i++) {
1919             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),i));
1920           } // for
1921         }
1922         emitCLRC;
1923         pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1924         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1925         if (size > 1)
1926           pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1927         return;
1928
1929       default:
1930         if(AOP_TYPE(left) != AOP_ACC)
1931           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1932         pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1933         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1934                 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1935         /* Adjust result's high bytes below! */
1936     }
1937   }
1938
1939   if (size > 1) {
1940     /* We need to fix PRODH for
1941      * (a) literals < 0 and
1942      * (b) signed register operands < 0.
1943      */
1944     //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left))));
1945     if (lit < 0) {
1946       /* literal negative (i.e. in [-128..-1]), high byte == -1 */
1947       pic16_mov2w(AOP(left), 0);
1948       pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1949     }
1950
1951     if (!SPEC_USIGN(getSpec(operandType(left)))) {
1952       /* register operand signed, determine signedness of high byte */
1953       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff));
1954       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1955       pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1956     }
1957
1958     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1959             &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1960
1961     /* Need to sign-extend here. */
1962     pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
1963   } // if
1964 }
1965
1966 #if 0
1967 /*-----------------------------------------------------------------------*
1968  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1969  *-----------------------------------------------------------------------*/
1970 void pic16_genUMult16XLit_16 (operand *left,
1971                              operand *right,
1972                              operand *result)
1973 {
1974   pCodeOp *pct1, *pct2, *pct3, *pct4;
1975   unsigned int lit;
1976   int same;
1977
1978
1979     FENTRY;
1980
1981         if (AOP_TYPE(right) != AOP_LIT){
1982                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1983                 exit(1);
1984         }
1985
1986         lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
1987         lit &= 0xffff;
1988
1989         same = pic16_sameRegs(AOP(left), AOP(result));
1990         if(same) {
1991                 switch(lit) {
1992                         case 0:
1993                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1994                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1995                                 return;
1996                         case 2:
1997                                 // its faster to left shift
1998                                 emitCLRC;
1999                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2000                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2001                                 return;
2002
2003                         default: {
2004                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2005
2006                                 pct1 = pic16_popGetTempReg(1);
2007                                 pct2 = pic16_popGetTempReg(1);
2008                                 pct3 = pic16_popGetTempReg(1);
2009                                 pct4 = pic16_popGetTempReg(1);
2010
2011                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2012                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2013                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2014                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2015                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2016                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2017
2018                                 /* WREG still holds the low literal */
2019                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2020                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2021                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2022
2023                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2024                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2025                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2026                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2027
2028                                 /* load result */
2029                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2030                                         pct1, pic16_popGet(AOP(result), 0)));
2031                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2032                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2033                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2034                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2035
2036                                 pic16_popReleaseTempReg(pct4,1);
2037                                 pic16_popReleaseTempReg(pct3,1);
2038                                 pic16_popReleaseTempReg(pct2,1);
2039                                 pic16_popReleaseTempReg(pct1,1);
2040                         }; return;
2041                 }
2042         } else {
2043                 // operands different
2044                 switch(lit) {
2045                         case 0:
2046                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2047                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2048                                 return;
2049                         case 2:
2050                                 emitCLRC;
2051                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2052                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2053                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2054                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2055                                 return;
2056                         default: {
2057
2058                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2059                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2060                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2061                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2062                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2063                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2064
2065                                 /* WREG still holds the low literal */
2066                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2067                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2068                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2069
2070                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2071                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2072                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2073                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2074
2075                         }; return;
2076                 }
2077         }
2078 }
2079 #endif
2080
2081
2082 /*-----------------------------------------------------------------*
2083  * genMult8X8_n - multiplication of two 8-bit numbers.
2084  *
2085  *
2086  *-----------------------------------------------------------------*/
2087 void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
2088
2089 {
2090   FENTRY;
2091
2092
2093   if (AOP_TYPE(right) == AOP_LIT) {
2094     pic16_genMult8XLit_n(left,right,result);
2095     return;
2096   }
2097
2098   /* cases:
2099      A = A x B  B = A x B
2100      A = B x C
2101      W = A x B
2102      W = W x B  W = B x W
2103      */
2104   /* if result == right then exchange left and right */
2105   if(pic16_sameRegs(AOP(result), AOP(right))) {
2106     operand *tmp;
2107     tmp = left;
2108     left = right;
2109     right = tmp;
2110   }
2111
2112   if(AOP_TYPE(left) != AOP_ACC) {
2113     // left is not WREG
2114     if(AOP_TYPE(right) != AOP_ACC) {
2115       pic16_mov2w(AOP(left), 0);
2116       pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2117     } else {
2118       pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2119     }
2120   } else {
2121     // left is WREG, right cannot be WREG (or can?!)
2122     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2123   }
2124
2125   /* result is in PRODL:PRODH */
2126   if(AOP_TYPE(result) != AOP_ACC) {
2127     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2128             &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2129
2130
2131     if(AOP_SIZE(result)>1) {
2132
2133       /* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
2134        * (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
2135        *
2136        *    a1a0 * b1b0
2137        * --------------
2138        *      a1b0 a0b0
2139        * a1b1 a0b1
2140        * ---------------
2141        *           a0b0  a1= 0, b1= 0 (both unsigned)
2142        *       -b0 a0b0  a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0)
2143        *       -a0 a0b0  a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0)
2144        *  -(a0+b0) a0b0  a1=-1, b1=-1 (a and b signed and < 0)
2145        *
2146        *  Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
2147        *  subtract a0 and/or b0 from PRODH. */
2148       if (!IS_UNSIGNED(operandType(right))) {
2149         /* right operand (b1) signed and < 0, then subtract left op (a0) */
2150         pic16_mov2w( AOP(left), 0 );
2151         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
2152         pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2153       }
2154
2155       if (!IS_UNSIGNED(getSpec(operandType(left)))) {
2156         /* left operand (a1) signed and < 0, then subtract right op (b0) */
2157         pic16_mov2w( AOP(right), 0 );
2158         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
2159         pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2160       }
2161
2162       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2163               &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2164
2165       /* Must sign-extend here. */
2166       pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
2167     }
2168   } else {
2169     pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2170   }
2171 }
2172
2173 #if 0
2174 /*------------------------------------------------------------------*
2175  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2176  *------------------------------------------------------------------*/
2177 void pic16_genUMult16X16_16 (operand *left,
2178                            operand *right,
2179                            operand *result)
2180
2181 {
2182   pCodeOp *pct1, *pct2, *pct3, *pct4;
2183
2184     FENTRY;
2185
2186
2187         if (AOP_TYPE(right) == AOP_LIT) {
2188                 pic16_genMult8XLit_n(left,right,result);
2189           return;
2190         }
2191
2192         /* cases:
2193                 A = A x B       B = A x B
2194                 A = B x C
2195         */
2196         /* if result == right then exchange left and right */
2197         if(pic16_sameRegs(AOP(result), AOP(right))) {
2198           operand *tmp;
2199                 tmp = left;
2200                 left = right;
2201                 right = tmp;
2202         }
2203
2204
2205         if(pic16_sameRegs(AOP(result), AOP(left))) {
2206
2207                 pct1 = pic16_popGetTempReg(1);
2208                 pct2 = pic16_popGetTempReg(1);
2209                 pct3 = pic16_popGetTempReg(1);
2210                 pct4 = pic16_popGetTempReg(1);
2211
2212                 pic16_mov2w(AOP(left), 0);
2213                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2214                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2216                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2218
2219                 /* WREG still holds the lower left */
2220                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2221                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2222                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2223
2224                 pic16_mov2w(AOP(left), 1);
2225                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2226                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2227                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2228
2229                 /* load result */
2230                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2231                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2232                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2233                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2234                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2235                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2236
2237                 pic16_popReleaseTempReg( pct4, 1 );
2238                 pic16_popReleaseTempReg( pct3, 1 );
2239                 pic16_popReleaseTempReg( pct2, 1 );
2240                 pic16_popReleaseTempReg( pct1, 1 );
2241
2242         } else {
2243
2244                 pic16_mov2w(AOP(left), 0);
2245                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2246                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2247                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2248                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2249                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2250
2251                 /* WREG still holds the lower left */
2252                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2253                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2254                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2255
2256                 pic16_mov2w(AOP(left), 1);
2257                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2258                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2259                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2260         }
2261 }
2262 #endif
2263
2264 #if 0
2265 void pic16_genSMult16X16_16(operand *left,
2266                         operand *right,
2267                         operand *result)
2268 {
2269
2270 }
2271 #endif
2272
2273 #if 0
2274 /*-----------------------------------------------------------------*
2275  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2276  *
2277  *  this routine will call the unsigned multiply routine and then
2278  * post-fix the sign bit.
2279  *-----------------------------------------------------------------*/
2280 void pic16_genSMult8X8_8 (operand *left,
2281                            operand *right,
2282                            operand *result,
2283                            pCodeOpReg *result_hi)
2284 {
2285         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2286
2287
2288   if(!result_hi) {
2289     result_hi = PCOR(pic16_popGet(AOP(result),1));
2290   }
2291
2292
2293   pic16_genUMult8X8_8(left,right,result);
2294
2295
2296 #if 0
2297   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2298   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2299   pic16_mov2w(AOP(left),0);
2300   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2301   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2302 #endif
2303 }
2304 #endif
2305
2306 /*-----------------------------------------------------------------*
2307  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2308  *-----------------------------------------------------------------*/
2309 void pic16_genMult8X8_8 (operand *left,
2310                          operand *right,
2311                          operand *result)
2312 {
2313   FENTRY;
2314
2315   if(AOP_TYPE(right) == AOP_LIT)
2316     pic16_genMult8XLit_n(left,right,result);
2317   else
2318     pic16_genMult8X8_n(left,right,result);
2319 }
2320
2321
2322 #if 0
2323 /*-----------------------------------------------------------------*
2324  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2325  *-----------------------------------------------------------------*/
2326 void pic16_genMult16X16_16 (operand *left,
2327                          operand *right,
2328                          operand *result)
2329 {
2330   FENTRY;
2331
2332   if (AOP_TYPE(right) == AOP_LIT)
2333     pic16_genUMult16XLit_16(left,right,result);
2334   else
2335     pic16_genUMult16X16_16(left,right,result);
2336 }
2337 #endif
2338
2339
2340 #if 0
2341 /*-----------------------------------------------------------------------*
2342  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2343  *-----------------------------------------------------------------------*/
2344 void pic16_genUMult32XLit_32 (operand *left,
2345                              operand *right,
2346                              operand *result)
2347 {
2348   pCodeOp *pct1, *pct2, *pct3, *pct4;
2349   unsigned int lit;
2350   int same;
2351
2352
2353     FENTRY;
2354
2355         if (AOP_TYPE(right) != AOP_LIT){
2356                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2357                 exit(1);
2358         }
2359
2360         lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
2361         lit &= 0xffff;
2362
2363         same = pic16_sameRegs(AOP(left), AOP(result));
2364         if(same) {
2365                 switch(lit) {
2366                         case 0:
2367                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2368                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2369                                 return;
2370                         case 2:
2371                                 // its faster to left shift
2372                                 emitCLRC;
2373                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2374                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2375                                 return;
2376
2377                         default: {
2378                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2379
2380                                 pct1 = pic16_popGetTempReg(1);
2381                                 pct2 = pic16_popGetTempReg(1);
2382                                 pct3 = pic16_popGetTempReg(1);
2383                                 pct4 = pic16_popGetTempReg(1);
2384
2385                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2386                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2387                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2388                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2389                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2390                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2391
2392                                 /* WREG still holds the low literal */
2393                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2394                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2395                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2396
2397                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2398                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2399                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2400                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2401
2402                                 /* load result */
2403                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2404                                         pct1, pic16_popGet(AOP(result), 0)));
2405                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2406                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2407                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2408                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2409
2410                                 pic16_popReleaseTempReg( pct4, 1 );
2411                                 pic16_popReleaseTempReg( pct3, 1 );
2412                                 pic16_popReleaseTempReg( pct2, 1 );
2413                                 pic16_popReleaseTempReg( pct1, 1 );
2414                         }; return;
2415                 }
2416         } else {
2417                 // operands different
2418                 switch(lit) {
2419                         case 0:
2420                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2421                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2422                                 return;
2423                         case 2:
2424                                 emitCLRC;
2425                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2426                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2427                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2428                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2429                                 return;
2430                         default: {
2431
2432                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2433                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2434                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2435                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2436                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2437                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2438
2439                                 /* WREG still holds the low literal */
2440                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2441                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2442                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2443
2444                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2445                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2446                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2447                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2448
2449                         }; return;
2450                 }
2451         }
2452 }
2453 #endif
2454
2455 #if 0
2456 /*------------------------------------------------------------------*
2457  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2458  *------------------------------------------------------------------*/
2459 void pic16_genUMult32X32_32 (operand *left,
2460                            operand *right,
2461                            operand *result)
2462
2463 {
2464   pCodeOp *pct1, *pct2, *pct3, *pct4;
2465
2466     FENTRY;
2467
2468         if (AOP_TYPE(right) == AOP_LIT) {
2469                 pic16_genMult8XLit_n(left,right,result);
2470           return;
2471         }
2472
2473         /* cases:
2474                 A = A x B       B = A x B
2475                 A = B x C
2476         */
2477         /* if result == right then exchange left and right */
2478         if(pic16_sameRegs(AOP(result), AOP(right))) {
2479           operand *tmp;
2480                 tmp = left;
2481                 left = right;
2482                 right = tmp;
2483         }
2484
2485
2486         if(pic16_sameRegs(AOP(result), AOP(left))) {
2487
2488                 pct1 = pic16_popGetTempReg(1);
2489                 pct2 = pic16_popGetTempReg(1);
2490                 pct3 = pic16_popGetTempReg(1);
2491                 pct4 = pic16_popGetTempReg(1);
2492
2493                 pic16_mov2w(AOP(left), 0);
2494                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2495                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2496                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2497                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2498                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2499
2500                 /* WREG still holds the lower left */
2501                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2502                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2503                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2504
2505                 pic16_mov2w(AOP(left), 1);
2506                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2507                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2508                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2509
2510                 /* load result */
2511                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2512                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2513                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2514                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2515                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2516                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2517
2518                 pic16_popReleaseTempReg( pct4, 1 );
2519                 pic16_popReleaseTempReg( pct3, 1 );
2520                 pic16_popReleaseTempReg( pct2, 1 );
2521                 pic16_popReleaseTempReg( pct1, 1 );
2522
2523         } else {
2524
2525                 pic16_mov2w(AOP(left), 0);
2526                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2527                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2528                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2529                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2530                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2531
2532                 /* WREG still holds the lower left */
2533                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2534                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2535                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2536
2537                 pic16_mov2w(AOP(left), 1);
2538                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2539                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2540                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2541         }
2542 }
2543 #endif
2544
2545
2546 #if 0
2547 /*-----------------------------------------------------------------*
2548  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2549  *-----------------------------------------------------------------*/
2550 void pic16_genMult32X32_32 (operand *left,
2551                          operand *right,
2552                          operand *result)
2553 {
2554   FENTRY;
2555
2556   if (AOP_TYPE(right) == AOP_LIT)
2557     pic16_genUMult32XLit_32(left,right,result);
2558   else
2559     pic16_genUMult32X32_32(left,right,result);
2560 }
2561 #endif
2562
2563
2564
2565
2566
2567
2568
2569 #if 0
2570 /*-----------------------------------------------------------------*/
2571 /* constMult - generates code for multiplication by a constant     */
2572 /*-----------------------------------------------------------------*/
2573 void genMultConst(unsigned C)
2574 {
2575
2576   unsigned lit;
2577   unsigned sr3; // Shift right 3
2578   unsigned mask;
2579
2580   int size = 1;
2581
2582   /*
2583     Convert a string of 3 binary 1's in the lit into
2584     0111 = 1000 - 1;
2585   */
2586
2587   mask = 7 << ( (size*8) - 3);
2588   lit = C;
2589   sr3 = 0;
2590
2591   while(mask < (1<<size*8)) {
2592
2593     if( (mask & lit) == lit) {
2594       unsigned lsb;
2595
2596       /* We found 3 (or more) consecutive 1's */
2597
2598       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2599
2600       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2601
2602       lit ^= consecutive_bits;
2603
2604       mask <<= 3;
2605
2606       sr3 |= (consecutive + lsb);
2607
2608     }
2609
2610     mask >>= 1;
2611
2612   }
2613
2614 }
2615
2616 #endif