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