a543487350e450115839f46d8d98fd97800fd95e
[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   int size = AOP_SIZE(result);
1608   int i;
1609
1610         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1611         DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1612
1613         if (AOP_TYPE(right) != AOP_LIT){
1614                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1615                 exit(1);
1616         }
1617
1618         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1619         lit &= 0xff;
1620         pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1621         pic16_emitpcomment("FIXME: the function does not support result==WREG");
1622         
1623         same = pic16_sameRegs(AOP(left), AOP(result));
1624         if(same) {
1625                 switch(lit) {
1626                         case 0:
1627                                 while (size--) {
1628                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1629                                 } // while
1630                                 return;
1631                         case 2:
1632                                 // its faster to left shift
1633                                 for (i=1; i < size; i++) {
1634                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1635                                 } // for
1636                                 emitCLRC;
1637                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1638                                 if (size > 1)
1639                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1640                                 return;
1641
1642                         default:
1643                                 if(AOP_TYPE(left) != AOP_ACC)
1644                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1645                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1646                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1647                                         pic16_popGet(AOP(result), 0)));
1648                                 if (size > 1) {
1649                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1650                                                                             pic16_popGet(AOP(result), 1)));
1651                                   for (i=2; i < size; i++) {
1652                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1653                                   } // for
1654                                 } // if
1655                                 return;
1656                 }
1657         } else {
1658                 // operands different
1659                 switch(lit) {
1660                         case 0:
1661                                 while (size--) {
1662                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
1663                                 } // while
1664                                 return;
1665                         case 2:
1666                                 for (i=1; i < size; i++) {
1667                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1668                                 } // for
1669                                 emitCLRC;
1670                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1671                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1672                                 if (size > 1)
1673                                   pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1674                                 return;
1675                         default:
1676                                 if(AOP_TYPE(left) != AOP_ACC)
1677                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1678                                 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1679                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1680                                         pic16_popGet(AOP(result), 0)));
1681
1682                                 if (size > 1) {
1683                                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1684                                                                             pic16_popGet(AOP(result), 1)));
1685                                   for (i=2; i < size; i++) {
1686                                     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
1687                                   } // for
1688                                 } // if
1689                                 return;
1690                 }
1691         }
1692 }
1693
1694 /*-----------------------------------------------------------------------*
1695  * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1696  *-----------------------------------------------------------------------*/
1697 void pic16_genUMult16XLit_16 (operand *left,
1698                              operand *right,
1699                              operand *result)
1700 {
1701   pCodeOp *pct1, *pct2, *pct3, *pct4;
1702   unsigned int lit;
1703   int same;
1704
1705
1706         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1707
1708         if (AOP_TYPE(right) != AOP_LIT){
1709                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1710                 exit(1);
1711         }
1712
1713         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1714         lit &= 0xffff;
1715
1716         same = pic16_sameRegs(AOP(left), AOP(result));
1717         if(same) {
1718                 switch(lit) {
1719                         case 0:
1720                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1721                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1722                                 return;
1723                         case 2:
1724                                 // its faster to left shift
1725                                 emitCLRC;
1726                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1727                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1728                                 return;
1729
1730                         default: {
1731                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1732
1733                                 pct1 = pic16_popGetTempReg(1);
1734                                 pct2 = pic16_popGetTempReg(1);
1735                                 pct3 = pic16_popGetTempReg(1);
1736                                 pct4 = pic16_popGetTempReg(1);
1737
1738                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1739                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1740                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1741                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1742                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1743                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1744                                         
1745                                 /* WREG still holds the low literal */
1746                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1747                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1748                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1749                                         
1750                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1751                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1752                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1753                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1754                                         
1755                                 /* load result */
1756                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1757                                         pct1, pic16_popGet(AOP(result), 0)));
1758                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1759                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1760                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1761                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1762
1763                                 pic16_popReleaseTempReg(pct4,1);
1764                                 pic16_popReleaseTempReg(pct3,1);
1765                                 pic16_popReleaseTempReg(pct2,1);
1766                                 pic16_popReleaseTempReg(pct1,1);
1767                         }; return;
1768                 }
1769         } else {
1770                 // operands different
1771                 switch(lit) {
1772                         case 0:
1773                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1774                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1775                                 return;
1776                         case 2:
1777                                 emitCLRC;
1778                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1779                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1780                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1781                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1782                                 return;
1783                         default: {
1784                                         
1785                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1786                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1787                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1788                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1789                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1790                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1791                                         
1792                                 /* WREG still holds the low literal */
1793                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1794                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1795                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1796                                         
1797                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1798                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1799                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1800                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1801
1802                         }; return;
1803                 }
1804         }
1805 }
1806
1807
1808 /*-----------------------------------------------------------------*
1809  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1810  * 
1811  * 
1812  *-----------------------------------------------------------------*/
1813 void pic16_genUMult8X8_8 (operand *left,
1814                            operand *right,
1815                            operand *result)
1816
1817 {
1818         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1819
1820
1821         if (AOP_TYPE(right) == AOP_LIT) {
1822                 pic16_genUMult8XLit_8(left,right,result);
1823           return;
1824         }
1825
1826         /* cases:
1827                 A = A x B       B = A x B
1828                 A = B x C
1829                 W = A x B
1830                 W = W x B       W = B x W
1831         */
1832         /* if result == right then exchange left and right */
1833         if(pic16_sameRegs(AOP(result), AOP(right))) {
1834           operand *tmp;
1835                 tmp = left;
1836                 left = right;
1837                 right = tmp;
1838         }
1839                 
1840         if(AOP_TYPE(left) != AOP_ACC) {
1841                 // left is not WREG
1842                 if(AOP_TYPE(right) != AOP_ACC) {
1843                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1844                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1845                 } else {
1846                         pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1847                 }
1848         } else {
1849                 // left is WREG, right cannot be WREG (or can?!)
1850                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1851         }
1852         
1853         /* result is in PRODL:PRODH */
1854         if(AOP_TYPE(result) != AOP_ACC) {
1855                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1856                         pic16_popGet(AOP(result), 0)));
1857
1858
1859                 if(AOP_SIZE(result)>1) {
1860                   int i;
1861
1862                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1863                         pic16_popGet(AOP(result), 1)));
1864                         
1865                         for(i=2;i<AOP_SIZE(result);i++)
1866                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1867                 }
1868         } else {
1869                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1870         }
1871 }
1872
1873 /*------------------------------------------------------------------*
1874  * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1875  *------------------------------------------------------------------*/
1876 void pic16_genUMult16X16_16 (operand *left,
1877                            operand *right,
1878                            operand *result)
1879
1880 {
1881   pCodeOp *pct1, *pct2, *pct3, *pct4;
1882
1883         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1884
1885
1886         if (AOP_TYPE(right) == AOP_LIT) {
1887                 pic16_genUMult8XLit_8(left,right,result);
1888           return;
1889         }
1890
1891         /* cases:
1892                 A = A x B       B = A x B
1893                 A = B x C
1894         */
1895         /* if result == right then exchange left and right */
1896         if(pic16_sameRegs(AOP(result), AOP(right))) {
1897           operand *tmp;
1898                 tmp = left;
1899                 left = right;
1900                 right = tmp;
1901         }
1902
1903
1904         if(pic16_sameRegs(AOP(result), AOP(left))) {
1905
1906                 pct1 = pic16_popGetTempReg(1);
1907                 pct2 = pic16_popGetTempReg(1);
1908                 pct3 = pic16_popGetTempReg(1);
1909                 pct4 = pic16_popGetTempReg(1);
1910
1911                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1912                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1913                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1914                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1915                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1916                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1917                                         
1918                 /* WREG still holds the lower left */
1919                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1920                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1921                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1922                 
1923                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1924                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1925                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1926                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1927                                         
1928                 /* load result */
1929                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1930                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1931                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1932                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1933                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1934                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1935
1936                 pic16_popReleaseTempReg( pct4, 1 );
1937                 pic16_popReleaseTempReg( pct3, 1 );
1938                 pic16_popReleaseTempReg( pct2, 1 );
1939                 pic16_popReleaseTempReg( pct1, 1 );
1940
1941         } else {
1942
1943                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1944                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1945                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1946                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1947                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1948                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1949
1950                 /* WREG still holds the lower left */
1951                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1952                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1953                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1954                 
1955                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1956                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1957                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1958                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1959         }       
1960 }
1961
1962
1963 void pic16_genSMult16X16_16(operand *left,
1964                         operand *right,
1965                         operand *result)
1966 {
1967
1968 }
1969
1970 #if 0
1971 /*-----------------------------------------------------------------*
1972  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1973  *
1974  *  this routine will call the unsigned multiply routine and then
1975  * post-fix the sign bit.
1976  *-----------------------------------------------------------------*/
1977 void pic16_genSMult8X8_8 (operand *left,
1978                            operand *right,
1979                            operand *result,
1980                            pCodeOpReg *result_hi)
1981 {
1982         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1983
1984
1985   if(!result_hi) {
1986     result_hi = PCOR(pic16_popGet(AOP(result),1));
1987   }
1988
1989
1990   pic16_genUMult8X8_8(left,right,result);
1991
1992   
1993 #if 0
1994   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1995   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1996   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1997   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1998   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1999 #endif
2000 }
2001 #endif
2002
2003 /*-----------------------------------------------------------------*
2004  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
2005  *-----------------------------------------------------------------*/
2006 void pic16_genMult8X8_8 (operand *left,
2007                          operand *right,
2008                          operand *result)
2009 {
2010         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2011
2012         if(AOP_TYPE(right) == AOP_LIT)
2013                 pic16_genUMult8XLit_8(left,right,result);
2014         else
2015                 pic16_genUMult8X8_8(left,right,result);
2016 }
2017
2018
2019 /*-----------------------------------------------------------------*
2020  * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
2021  *-----------------------------------------------------------------*/
2022 void pic16_genMult16X16_16 (operand *left,
2023                          operand *right,
2024                          operand *result)
2025 {
2026         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2027
2028         if (AOP_TYPE(right) == AOP_LIT)
2029                 pic16_genUMult16XLit_16(left,right,result);
2030         else
2031                 pic16_genUMult16X16_16(left,right,result);
2032
2033 }
2034
2035
2036
2037
2038 /*-----------------------------------------------------------------------*
2039  * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2040  *-----------------------------------------------------------------------*/
2041 void pic16_genUMult32XLit_32 (operand *left,
2042                              operand *right,
2043                              operand *result)
2044 {
2045   pCodeOp *pct1, *pct2, *pct3, *pct4;
2046   unsigned int lit;
2047   int same;
2048
2049
2050         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2051
2052         if (AOP_TYPE(right) != AOP_LIT){
2053                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2054                 exit(1);
2055         }
2056
2057         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2058         lit &= 0xffff;
2059
2060         same = pic16_sameRegs(AOP(left), AOP(result));
2061         if(same) {
2062                 switch(lit) {
2063                         case 0:
2064                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2065                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2066                                 return;
2067                         case 2:
2068                                 // its faster to left shift
2069                                 emitCLRC;
2070                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2071                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2072                                 return;
2073
2074                         default: {
2075                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2076
2077                                 pct1 = pic16_popGetTempReg(1);
2078                                 pct2 = pic16_popGetTempReg(1);
2079                                 pct3 = pic16_popGetTempReg(1);
2080                                 pct4 = pic16_popGetTempReg(1);
2081
2082                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2083                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2084                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2085                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2086                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2087                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2088                                         
2089                                 /* WREG still holds the low literal */
2090                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2091                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2092                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2093                                         
2094                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2095                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2096                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2097                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2098                                         
2099                                 /* load result */
2100                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2101                                         pct1, pic16_popGet(AOP(result), 0)));
2102                                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2103                                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2104                                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2105                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2106
2107                                 pic16_popReleaseTempReg( pct4, 1 );
2108                                 pic16_popReleaseTempReg( pct3, 1 );
2109                                 pic16_popReleaseTempReg( pct2, 1 );
2110                                 pic16_popReleaseTempReg( pct1, 1 );
2111                         }; return;
2112                 }
2113         } else {
2114                 // operands different
2115                 switch(lit) {
2116                         case 0:
2117                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2118                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2119                                 return;
2120                         case 2:
2121                                 emitCLRC;
2122                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2123                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2124                                 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2125                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2126                                 return;
2127                         default: {
2128                                         
2129                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2130                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2131                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2132                                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2133                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2134                                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2135                                         
2136                                 /* WREG still holds the low literal */
2137                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2138                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2139                                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2140                                         
2141                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2142                                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2143                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2144                                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2145
2146                         }; return;
2147                 }
2148         }
2149 }
2150
2151
2152 /*------------------------------------------------------------------*
2153  * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2154  *------------------------------------------------------------------*/
2155 void pic16_genUMult32X32_32 (operand *left,
2156                            operand *right,
2157                            operand *result)
2158
2159 {
2160   pCodeOp *pct1, *pct2, *pct3, *pct4;
2161
2162         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2163
2164
2165         if (AOP_TYPE(right) == AOP_LIT) {
2166                 pic16_genUMult8XLit_8(left,right,result);
2167           return;
2168         }
2169
2170         /* cases:
2171                 A = A x B       B = A x B
2172                 A = B x C
2173         */
2174         /* if result == right then exchange left and right */
2175         if(pic16_sameRegs(AOP(result), AOP(right))) {
2176           operand *tmp;
2177                 tmp = left;
2178                 left = right;
2179                 right = tmp;
2180         }
2181
2182
2183         if(pic16_sameRegs(AOP(result), AOP(left))) {
2184
2185                 pct1 = pic16_popGetTempReg(1);
2186                 pct2 = pic16_popGetTempReg(1);
2187                 pct3 = pic16_popGetTempReg(1);
2188                 pct4 = pic16_popGetTempReg(1);
2189
2190                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2191                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2192                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2193                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2194                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2195                         pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2196                                         
2197                 /* WREG still holds the lower left */
2198                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2199                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2200                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2201                 
2202                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2203                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2204                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2205                         pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2206                                         
2207                 /* load result */
2208                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2209                         pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2210                 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2211                 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2212                 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2213                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2214
2215                 pic16_popReleaseTempReg( pct4, 1 );
2216                 pic16_popReleaseTempReg( pct3, 1 );
2217                 pic16_popReleaseTempReg( pct2, 1 );
2218                 pic16_popReleaseTempReg( pct1, 1 );
2219
2220         } else {
2221
2222                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2223                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2224                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2225                         pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2226                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2227                         pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2228
2229                 /* WREG still holds the lower left */
2230                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2231                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2232                 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2233                 
2234                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2235                 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2236                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2237                 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2238         }       
2239 }
2240
2241
2242 /*-----------------------------------------------------------------*
2243  * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
2244  *-----------------------------------------------------------------*/
2245 void pic16_genMult32X32_32 (operand *left,
2246                          operand *right,
2247                          operand *result)
2248 {
2249         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2250
2251         if (AOP_TYPE(right) == AOP_LIT)
2252                 pic16_genUMult32XLit_32(left,right,result);
2253         else
2254                 pic16_genUMult32X32_32(left,right,result);
2255
2256 }
2257
2258
2259
2260
2261
2262
2263
2264 #if 0
2265 /*-----------------------------------------------------------------*/
2266 /* constMult - generates code for multiplication by a constant     */
2267 /*-----------------------------------------------------------------*/
2268 void genMultConst(unsigned C)
2269 {
2270
2271   unsigned lit;
2272   unsigned sr3; // Shift right 3
2273   unsigned mask;
2274
2275   int size = 1;
2276
2277   /*
2278     Convert a string of 3 binary 1's in the lit into
2279     0111 = 1000 - 1;
2280   */
2281
2282   mask = 7 << ( (size*8) - 3);
2283   lit = C;
2284   sr3 = 0;
2285
2286   while(mask < (1<<size*8)) {
2287
2288     if( (mask & lit) == lit) {
2289       unsigned lsb;
2290
2291       /* We found 3 (or more) consecutive 1's */
2292
2293       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2294
2295       consecutive_bits = ((lit + lsb) & lit) ^ lit;
2296
2297       lit ^= consecutive_bits;
2298
2299       mask <<= 3;
2300
2301       sr3 |= (consecutive + lsb);
2302
2303     }
2304
2305     mask >>= 1;
2306
2307   }
2308
2309 }
2310
2311 #endif