218c263ad35e7a378dc0a50e406baca289a0b3dd
[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)) > 2)
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*/
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
787   /* special cases :- */
788   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
789
790   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
791   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
792   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
793
794   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
795
796   /* if literal, literal on the right or
797      if left requires ACC or right is already
798      in ACC */
799
800   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
801     operand *t = IC_RIGHT(ic);
802     IC_RIGHT(ic) = IC_LEFT(ic);
803     IC_LEFT(ic) = t;
804   }
805
806   /* if both left & right are in bit space */
807   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
808       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
809     pic16_genPlusBits (ic);
810     goto release ;
811   }
812
813   /* if left in bit space & right literal */
814   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
815       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
816     /* if result in bit space */
817     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
818       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
819         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
820         if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
821           pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
822         pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
823       }
824     } else {
825       size = pic16_getDataSize(IC_RESULT(ic));
826       while (size--) {
827         MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
828         pic16_emitcode("addc","a,#00  ;%d",__LINE__);
829         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
830       }
831     }
832     goto release ;
833   }
834
835   /* if I can do an increment instead
836      of add then GOOD for ME */
837   if (pic16_genPlusIncr (ic) == TRUE)
838     goto release;   
839
840   size = pic16_getDataSize(IC_RESULT(ic));
841
842   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
843     /* Add a literal to something else */
844     //bool know_W=0;
845     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
846     //      unsigned l1=0;
847
848     //      offset = 0;
849     DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
850
851     genAddLit (ic,  lit);
852     goto release;
853
854   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
855
856     pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
857     pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
858     pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
859
860     /* here we are adding a bit to a char or int */
861     if(size == 1) {
862       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
863
864         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
865         pic16_emitpcode(POC_INCF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
866
867         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
868                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
869                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
870         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
871       } else {
872
873         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
874           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
875           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
876
877           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
878                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
879                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
880           pic16_emitcode(" xorlw","1");
881         } else {
882           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
883           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
884           pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
885
886           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
887           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
888                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
889                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
890           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
891         }
892           
893         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
894             
895           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
896             pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
897             pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
898             emitSKPZ;
899             pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
900           } else {
901             pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
902             pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
903           }
904         }
905       }
906
907     } else {
908       int offset = 1;
909       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
910       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
911         emitCLRZ;
912         pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
913         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
914
915         pic16_emitcode("clrz","");
916
917         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
918                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
919                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
920         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
921
922       } else {
923
924         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
925         pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
926         pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
927         //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
928         emitMOVWF(IC_RIGHT(ic),0);
929
930         pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
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,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
935         pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
936
937       }
938
939       while(--size){
940         emitSKPZ;
941         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset++));
942         //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
943       }
944
945     }
946       
947   } else {
948     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
949
950     /* Add the first bytes */
951
952     if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
953       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
954       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
955     } else {
956
957       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
958         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
959         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
960           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
961       } else {
962
963         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
964
965         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
966           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
967         else {
968           PIC_OPCODE poc = POC_ADDFW;
969
970           if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
971               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
972               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
973             poc = POC_ADDLW;
974           pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
975           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
976             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
977         }
978       }
979     }
980
981     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
982     offset = 1;
983
984
985     while(size--){
986       if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
987         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
988         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
989
990         pic16_emitcode("movf","%s,w",  pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
991         pic16_emitcode("movwf","%s",  pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
992       }
993
994       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(IC_RIGHT(ic)),offset));
995       emitSKPNC;
996       pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
997       pic16_emitpcode(POC_ADDWF,   pic16_popGet(AOP(IC_RESULT(ic)),offset));
998
999       /*
1000         pic16_emitcode("movf","%s,w",  pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1001         emitSKPNC;
1002         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1003         pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1004       */
1005
1006       offset++;
1007     }
1008
1009   }
1010
1011   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1012     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1013                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1014
1015
1016     /* Need to extend result to higher bytes */
1017     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1018
1019     /* First grab the carry from the lower bytes */
1020     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1021     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1022
1023
1024     if(sign) {
1025       /* Now this is really horrid. Gotta check the sign of the addends and propogate
1026        * to the result */
1027
1028       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1029       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1030       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1031       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1032
1033       /* if chars or ints or being signed extended to longs: */
1034       if(size) {
1035         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1036         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1037         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1038       }
1039     }
1040
1041     offset++;
1042     while(size--) {
1043       
1044       if(sign)
1045         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1046       else
1047         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1048
1049       offset++;
1050     }
1051   }
1052
1053
1054   //adjustArithmeticResult(ic);
1055
1056  release:
1057   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1058   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1059   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1060 }
1061
1062 /*-----------------------------------------------------------------*/
1063 /* pic16_genMinusDec :- does subtraction with decrement if possible     */
1064 /*-----------------------------------------------------------------*/
1065 bool pic16_genMinusDec (iCode *ic)
1066 {
1067     unsigned int icount ;
1068     unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1069
1070     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1071     /* will try to generate an increment */
1072     /* if the right side is not a literal 
1073     we cannot */
1074     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1075         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1076         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1077         return FALSE ;
1078
1079     DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1080
1081     /* if the literal value of the right hand side
1082     is greater than 4 then it is not worth it */
1083     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1084         return FALSE ;
1085
1086     /* if decrement 16 bits in register */
1087     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1088         (size > 1) &&
1089         (icount == 1)) {
1090
1091       if(size == 2) { 
1092         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1093         pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1094         pic16_emitpcode(POC_INCF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1095         pic16_emitpcode(POC_DECF,    pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1096
1097         pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1098         pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1099         pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1100       } else {
1101         /* size is 3 or 4 */
1102         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1103         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1104         emitSKPNC;
1105         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1106         emitSKPNC;
1107         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1108
1109         pic16_emitcode("movlw","0xff");
1110         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1111
1112         emitSKPNC;
1113         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1114         emitSKPNC;
1115         pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1116
1117         if(size > 3) {
1118           emitSKPNC;
1119           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1120
1121           pic16_emitcode("skpnc","");
1122           emitSKPNC;
1123           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1124         }
1125
1126       }
1127
1128       return TRUE;
1129
1130     }
1131
1132     /* if the sizes are greater than 1 then we cannot */
1133     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1134         AOP_SIZE(IC_LEFT(ic)) > 1   )
1135         return FALSE ;
1136
1137     /* we can if the aops of the left & result match or
1138     if they are in registers and the registers are the
1139     same */
1140     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1141
1142       while (icount--) 
1143         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1144
1145         //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1146
1147         return TRUE ;
1148     }
1149
1150     DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1151                    pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1152                    pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1153     if(size==1) {
1154
1155       pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1156       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1157
1158       pic16_emitpcode(POC_DECFW,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1159       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1160
1161       return TRUE;
1162     }
1163
1164     return FALSE ;
1165 }
1166
1167 /*-----------------------------------------------------------------*/
1168 /* pic16_addSign - propogate sign bit to higher bytes                    */
1169 /*-----------------------------------------------------------------*/
1170 void pic16_addSign(operand *result, int offset, int sign)
1171 {
1172   int size = (pic16_getDataSize(result) - offset);
1173   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1174
1175   if(size > 0){
1176     if(sign && offset) {
1177
1178       if(size == 1) {
1179         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1180         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1181         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1182       } else {
1183
1184         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1185         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1186         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1187         while(size--)
1188           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1189
1190       }
1191     } else
1192       while(size--)
1193         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1194   }
1195 }
1196
1197 /*-----------------------------------------------------------------*/
1198 /* pic16_genMinusBits - generates code for subtraction  of two bits      */
1199 /*-----------------------------------------------------------------*/
1200 void pic16_genMinusBits (iCode *ic)
1201 {
1202     symbol *lbl = newiTempLabel(NULL);
1203     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1204     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1205         pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1206         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1207         pic16_emitcode("cpl","c");
1208         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1209         pic16_outBitC(IC_RESULT(ic));
1210     }
1211     else{
1212         pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1213         pic16_emitcode("subb","a,acc");
1214         pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1215         pic16_emitcode("inc","a");
1216         pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1217         pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1218         pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1219     }
1220 }
1221
1222 /*-----------------------------------------------------------------*/
1223 /* pic16_genMinus - generates code for subtraction                       */
1224 /*-----------------------------------------------------------------*/
1225 void pic16_genMinus (iCode *ic)
1226 {
1227   int size, offset = 0, same=0;
1228   unsigned long lit = 0L;
1229
1230   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1231   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1232   pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1233   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1234
1235   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1236       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1237     operand *t = IC_RIGHT(ic);
1238     IC_RIGHT(ic) = IC_LEFT(ic);
1239     IC_LEFT(ic) = t;
1240   }
1241
1242   DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1243                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1244                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1245                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1246
1247   /* special cases :- */
1248   /* if both left & right are in bit space */
1249   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1250       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1251     pic16_genPlusBits (ic);
1252     goto release ;
1253   }
1254
1255   /* if I can do an decrement instead
1256      of subtract then GOOD for ME */
1257   //  if (pic16_genMinusDec (ic) == TRUE)
1258   //    goto release;   
1259
1260   size = pic16_getDataSize(IC_RESULT(ic));   
1261   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1262
1263   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1264     /* Add a literal to something else */
1265
1266     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1267     lit = - (long)lit;
1268
1269     genAddLit ( ic,  lit);
1270     
1271 #if 0
1272     /* add the first byte: */
1273     pic16_emitcode("movlw","0x%x", lit & 0xff);
1274     pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1275     pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1276     pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
1277
1278
1279     offset = 1;
1280     size--;
1281
1282     while(size-- > 0) {
1283
1284       lit >>= 8;
1285
1286       if(lit & 0xff) {
1287
1288         if((lit & 0xff) == 0xff) {
1289           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
1290           emitSKPC;
1291           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1292         } else {
1293           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
1294           emitSKPNC;
1295           pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
1296           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1297         }
1298
1299       } else {
1300         /* do the rlf known zero trick here */
1301         pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
1302         emitSKPNC;
1303         pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1304       }
1305       offset++;
1306     }
1307 #endif
1308   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1309     // bit subtraction
1310
1311     pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1312     pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1313     pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1314
1315     /* here we are subtracting a bit from a char or int */
1316     if(size == 1) {
1317       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1318
1319         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1320         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1321
1322         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1323                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1324                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1325         pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1326       } else {
1327
1328         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1329           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1330           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1331         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1332               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1333
1334           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1335
1336           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1337             if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1338               if(lit & 1) {
1339                 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1340                 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1341               }
1342             }else{
1343               pic16_emitpcode(POC_BCF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1344               if(lit & 1) 
1345                 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1346               else
1347                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1348               pic16_emitpcode(POC_BSF ,     pic16_popGet(AOP(IC_RESULT(ic)),0));
1349             }
1350             goto release;
1351           } else {
1352             pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1353             pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1354             pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1355             pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1356
1357           }
1358
1359         } else {
1360           pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1361           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1362           pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1363         }
1364           
1365         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1366             
1367           pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1368
1369         } else  {
1370           pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1371 /*
1372           pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1373           emitSKPZ;
1374           pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1375 */
1376         }
1377
1378       }
1379
1380     }
1381   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1382               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1383               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1384
1385     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1386     DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1387                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1388                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1389                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1390
1391
1392     if( (size == 1) && ((lit & 0xff) == 0) ) {
1393       /* res = 0 - right */
1394       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1395         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1396         pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1397       } else { 
1398         pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1399         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
1400         pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1401       }
1402       goto release;
1403     }
1404
1405     pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
1406     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
1407     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1408
1409
1410     offset = 1;
1411     while(--size) {
1412       lit >>= 8;
1413
1414       if(size == 1) {
1415         /* This is the last byte in a multibyte subtraction 
1416          * There are a couple of tricks we can do by not worrying about 
1417          * propogating the carry */
1418         if(lit == 0xff) {
1419           /* 0xff - x == ~x */
1420           if(same) {
1421             pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1422             emitSKPC;
1423             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1424           } else {
1425             pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1426             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1427             emitSKPC;
1428             pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1429           }
1430         } else {
1431             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1432             emitSKPC;
1433             pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1434             pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1435             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1436         }
1437
1438         goto release;
1439       }
1440
1441       if(same) {
1442
1443         if(lit & 0xff) {
1444           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1445           emitSKPC;
1446           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1447           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1448         } else {
1449           emitSKPNC;
1450           pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1451
1452         }
1453       } else {
1454
1455         if(lit & 0xff) {
1456           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1457           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1458         } else
1459           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1460
1461         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1462         emitSKPC;
1463         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1464         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1465       }
1466     }
1467   
1468
1469   } else {
1470
1471     DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1472                    pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1473                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1474                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1475
1476     if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1477       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1478       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1479       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1480       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1481     } else {
1482
1483       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1484         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1485         pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1486         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1487           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1488       } else {
1489
1490         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1491         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1492           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1493
1494         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1495           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1496         else {
1497           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1498               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1499             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1500           } else {
1501             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1502           }
1503           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1504             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1505               pic16_emitpcode(POC_BCF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1506               emitSKPZ;
1507               pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1508             }else
1509               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1510           }
1511         }
1512       }
1513     }
1514
1515     /*
1516       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1517
1518       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1519       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1520       } else {
1521       pic16_emitpcode(POC_SUBFW,  pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1522       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1523       }
1524     */
1525     offset = 1;
1526     size--;
1527
1528     while(size--){
1529       if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1530         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
1531         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1532       }
1533       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1534       emitSKPC;
1535       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1536       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
1537
1538       offset++;
1539     }
1540
1541   }
1542
1543
1544   //    adjustArithmeticResult(ic);
1545         
1546  release:
1547   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1548   pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1549   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1550 }
1551 /*-----------------------------------------------------------------*
1552  * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1553  * 
1554  * 
1555  *-----------------------------------------------------------------*/
1556 void pic16_genUMult8XLit_16 (operand *left,
1557                              operand *right,
1558                              operand *result,
1559                              pCodeOpReg *result_hi)
1560
1561 {
1562
1563   unsigned int lit;
1564   unsigned int i,have_first_bit;
1565   int same;
1566   pCodeOp *temp;
1567
1568   if (AOP_TYPE(right) != AOP_LIT){
1569     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1570     exit(1);
1571   }
1572
1573
1574   if(!result_hi) {
1575     result_hi = PCOR(pic16_popGet(AOP(result),1));
1576   }
1577
1578   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1579   lit &= 0xff;
1580   pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1581
1582   same = pic16_sameRegs(AOP(left), AOP(result));
1583
1584   if(same) {
1585     switch(lit) {
1586     case 0:
1587       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(left),0));
1588       return;
1589     case 2:
1590       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1591       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1592       return;
1593     case 3:
1594       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1595       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1596       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1597       return;
1598     case 4:
1599       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1600       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1601       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1602       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1603       return;
1604     case 5:
1605       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1606       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1607       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1608       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
1609       return;
1610     case 6:
1611       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1612       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1613       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1614       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1615       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1616       return;
1617     case 7:
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       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 7*F
1623       return;
1624     case 8:
1625       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1626       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1627       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1628       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
1629       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
1630       return;
1631     case 9:
1632       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1633       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1634       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1635       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1636       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1637       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1638       return;
1639     case 10:
1640       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1641       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1642       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1643       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
1644       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1645       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1646       return;
1647     case 11:
1648       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1649       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1650       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1651       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
1652       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
1653       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 11*F
1654       return;
1655     case 12:
1656       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1657       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1658       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1659       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1660       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1661       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1662       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1663       return;
1664     case 13:
1665       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1666       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1667       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1668       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
1669       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
1670       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 13*F
1671       return;
1672     case 14:
1673       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1674       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
1675       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
1676       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
1677       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
1678       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 11*F
1679       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 14*F
1680       return;
1681     case 15:
1682       temp = pic16_popGetTempReg();
1683       if(!temp) {
1684         fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1685         exit(1);
1686       }
1687       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1688       pic16_emitpcode(POC_MOVWF,  temp);
1689       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
1690       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
1691       pic16_emitpcode(POC_SWAPFW, temp);
1692       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(left),0));
1693       pic16_popReleaseTempReg(temp);
1694       return;
1695     case 16:
1696       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1697       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
1698       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
1699       return;
1700     case 17:
1701       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1702       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
1703       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(left),0));
1704       return;
1705     case 32:
1706       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
1707       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
1708       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xe0));
1709       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
1710       return;
1711     case 64:
1712       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
1713       pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(left),0));
1714       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
1715       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xc0));
1716       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
1717       return;
1718     case 128:
1719       pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0));
1720       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(left),0));
1721       pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(left),0));
1722       return;
1723
1724     }
1725   } else {
1726
1727     switch(lit) {
1728     case 0:
1729       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1730       pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1731       return;
1732     case 2:
1733       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1734       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1735       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1736       pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1737       pic16_emitpcode(POC_RLCF,  pic16_popCopyReg(result_hi));
1738       return;
1739     }
1740
1741   }
1742
1743   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1744   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1745   pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1746
1747   have_first_bit = 0;
1748   for(i=0; i<8; i++) {
1749
1750     if(lit & 1) {
1751       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1752       have_first_bit = 1;
1753     }
1754
1755     if(have_first_bit) {
1756       pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
1757       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
1758     }
1759
1760     lit >>= 1;
1761   }
1762
1763 }
1764
1765 /*-----------------------------------------------------------------*
1766  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1767  * 
1768  * 
1769  *-----------------------------------------------------------------*/
1770 void pic16_genUMult8X8_16 (operand *left,
1771                            operand *right,
1772                            operand *result,
1773                            pCodeOpReg *result_hi)
1774
1775 {
1776
1777   int i;
1778   int looped = 1;
1779
1780   if(!result_hi) {
1781     result_hi = PCOR(pic16_popGet(AOP(result),1));
1782   }
1783
1784   if (AOP_TYPE(right) == AOP_LIT) {
1785     pic16_genUMult8XLit_16(left,right,result,result_hi);
1786     return;
1787   }
1788
1789   if(!looped) {
1790     pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1791
1792     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1793     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1794     pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1795     emitCLRC;
1796
1797     for(i=0; i<8; i++) {
1798       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1799       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1800       pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
1801       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
1802     }
1803
1804
1805     /*
1806       Here's another version that does the same thing and takes the 
1807       same number of instructions. The one above is slightly better
1808       because the entry instructions have a higher probability of
1809       being optimized out.
1810     */
1811     /*
1812       pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1813       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1814       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1815       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1816
1817       for(i=0; i<8; i++) {
1818       emitSKPNC;
1819       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1820       pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
1821       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
1822       }
1823     */
1824
1825   } else {
1826     symbol  *tlbl = newiTempLabel(NULL);
1827     pCodeOp *temp;
1828
1829
1830     pic16_emitcode(";","Looped 8 X 8 multiplication");
1831
1832     pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
1833     pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
1834
1835     pic16_emitpcode(POC_BSF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1836
1837     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1838
1839     temp = pic16_popGetTempReg();
1840     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1841
1842     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1843
1844     pic16_emitpLabel(tlbl->key);
1845
1846     pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(PCOR(temp)));
1847     emitSKPNC;
1848     pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1849
1850     pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
1851     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
1852
1853     emitSKPC;
1854     pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl->key));
1855
1856     pic16_popReleaseTempReg(temp);
1857
1858   }
1859 }
1860
1861 /*-----------------------------------------------------------------*
1862  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1863  *
1864  *  this routine will call the unsigned multiply routine and then
1865  * post-fix the sign bit.
1866  *-----------------------------------------------------------------*/
1867 void pic16_genSMult8X8_16 (operand *left,
1868                            operand *right,
1869                            operand *result,
1870                            pCodeOpReg *result_hi)
1871 {
1872
1873   if(!result_hi) {
1874     result_hi = PCOR(pic16_popGet(AOP(result),1));
1875   }
1876
1877   pic16_genUMult8X8_16(left,right,result,result_hi);
1878
1879   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1880   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1881   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1882   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1883   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1884   
1885 }
1886
1887 /*-----------------------------------------------------------------*
1888  * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1889  *
1890  *  this routine will call the unsigned multiply 8X8=>16 routine and
1891  * then throw away the high byte of the result.
1892  *
1893  *-----------------------------------------------------------------*/
1894 void pic16_genMult8X8_8 (operand *left,
1895                          operand *right,
1896                          operand *result)
1897 {
1898   pCodeOp *result_hi = pic16_popGetTempReg();
1899
1900   if (AOP_TYPE(right) == AOP_LIT)
1901     pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1902   else
1903     pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1904
1905   pic16_popReleaseTempReg(result_hi);
1906 }
1907 #if 0
1908 /*-----------------------------------------------------------------*/
1909 /* constMult - generates code for multiplication by a constant     */
1910 /*-----------------------------------------------------------------*/
1911 void genMultConst(unsigned C)
1912 {
1913
1914   unsigned lit;
1915   unsigned sr3; // Shift right 3
1916   unsigned mask;
1917
1918   int size = 1;
1919
1920   /*
1921     Convert a string of 3 binary 1's in the lit into
1922     0111 = 1000 - 1;
1923   */
1924
1925   mask = 7 << ( (size*8) - 3);
1926   lit = C;
1927   sr3 = 0;
1928
1929   while(mask < (1<<size*8)) {
1930
1931     if( (mask & lit) == lit) {
1932       unsigned lsb;
1933
1934       /* We found 3 (or more) consecutive 1's */
1935
1936       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1937
1938       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1939
1940       lit ^= consecutive_bits;
1941
1942       mask <<= 3;
1943
1944       sr3 |= (consecutive + lsb);
1945
1946     }
1947
1948     mask >>= 1;
1949
1950   }
1951
1952 }
1953
1954 #endif