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