Large cummulative patch for pic16 port.
[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 0");
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 - default");
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                         DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1003
1004                         // add leftover bytes
1005                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1006                                 // right is unsigned
1007                                 for(i=size; i< AOP_SIZE(result); i++) {
1008                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1009                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1010                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1011                                 }
1012
1013                         } else {
1014                                 // right is signed, oh dear ...
1015                                 for(i=size; i< AOP_SIZE(result); i++) {
1016                                         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1017                                         D_POS(">>> FIXED sign test from result to right");
1018                                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1019                                         D_POS("<<< FIXED sign test from result to right");
1020                                         pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1021                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1022                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1023                                 }
1024
1025                         }
1026                         goto release;
1027
1028                 } else {
1029                         // add regs
1030
1031                         // add first bytes
1032                         for(i=0; i<size; i++) {
1033                                 if (AOP_TYPE(right) != AOP_ACC)
1034                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1035                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1036                                 {
1037                                         if(i) { // add with carry
1038                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1039                                         } else { // add without
1040                                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1041                                         }
1042                                 } else { // not same
1043                                         if(i) { // add with carry
1044                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1045                                         } else { // add without
1046                                                 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1047                                         }
1048                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1049                                 }
1050                         }
1051
1052                         // add leftover bytes
1053                         if (SPEC_USIGN(getSpec(operandType(right)))) {
1054                                 // right is unsigned
1055                                 for(i=size; i< AOP_SIZE(result); i++) {
1056                                         if (pic16_sameRegs(AOP(left), AOP(result)))
1057                                         {
1058                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1059                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1060                                         } else { // not same
1061                                                 D_POS (">>> FIXED added to uninitialized result");
1062                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1063                                                 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1064                                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1065                                                 D_POS ("<<< FIXED");
1066                                         }
1067                                 }
1068                         } else {
1069                                 // right is signed
1070                                 for(i=size; i< AOP_SIZE(result); i++) {
1071                                         if(size < AOP_SIZE(left)) {
1072                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1073                                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1074                                                 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1075                                                 if (pic16_sameRegs(AOP(left), AOP(result)))
1076                                                 {
1077                                                         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1078                                                 } else { // not same
1079                                                         pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1080                                                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1081                                                 }
1082                                         } else {
1083                                                 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1084                                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1085                                         }
1086                                 }
1087                         }
1088                         goto release;
1089                 }
1090
1091         }
1092
1093         assert( 0 );
1094         // TODO:        anything from here to before "release:" is probably obsolete and should be removed
1095         //              when the regression tests are stable
1096
1097         if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1098                 int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1099                                 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1100
1101
1102                 /* Need to extend result to higher bytes */
1103                 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1104
1105                 /* First grab the carry from the lower bytes */
1106                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1107                 pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1108
1109
1110                 if(sign) {
1111                         /* Now this is really horrid. Gotta check the sign of the addends and propogate
1112                         * to the result */
1113
1114                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1115                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1116                         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1117                         pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1118
1119                         /* if chars or ints or being signed extended to longs: */
1120                         if(size) {
1121                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1122                                 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1123                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1124                         }
1125                 }
1126
1127                 offset++;
1128                 while(size--) {
1129       
1130                         if(sign)
1131                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1132                         else
1133                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1134
1135                         offset++;
1136                 }
1137         }
1138
1139
1140         //adjustArithmeticResult(ic);
1141
1142         release:
1143         pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1144         pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1145         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1146 }
1147
1148 /*-----------------------------------------------------------------*/
1149 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1150 /*-----------------------------------------------------------------*/
1151 bool pic16_genMinusDec (iCode *ic)
1152 {
1153     unsigned int icount ;
1154     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1155
1156     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1157     /* will try to generate an increment */
1158     /* if the right side is not a literal 
1159     we cannot */
1160     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1161         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1162         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1163         return FALSE ;
1164
1165     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1166
1167     /* if the literal value of the right hand side
1168     is greater than 4 then it is not worth it */
1169     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1170         return FALSE ;
1171
1172     /* if decrement 16 bits in register */
1173     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1174         (size > 1) &&
1175         (icount == 1)) {
1176
1177       if(size == 2) { 
1178         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1179         pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1180         pic16_emitpcode(POC_INCF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1181         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1182
1183         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1184         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1185         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1186       } else {
1187         /* size is 3 or 4 */
1188         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1189         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1190         emitSKPNC;
1191         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1192         emitSKPNC;
1193         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1194
1195         pic16_emitcode("movlw","0xff");
1196         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1197
1198         emitSKPNC;
1199         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1200         emitSKPNC;
1201         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1202
1203         if(size > 3) {
1204           emitSKPNC;
1205           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1206
1207           pic16_emitcode("skpnc","");
1208           emitSKPNC;
1209           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1210         }
1211
1212       }
1213
1214       return TRUE;
1215
1216     }
1217
1218     /* if the sizes are greater than 1 then we cannot */
1219     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1220         AOP_SIZE(IC_LEFT(ic)) > 1   )
1221         return FALSE ;
1222
1223     /* we can if the aops of the left & result match or
1224     if they are in registers and the registers are the
1225     same */
1226     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1227
1228       while (icount--) 
1229         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1230
1231         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1232
1233         return TRUE ;
1234     }
1235
1236     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1237                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1238                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1239     if(size==1) {
1240
1241       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1242       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1243
1244       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1245       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1246
1247       return TRUE;
1248     }
1249
1250     return FALSE ;
1251 }
1252
1253 /*-----------------------------------------------------------------*/
1254 /* pic16_addSign - propogate sign bit to higher bytes                    */
1255 /*-----------------------------------------------------------------*/
1256 void pic16_addSign(operand *result, int offset, int sign)
1257 {
1258   int size = (pic16_getDataSize(result) - offset);
1259   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1260
1261   if(size > 0){
1262     if(sign && offset) {
1263
1264       if(size == 1) {
1265         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1266         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1267         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1268       } else {
1269
1270         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1271         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1272         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1273         while(size--)
1274           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1275
1276       }
1277     } else
1278       while(size--)
1279         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1280   }
1281 }
1282
1283 /*-----------------------------------------------------------------*/
1284 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1285 /*-----------------------------------------------------------------*/
1286 void pic16_genMinusBits (iCode *ic)
1287 {
1288     symbol *lbl = newiTempLabel(NULL);
1289     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1290     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1291         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1292         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1293         pic16_emitcode("cpl","c");
1294         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1295         pic16_outBitC(IC_RESULT(ic));
1296     }
1297     else{
1298         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1299         pic16_emitcode("subb","a,acc");
1300         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1301         pic16_emitcode("inc","a");
1302         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1303         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1304         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1305     }
1306 }
1307
1308 /*-----------------------------------------------------------------*/
1309 /* pic16_genMinus - generates code for subtraction                       */
1310 /*-----------------------------------------------------------------*/
1311 void pic16_genMinus (iCode *ic)
1312 {
1313   int size, offset = 0, same=0;
1314   unsigned long lit = 0L;
1315
1316   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1317   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1318   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1319   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1320
1321   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1322       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1323     operand *t = IC_RIGHT(ic);
1324     IC_RIGHT(ic) = IC_LEFT(ic);
1325     IC_LEFT(ic) = t;
1326   }
1327
1328   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1329                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1330                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1331                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1332
1333   /* special cases :- */
1334   /* if both left & right are in bit space */
1335   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1336       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1337     pic16_genPlusBits (ic);
1338     goto release ;
1339   }
1340
1341   /* if I can do an decrement instead
1342      of subtract then GOOD for ME */
1343 //  if (pic16_genMinusDec (ic) == TRUE)
1344 //    goto release;   
1345
1346   size = pic16_getDataSize(IC_RESULT(ic));   
1347   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1348
1349   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1350     /* Add a literal to something else */
1351
1352     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1353     lit = - (long)lit;
1354
1355     genAddLit ( ic,  lit);
1356     
1357 #if 0
1358     /* add the first byte: */
1359     pic16_emitcode("movlw","0x%x", lit & 0xff);
1360     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1361     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1362     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1363
1364
1365     offset = 1;
1366     size--;
1367
1368     while(size-- > 0) {
1369
1370       lit >>= 8;
1371
1372       if(lit & 0xff) {
1373
1374         if((lit & 0xff) == 0xff) {
1375           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1376           emitSKPC;
1377           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1378         } else {
1379           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1380           emitSKPNC;
1381           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1382           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1383         }
1384
1385       } else {
1386         /* do the rlf known zero trick here */
1387         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1388         emitSKPNC;
1389         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1390       }
1391       offset++;
1392     }
1393 #endif
1394   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1395     // bit subtraction
1396
1397     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1398     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1399     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1400
1401     /* here we are subtracting a bit from a char or int */
1402     if(size == 1) {
1403       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1404
1405         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1406         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1407
1408         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1409                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1410                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1411         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1412       } else {
1413
1414         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1415           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1416           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1417         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1418               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1419
1420           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1421
1422           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1423             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1424               if(lit & 1) {
1425                 D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
1426                 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1427                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1428               }
1429             }else{
1430               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1431               if(lit & 1) 
1432                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1433               else
1434                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1436             }
1437             goto release;
1438           } else {
1439             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1440             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1441             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1442             D_POS(">>> IMPROVED removed following assignment W-->result");
1443             //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1444
1445           }
1446
1447         } else {
1448           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1449           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1450           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1451         }
1452           
1453         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1454             
1455           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1456
1457         } else  {
1458           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1459 /*
1460           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1461           emitSKPZ;
1462           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1463 */
1464         }
1465
1466       }
1467
1468     }
1469   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1470               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1471               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1472
1473     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1474     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1475                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1476                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1477                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1478
1479
1480     if( (size == 1) && ((lit & 0xff) == 0) ) {
1481       /* res = 0 - right */
1482       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1483         D_POS(">>> IMPROVED changed comf,incf to negf");
1484         pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1485         D_POS("<<< IMPROVED changed comf,incf to negf");
1486       } else { 
1487         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1488         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1489         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1490       }
1491       goto release;
1492     }
1493
1494     pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1495     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1496     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1497
1498
1499     offset = 0;
1500     while(--size) {
1501       lit >>= 8;
1502       offset++;
1503       D_POS(">>> FIXED and compacted");
1504       if(same) {
1505         // here we have x = lit - x   for sizeof(x)>1
1506         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1507         pic16_emitpcode(POC_SUBFWB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1508       } else {
1509         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1510         pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1511         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1512       }
1513       D_POS("<<< FIXED and compacted");
1514     }
1515   
1516
1517   } else {
1518
1519     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1520                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1521                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1522                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1523
1524     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1525       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1526       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1527       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1528       if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1529         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1530     } else {
1531
1532         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1533         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1534           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1535
1536         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1537           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1538         else {
1539           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1540               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1541             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1542           } else {
1543             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1544           }
1545           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1546             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1547               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1548               emitSKPZ;
1549               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1550             }else
1551               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1552           }
1553         }
1554     }
1555
1556     /*
1557       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1558
1559       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1560       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1561       } else {
1562       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1563       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1564       }
1565     */
1566     offset = 1;
1567     size--;
1568
1569     while(size--){
1570       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1571         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1572         D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
1573         pic16_emitpcode(POC_SUBWFB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1574         D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
1575       } else {
1576         D_POS(">>> FIXED for same regs right and result");
1577         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1578         pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1579         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1580       } 
1581       offset++;
1582     }
1583
1584   }
1585
1586
1587   //    adjustArithmeticResult(ic);
1588         
1589  release:
1590   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1591   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1592   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1593 }
1594
1595
1596 /*-----------------------------------------------------------------*
1597  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1598  * 
1599  * 
1600  *-----------------------------------------------------------------*/
1601 void pic16_genUMult8XLit_8 (operand *left,
1602                              operand *right,
1603                              operand *result)
1604 {
1605   unsigned int lit;
1606   int same;
1607
1608
1609         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1610         DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1611   
1612         if (AOP_TYPE(right) != AOP_LIT){
1613                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1614                 exit(1);
1615         }
1616
1617         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1618         lit &= 0xff;
1619         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1620         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1621         
1622         same = pic16_sameRegs(AOP(left), AOP(result));
1623         if(same) {
1624                 switch(lit) {
1625                         case 0:
1626                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1627                                 return;
1628                         case 2:
1629                                 // its faster to left shift
1630                                 emitCLRC;
1631                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1632                                 return;
1633
1634                         default:
1635                                 if(AOP_TYPE(left) != AOP_ACC)
1636                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1637                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1638                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1639                                         pic16_popGet(AOP(result), 0)));
1640                                 return;
1641                 }
1642         } else {
1643                 // operands different
1644                 switch(lit) {
1645                         case 0:
1646                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1647                                 return;
1648                         case 2:
1649                                 emitCLRC;
1650                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1651                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1652                                 return;
1653                         default:
1654                                 if(AOP_TYPE(left) != AOP_ACC)
1655                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1656                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1657                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1658                                         pic16_popGet(AOP(result), 0)));
1659                                 return;
1660                 }
1661         }
1662 }
1663
1664 /*-----------------------------------------------------------------------*
1665  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1666  *-----------------------------------------------------------------------*/
1667 void pic16_genUMult16XLit_16 (operand *left,
1668                              operand *right,
1669                              operand *result)
1670 {
1671   pCodeOp *pct1, *pct2, *pct3, *pct4;
1672   unsigned int lit;
1673   int same;
1674
1675
1676         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1677
1678         if (AOP_TYPE(right) != AOP_LIT){
1679                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1680                 exit(1);
1681         }
1682
1683         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1684         lit &= 0xffff;
1685
1686         same = pic16_sameRegs(AOP(left), AOP(result));
1687         if(same) {
1688                 switch(lit) {
1689                         case 0:
1690                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1691                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1692                                 return;
1693                         case 2:
1694                                 // its faster to left shift
1695                                 emitCLRC;
1696                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1697                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1698                                 return;
1699
1700                         default: {
1701                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1702
1703                                 pct1 = pic16_popGetTempReg(1);
1704                                 pct2 = pic16_popGetTempReg(1);
1705                                 pct3 = pic16_popGetTempReg(1);
1706                                 pct4 = pic16_popGetTempReg(1);
1707
1708                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1709                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1710                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1711                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1712                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1713                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1714                                         
1715                                 /* WREG still holds the low literal */
1716                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1717                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1718                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1719                                         
1720                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1721                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1722                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1723                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1724                                         
1725                                 /* load result */
1726                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1727                                         pct1, pic16_popGet(AOP(result), 0)));
1728                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1729                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1730                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1731                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1732
1733                                 pic16_popReleaseTempReg(pct4,1);
1734                                 pic16_popReleaseTempReg(pct3,1);
1735                                 pic16_popReleaseTempReg(pct2,1);
1736                                 pic16_popReleaseTempReg(pct1,1);
1737                         }; return;
1738                 }
1739         } else {
1740                 // operands different
1741                 switch(lit) {
1742                         case 0:
1743                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1744                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1745                                 return;
1746                         case 2:
1747                                 emitCLRC;
1748                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1749                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1750                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1751                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1752                                 return;
1753                         default: {
1754                                         
1755                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1756                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1757                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1758                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1759                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1760                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1761                                         
1762                                 /* WREG still holds the low literal */
1763                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1764                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1765                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1766                                         
1767                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1768                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1769                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1770                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1771
1772                         }; return;
1773                 }
1774         }
1775 }
1776
1777
1778 /*-----------------------------------------------------------------*
1779  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1780  * 
1781  * 
1782  *-----------------------------------------------------------------*/
1783 void pic16_genUMult8X8_8 (operand *left,
1784                            operand *right,
1785                            operand *result)
1786
1787 {
1788         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1789
1790
1791         if (AOP_TYPE(right) == AOP_LIT) {
1792                 pic16_genUMult8XLit_8(left,right,result);
1793           return;
1794         }
1795
1796         /* cases:
1797                 A = A x B       B = A x B
1798                 A = B x C
1799                 W = A x B
1800                 W = W x B       W = B x W
1801         */
1802         /* if result == right then exchange left and right */
1803         if(pic16_sameRegs(AOP(result), AOP(right))) {
1804           operand *tmp;
1805                 tmp = left;
1806                 left = right;
1807                 right = tmp;
1808         }
1809                 
1810         if(AOP_TYPE(left) != AOP_ACC) {
1811                 // left is not WREG
1812                 if(AOP_TYPE(right) != AOP_ACC) {
1813                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1814                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1815                 } else {
1816                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1817                 }
1818         } else {
1819                 // left is WREG, right cannot be WREG (or can?!)
1820                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1821         }
1822         
1823         /* result is in PRODL:PRODH */
1824         if(AOP_TYPE(result) != AOP_ACC) {
1825                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1826                         pic16_popGet(AOP(result), 0)));
1827
1828
1829                 if(AOP_SIZE(result)>1) {
1830                   int i;
1831
1832                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1833                         pic16_popGet(AOP(result), 1)));
1834                         
1835                         for(i=2;i<AOP_SIZE(result);i++)
1836                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1837                 }
1838         } else {
1839                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1840         }
1841 }
1842
1843 /*------------------------------------------------------------------*
1844  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1845  *------------------------------------------------------------------*/
1846 void pic16_genUMult16X16_16 (operand *left,
1847                            operand *right,
1848                            operand *result)
1849
1850 {
1851   pCodeOp *pct1, *pct2, *pct3, *pct4;
1852
1853         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1854
1855
1856         if (AOP_TYPE(right) == AOP_LIT) {
1857                 pic16_genUMult8XLit_8(left,right,result);
1858           return;
1859         }
1860
1861         /* cases:
1862                 A = A x B       B = A x B
1863                 A = B x C
1864         */
1865         /* if result == right then exchange left and right */
1866         if(pic16_sameRegs(AOP(result), AOP(right))) {
1867           operand *tmp;
1868                 tmp = left;
1869                 left = right;
1870                 right = tmp;
1871         }
1872
1873
1874         if(pic16_sameRegs(AOP(result), AOP(left))) {
1875
1876                 pct1 = pic16_popGetTempReg(1);
1877                 pct2 = pic16_popGetTempReg(1);
1878                 pct3 = pic16_popGetTempReg(1);
1879                 pct4 = pic16_popGetTempReg(1);
1880
1881                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1882                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1883                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1884                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1885                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1886                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1887                                         
1888                 /* WREG still holds the lower left */
1889                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1890                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1891                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1892                 
1893                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1894                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1895                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1896                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1897                                         
1898                 /* load result */
1899                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1900                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1901                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1902                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1903                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1904                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1905
1906                 pic16_popReleaseTempReg( pct4, 1 );
1907                 pic16_popReleaseTempReg( pct3, 1 );
1908                 pic16_popReleaseTempReg( pct2, 1 );
1909                 pic16_popReleaseTempReg( pct1, 1 );
1910
1911         } else {
1912
1913                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1914                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1915                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1916                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1917                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1918                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1919
1920                 /* WREG still holds the lower left */
1921                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1922                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1923                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1924                 
1925                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1926                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1927                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1928                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1929         }       
1930 }
1931
1932
1933 void pic16_genSMult16X16_16(operand *left,
1934                         operand *right,
1935                         operand *result)
1936 {
1937
1938 }
1939
1940 #if 0
1941 /*-----------------------------------------------------------------*
1942  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1943  *
1944  *  this routine will call the unsigned multiply routine and then
1945  * post-fix the sign bit.
1946  *-----------------------------------------------------------------*/
1947 void pic16_genSMult8X8_8 (operand *left,
1948                            operand *right,
1949                            operand *result,
1950                            pCodeOpReg *result_hi)
1951 {
1952         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1953
1954
1955   if(!result_hi) {
1956     result_hi = PCOR(pic16_popGet(AOP(result),1));
1957   }
1958
1959
1960   pic16_genUMult8X8_8(left,right,result);
1961
1962   
1963 #if 0
1964   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1965   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1966   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1967   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1968   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1969 #endif
1970 }
1971 #endif
1972
1973 /*-----------------------------------------------------------------*
1974  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
1975  *-----------------------------------------------------------------*/
1976 void pic16_genMult8X8_8 (operand *left,
1977                          operand *right,
1978                          operand *result)
1979 {
1980         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1981
1982         if(AOP_TYPE(right) == AOP_LIT)
1983                 pic16_genUMult8XLit_8(left,right,result);
1984         else
1985                 pic16_genUMult8X8_8(left,right,result);
1986 }
1987
1988
1989 /*-----------------------------------------------------------------*
1990  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
1991  *-----------------------------------------------------------------*/
1992 void pic16_genMult16X16_16 (operand *left,
1993                          operand *right,
1994                          operand *result)
1995 {
1996         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1997
1998         if (AOP_TYPE(right) == AOP_LIT)
1999                 pic16_genUMult16XLit_16(left,right,result);
2000         else
2001                 pic16_genUMult16X16_16(left,right,result);
2002
2003 }
2004
2005
2006
2007
2008 /*-----------------------------------------------------------------------*
2009  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2010  *-----------------------------------------------------------------------*/
2011 void pic16_genUMult32XLit_32 (operand *left,
2012                              operand *right,
2013                              operand *result)
2014 {
2015   pCodeOp *pct1, *pct2, *pct3, *pct4;
2016   unsigned int lit;
2017   int same;
2018
2019
2020         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2021
2022         if (AOP_TYPE(right) != AOP_LIT){
2023                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2024                 exit(1);
2025         }
2026
2027         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2028         lit &= 0xffff;
2029
2030         same = pic16_sameRegs(AOP(left), AOP(result));
2031         if(same) {
2032                 switch(lit) {
2033                         case 0:
2034                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2035                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2036                                 return;
2037                         case 2:
2038                                 // its faster to left shift
2039                                 emitCLRC;
2040                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2041                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2042                                 return;
2043
2044                         default: {
2045                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2046
2047                                 pct1 = pic16_popGetTempReg(1);
2048                                 pct2 = pic16_popGetTempReg(1);
2049                                 pct3 = pic16_popGetTempReg(1);
2050                                 pct4 = pic16_popGetTempReg(1);
2051
2052                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2053                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2054                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2055                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2056                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2057                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2058                                         
2059                                 /* WREG still holds the low literal */
2060                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2061                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2062                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2063                                         
2064                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2065                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2066                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2067                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2068                                         
2069                                 /* load result */
2070                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2071                                         pct1, pic16_popGet(AOP(result), 0)));
2072                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2073                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2074                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2075                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2076
2077                                 pic16_popReleaseTempReg( pct4, 1 );
2078                                 pic16_popReleaseTempReg( pct3, 1 );
2079                                 pic16_popReleaseTempReg( pct2, 1 );
2080                                 pic16_popReleaseTempReg( pct1, 1 );
2081                         }; return;
2082                 }
2083         } else {
2084                 // operands different
2085                 switch(lit) {
2086                         case 0:
2087                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2088                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2089                                 return;
2090                         case 2:
2091                                 emitCLRC;
2092                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2093                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2094                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2095                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2096                                 return;
2097                         default: {
2098                                         
2099                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2100                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2101                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2102                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2103                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2104                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2105                                         
2106                                 /* WREG still holds the low literal */
2107                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2108                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2109                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2110                                         
2111                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2112                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2113                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2114                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2115
2116                         }; return;
2117                 }
2118         }
2119 }
2120
2121
2122 /*------------------------------------------------------------------*
2123  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2124  *------------------------------------------------------------------*/
2125 void pic16_genUMult32X32_32 (operand *left,
2126                            operand *right,
2127                            operand *result)
2128
2129 {
2130   pCodeOp *pct1, *pct2, *pct3, *pct4;
2131
2132         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2133
2134
2135         if (AOP_TYPE(right) == AOP_LIT) {
2136                 pic16_genUMult8XLit_8(left,right,result);
2137           return;
2138         }
2139
2140         /* cases:
2141                 A = A x B       B = A x B
2142                 A = B x C
2143         */
2144         /* if result == right then exchange left and right */
2145         if(pic16_sameRegs(AOP(result), AOP(right))) {
2146           operand *tmp;
2147                 tmp = left;
2148                 left = right;
2149                 right = tmp;
2150         }
2151
2152
2153         if(pic16_sameRegs(AOP(result), AOP(left))) {
2154
2155                 pct1 = pic16_popGetTempReg(1);
2156                 pct2 = pic16_popGetTempReg(1);
2157                 pct3 = pic16_popGetTempReg(1);
2158                 pct4 = pic16_popGetTempReg(1);
2159
2160                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2161                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2162                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2163                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2164                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2165                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2166                                         
2167                 /* WREG still holds the lower left */
2168                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2169                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2170                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2171                 
2172                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2173                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2174                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2175                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2176                                         
2177                 /* load result */
2178                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2179                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2180                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2181                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2182                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2183                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2184
2185                 pic16_popReleaseTempReg( pct4, 1 );
2186                 pic16_popReleaseTempReg( pct3, 1 );
2187                 pic16_popReleaseTempReg( pct2, 1 );
2188                 pic16_popReleaseTempReg( pct1, 1 );
2189
2190         } else {
2191
2192                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2193                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2194                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2195                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2196                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2197                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2198
2199                 /* WREG still holds the lower left */
2200                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2201                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2202                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2203                 
2204                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2205                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2206                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2207                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2208         }       
2209 }
2210
2211
2212 /*-----------------------------------------------------------------*
2213  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2214  *-----------------------------------------------------------------*/
2215 void pic16_genMult32X32_32 (operand *left,
2216                          operand *right,
2217                          operand *result)
2218 {
2219         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2220
2221         if (AOP_TYPE(right) == AOP_LIT)
2222                 pic16_genUMult32XLit_32(left,right,result);
2223         else
2224                 pic16_genUMult32X32_32(left,right,result);
2225
2226 }
2227
2228
2229
2230
2231
2232
2233
2234 #if 0
2235 /*-----------------------------------------------------------------*/
2236 /* constMult - generates code for multiplication by a constant     */
2237 /*-----------------------------------------------------------------*/
2238 void genMultConst(unsigned C)
2239 {
2240
2241   unsigned lit;
2242   unsigned sr3; // Shift right 3
2243   unsigned mask;
2244
2245   int size = 1;
2246
2247   /*
2248     Convert a string of 3 binary 1's in the lit into
2249     0111 = 1000 - 1;
2250   */
2251
2252   mask = 7 << ( (size*8) - 3);
2253   lit = C;
2254   sr3 = 0;
2255
2256   while(mask < (1<<size*8)) {
2257
2258     if( (mask & lit) == lit) {
2259       unsigned lsb;
2260
2261       /* We found 3 (or more) consecutive 1's */
2262
2263       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2264
2265       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2266
2267       lit ^= consecutive_bits;
2268
2269       mask <<= 3;
2270
2271       sr3 |= (consecutive + lsb);
2272
2273     }
2274
2275     mask >>= 1;
2276
2277   }
2278
2279 }
2280
2281 #endif