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