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