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