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