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