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