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