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