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