* src/pic/gen.c (popGet): changed assert to allow for
[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 (op_isLitLike (IC_LEFT (ic)))
1028                                                 poc = POC_ADDLW;
1029                                         emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
1030                                         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1031                                                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1032                                 }
1033                         }
1034                 }
1035                 
1036                 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1037                 offset = 1;
1038                 
1039                 
1040                 if(size){
1041                         if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1042                                 if (op_isLitLike (IC_LEFT(ic)))
1043                                 {
1044                                         while(size--){
1045                                                 emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
1046                                                 emitSKPNC;
1047                                                 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1048                                                 emitpcode(POC_ADDLW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1049                                                 emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
1050                                                 offset++;
1051                                         }
1052                                 } else {
1053                                         while(size--){
1054                                                 emitpcode(POC_MOVFW,   popGet(AOP(IC_LEFT(ic)),offset));
1055                                                 emitSKPNC;
1056                                                 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1057                                                 emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
1058                                                 offset++;
1059                                         }
1060                                 }
1061                         } else {
1062                                 PIC_OPCODE poc = POC_MOVFW;
1063                                 if (op_isLitLike (IC_LEFT(ic)))
1064                                         poc = POC_MOVLW;
1065                                 while(size--){
1066                                         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1067                                                 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1068                                                 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1069                                         }
1070                                         emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
1071                                         emitSKPNC;
1072                                         emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1073                                         emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
1074                                         offset++;
1075                                 }
1076                         }
1077                 }
1078         }
1079         
1080         if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1081                 int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1082                         SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1083                 
1084                 
1085                 /* Need to extend result to higher bytes */
1086                 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1087                 
1088                 /* First grab the carry from the lower bytes */
1089                 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { 
1090                         int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1091                         PIC_OPCODE poc = POC_MOVFW;
1092                         if (op_isLitLike (IC_LEFT(ic)))
1093                                 poc = POC_MOVLW;
1094                         while(leftsize-- > 0) {
1095                                 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1096                                 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1097                                 emitSKPNC;
1098                                 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
1099                                 offset++;
1100                                 if (size)
1101                                         size--;
1102                                 else
1103                                         break;
1104                         }
1105                 } else {
1106                         emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1107                         emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
1108                 }
1109                 
1110                 
1111                 if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
1112                 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1113                         * to the result */
1114                         
1115                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1116                         emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1117                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1118                         emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1119                         
1120                         /* if chars or ints or being signed extended to longs: */
1121                         if(size) {
1122                                 emitpcode(POC_MOVLW, popGetLit(0));
1123                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1124                                 emitpcode(POC_MOVLW, popGetLit(0xff));
1125                         }
1126                 }
1127                 
1128                 offset++;
1129                 while(size--) {
1130                         
1131                         if(sign)
1132                                 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1133                         else
1134                                 emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
1135                         
1136                         offset++;
1137                 }
1138         }
1139         
1140         
1141         //adjustArithmeticResult(ic);
1142         
1143 release:
1144         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1145         freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1146         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1147 }
1148
1149 /*-----------------------------------------------------------------*/
1150 /* genMinusDec :- does subtraction with decrement if possible     */
1151 /*-----------------------------------------------------------------*/
1152 bool genMinusDec (iCode *ic)
1153 {
1154         unsigned int icount ;
1155         unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1156         FENTRY;
1157         
1158         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1159         /* will try to generate an increment */
1160         /* if the right side is not a literal 
1161         we cannot */
1162         if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1163                 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1164                 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1165                 return FALSE ;
1166         
1167         DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1168         
1169         /* if the literal value of the right hand side
1170         is greater than 4 then it is not worth it */
1171         if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1172                 return FALSE ;
1173         
1174         /* if decrement 16 bits in register */
1175         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1176                 (size > 1) &&
1177                 (icount == 1)) {
1178                 
1179                 if(size == 2) { 
1180                         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1181                         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1182                         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1183                         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1184                         
1185                         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1186                         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1187                         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1188                 } else {
1189                         /* size is 3 or 4 */
1190                         emitpcode(POC_MOVLW,  popGetLit(0xff));
1191                         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1192                         emitSKPNC;
1193                         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1194                         emitSKPNC;
1195                         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1196                         
1197                         pic14_emitcode("movlw","0xff");
1198                         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1199                         
1200                         emitSKPNC;
1201                         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1202                         emitSKPNC;
1203                         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1204                         
1205                         if(size > 3) {
1206                                 emitSKPNC;
1207                                 emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1208                                 
1209                                 pic14_emitcode("skpnc","");
1210                                 emitSKPNC;
1211                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1212                         }
1213                         
1214                 }
1215                 
1216                 return TRUE;
1217                 
1218         }
1219         
1220         /* if the sizes are greater than 1 then we cannot */
1221         if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1222                 AOP_SIZE(IC_LEFT(ic)) > 1   )
1223                 return FALSE ;
1224         
1225         /* we can if the aops of the left & result match or
1226         if they are in registers and the registers are the
1227         same */
1228         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1229                 
1230                 while (icount--) 
1231                         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1232                 
1233                 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1234                 
1235                 return TRUE ;
1236         }
1237         
1238         DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1239                 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1240                 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1241         if(size==1) {
1242                 
1243                 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1244                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1245                 
1246                 emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1247                 emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1248                 
1249                 return TRUE;
1250         }
1251         
1252         return FALSE ;
1253 }
1254
1255 /*-----------------------------------------------------------------*/
1256 /* addSign - propogate sign bit to higher bytes                    */
1257 /*-----------------------------------------------------------------*/
1258 void addSign(operand *result, int offset, int sign)
1259 {
1260         int size = (pic14_getDataSize(result) - offset);
1261         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1262         FENTRY;
1263         
1264         if(size > 0){
1265                 if(sign && offset) {
1266                         
1267                         if(size == 1) {
1268                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1269                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1270                                 emitpcode(POC_DECF, popGet(AOP(result),offset));
1271                         } else {
1272                                 
1273                                 emitpcode(POC_MOVLW, popGetLit(0));
1274                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1275                                 emitpcode(POC_MOVLW, popGetLit(0xff));
1276                                 while(size--)
1277                                         emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
1278                         }
1279                 } else
1280                         while(size--)
1281                                 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1282         }
1283 }
1284
1285 /*-----------------------------------------------------------------*/
1286 /* genMinusBits - generates code for subtraction  of two bits      */
1287 /*-----------------------------------------------------------------*/
1288 void genMinusBits (iCode *ic)
1289 {
1290         symbol *lbl = newiTempLabel(NULL);
1291         FENTRY;
1292         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1293         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1294                 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1295                 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1296                 pic14_emitcode("cpl","c");
1297                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1298                 pic14_outBitC(IC_RESULT(ic));
1299         }
1300         else{
1301                 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1302                 pic14_emitcode("subb","a,acc");
1303                 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1304                 pic14_emitcode("inc","a");
1305                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1306                 aopPut(AOP(IC_RESULT(ic)),"a",0);
1307                 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1308         }
1309 }
1310
1311 /*-----------------------------------------------------------------*/
1312 /* genMinus - generates code for subtraction                       */
1313 /*-----------------------------------------------------------------*/
1314 void genMinus (iCode *ic)
1315 {
1316         int size, offset = 0, same=0;
1317         unsigned long lit = 0L;
1318         
1319         FENTRY;
1320         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1321         aopOp (IC_LEFT(ic),ic,FALSE);
1322         aopOp (IC_RIGHT(ic),ic,FALSE);
1323         aopOp (IC_RESULT(ic),ic,TRUE);
1324         
1325         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1326                 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1327                 operand *t = IC_RIGHT(ic);
1328                 IC_RIGHT(ic) = IC_LEFT(ic);
1329                 IC_LEFT(ic) = t;
1330         }
1331         
1332         DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1333                 AopType(AOP_TYPE(IC_RESULT(ic))),
1334                 AopType(AOP_TYPE(IC_LEFT(ic))),
1335                 AopType(AOP_TYPE(IC_RIGHT(ic))));
1336         
1337         /* special cases :- */
1338         /* if both left & right are in bit space */
1339         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1340                 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1341                 genPlusBits (ic);
1342                 goto release ;
1343         }
1344         
1345         /* if I can do an decrement instead
1346         of subtract then GOOD for ME */
1347         //  if (genMinusDec (ic) == TRUE)
1348         //    goto release;   
1349         
1350         size = pic14_getDataSize(IC_RESULT(ic));   
1351         same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1352         
1353         if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1354                 /* Add a literal to something else */
1355                 
1356                 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1357                 lit = - (long)lit;
1358                 
1359                 genAddLit ( ic,  lit);
1360                 
1361 #if 0
1362                 /* add the first byte: */
1363                 pic14_emitcode("movlw","0x%x", lit & 0xff);
1364                 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1365                 emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1366                 emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1367                 
1368                 
1369                 offset = 1;
1370                 size--;
1371                 
1372                 while(size-- > 0) {
1373                         
1374                         lit >>= 8;
1375                         
1376                         if(lit & 0xff) {
1377                                 
1378                                 if((lit & 0xff) == 0xff) {
1379                                         emitpcode(POC_MOVLW,  popGetLit(0xff));
1380                                         emitSKPC;
1381                                         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1382                                 } else {
1383                                         emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1384                                         emitSKPNC;
1385                                         emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1386                                         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1387                                 }
1388                                 
1389                         } else {
1390                                 /* do the rlf known zero trick here */
1391                                 emitpcode(POC_MOVLW,  popGetLit(1));
1392                                 emitSKPNC;
1393                                 emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1394                         }
1395                         offset++;
1396                 }
1397 #endif
1398         } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1399                 // bit subtraction
1400                 
1401                 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1402                 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1403                 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1404                 
1405                 /* here we are subtracting a bit from a char or int */
1406                 if(size == 1) {
1407                         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1408                                 
1409                                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1410                                 emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1411                                 
1412                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1413                                         AOP(IC_RIGHT(ic))->aopu.aop_dir,
1414                                         AOP(IC_RIGHT(ic))->aopu.aop_dir);
1415                                 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1416                         } else {
1417                                 
1418                                 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1419                                         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1420                                         emitpcode(POC_XORLW , popGetLit(1));
1421                                 }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1422                                         (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1423                                         
1424                                         lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1425                                         
1426                                         if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1427                                                 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1428                                                         if(lit & 1) {
1429                                                                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1430                                                                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1431                                                         }
1432                                                 }else{
1433                                                         emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1434                                                         if(lit & 1) 
1435                                                                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1436                                                         else
1437                                                                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1438                                                         emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1439                                                 }
1440                                                 goto release;
1441                                         } else {
1442                                                 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1443                                                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1444                                                 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1445                                                 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1446                                                 
1447                                         }
1448                                         
1449                                 } else {
1450                                         emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1451                                         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1452                                         emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1453                                 }
1454                                 
1455                                 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1456                                         
1457                                         emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1458                                         
1459                                 } else  {
1460                                         emitpcode(POC_ANDLW , popGetLit(1));
1461                                         /*
1462                                         emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1463                                         emitSKPZ;
1464                                         emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1465                                         */
1466                                 }
1467                                 
1468                         }
1469                         
1470                 }
1471         } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1472                 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1473                 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1474                 
1475                 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1476                 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1477                         AopType(AOP_TYPE(IC_RESULT(ic))),
1478                         AopType(AOP_TYPE(IC_LEFT(ic))),
1479                         AopType(AOP_TYPE(IC_RIGHT(ic))));
1480                 
1481                 
1482                 if( (size == 1) && ((lit & 0xff) == 0) ) {
1483                         /* res = 0 - right */
1484                         if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1485                                 emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1486                                 emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1487                         } else { 
1488                                 emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1489                                 emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1490                                 emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1491                         }
1492                         goto release;
1493                 }
1494                 
1495                 emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1496                 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1497                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1498                 
1499                 
1500                 offset = 1;
1501                 while(--size) {
1502                         lit >>= 8;
1503                         
1504                         if(size == 1) {
1505                         /* This is the last byte in a multibyte subtraction 
1506                         * There are a couple of tricks we can do by not worrying about 
1507                                 * propogating the carry */
1508                                 if(lit == 0xff) {
1509                                         /* 0xff - x == ~x */
1510                                         if(same) {
1511                                                 emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1512                                                 emitSKPC;
1513                                                 emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1514                                         } else {
1515                                                 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1516                                                 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1517                                                 emitSKPC;
1518                                                 emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1519                                         }
1520                                 } else {
1521                                         emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1522                                         emitSKPC;
1523                                         emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1524                                         emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1525                                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1526                                 }
1527                                 
1528                                 goto release;
1529                         }
1530                         
1531                         if(same) {
1532                                 
1533                                 if(lit & 0xff) {
1534                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1535                                         emitSKPC;
1536                                         emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1537                                         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1538                                 } else {
1539                                         emitSKPNC;
1540                                         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1541                                         
1542                                 }
1543                         } else {
1544                                 
1545                                 if(lit & 0xff) {
1546                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1547                                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1548                                 } else
1549                                         emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1550                                 
1551                                 emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1552                                 emitSKPC;
1553                                 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1554                                 emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1555                         }
1556                 }
1557                 
1558                 
1559         } else {
1560                 
1561                 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1562                         AopType(AOP_TYPE(IC_RESULT(ic))),
1563                         AopType(AOP_TYPE(IC_LEFT(ic))),
1564                         AopType(AOP_TYPE(IC_RIGHT(ic))));
1565                 
1566                 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1567                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1568                         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1569                         emitpcode(POC_SUBLW, popGetLit(0));
1570                         emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1571                 } else {
1572                         
1573                         if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1574                                 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1575                                 emitpcode(POC_SUBLW, popGetLit(0));
1576                                 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1577                                         emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1578                         } else {
1579                                 
1580                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1581                                 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1582                                         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1583                                 
1584                                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1585                                         emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1586                                 else {
1587                                         if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1588                                                 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1589                                                 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1590                                         } else {
1591                                                 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1592                                         }
1593                                         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1594                                                 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1595                                                         emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1596                                                         emitSKPZ;
1597                                                         emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1598                                                 }else
1599                                                         emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1600                                         }
1601                                 }
1602                         }
1603                 }
1604                 
1605                 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1606                 offset = 1;
1607                 
1608                 if(size){
1609                         if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1610                                 int lit = 0;
1611                                 if (op_isLitLike (IC_LEFT(ic)))
1612                                         lit = 1;
1613                                 while(size--){
1614                                         emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
1615                                         emitSKPC;
1616                                         emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1617                                         emitpcode(lit?POC_SUBLW:POC_SUBFW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1618                                         emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
1619                                         offset++;
1620                                 }
1621                         } else {
1622                                 PIC_OPCODE poc = POC_MOVFW;
1623                                 if (op_isLitLike (IC_LEFT(ic)))
1624                                         poc = POC_MOVLW;
1625                                 while(size--){
1626                                         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1627                                                 emitpcode(poc,  popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1628                                                 emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1629                                         }
1630                                         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1631                                         emitSKPC;
1632                                         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1633                                         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1634                                         offset++;
1635                                 }
1636                         }
1637                 }
1638         }
1639         
1640         //    adjustArithmeticResult(ic);
1641         
1642 release:
1643         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1644         freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1645         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1646 }
1647 /*-----------------------------------------------------------------*
1648 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1649
1650
1651 *-----------------------------------------------------------------*/
1652 void genUMult8XLit_16 (operand *left,
1653                                            operand *right,
1654                                            operand *result,
1655                                            pCodeOpReg *result_hi)
1656                                            
1657 {
1658         
1659         unsigned int lit;
1660         unsigned int i,have_first_bit;
1661         int same;
1662         pCodeOp *temp;
1663         
1664         FENTRY;
1665         if (AOP_TYPE(right) != AOP_LIT){
1666                 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1667                 exit(1);
1668         }
1669         
1670         
1671         if(!result_hi) {
1672                 result_hi = PCOR(popGet(AOP(result),1));
1673         }
1674         
1675         lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1676         lit &= 0xff;
1677         pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1678         
1679         same = pic14_sameRegs(AOP(left), AOP(result));
1680         
1681         if(same) {
1682                 switch(lit) {
1683                 case 0:
1684                         emitpcode(POC_CLRF,  popGet(AOP(left),0));
1685                         return;
1686                 case 2:
1687                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1688                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1689                         return;
1690                 case 3:
1691                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1692                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1693                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1694                         return;
1695                 case 4:
1696                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1697                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1698                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1699                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1700                         return;
1701                 case 5:
1702                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1703                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1704                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1705                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1706                         return;
1707                 case 6:
1708                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1709                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1710                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1712                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1713                         return;
1714                 case 7:
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                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
1720                         return;
1721                 case 8:
1722                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1723                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1724                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1725                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1726                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1727                         return;
1728                 case 9:
1729                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1730                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1731                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1732                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1733                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1734                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1735                         return;
1736                 case 10:
1737                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1738                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1739                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1740                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
1741                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1742                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1743                         return;
1744                 case 11:
1745                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1746                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1747                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1748                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1749                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1750                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
1751                         return;
1752                 case 12:
1753                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1754                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1755                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1756                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1757                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1758                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1759                         emitpcode(POC_ADDWF, popGet(AOP(left),0));
1760                         return;
1761                 case 13:
1762                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1763                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1764                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1765                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1766                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
1767                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
1768                         return;
1769                 case 14:
1770                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1771                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
1772                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
1773                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
1774                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
1775                         emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
1776                         emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
1777                         return;
1778                 case 15:
1779                         temp = popGetTempReg();
1780                         if(!temp) {
1781                                 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1782                                 exit(1);
1783                         }
1784                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1785                         emitpcode(POC_MOVWF,  temp);
1786                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
1787                         emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1788                         emitpcode(POC_SWAPFW, temp);
1789                         emitpcode(POC_SUBWF,  popGet(AOP(left),0));
1790                         popReleaseTempReg(temp);
1791                         return;
1792                 case 16:
1793                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1794                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
1795                         emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1796                         return;
1797                 case 17:
1798                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1799                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
1800                         emitpcode(POC_ADDWF,  popGet(AOP(left),0));
1801                         return;
1802                 case 32:
1803                         emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1804                         emitpcode(POC_RLFW,   popGet(AOP(left),0));
1805                         emitpcode(POC_ANDLW,  popGetLit(0xe0));
1806                         emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1807                         return;
1808                 case 64:
1809                         emitpcode(POC_SWAPF,  popGet(AOP(left),0));
1810                         emitpcode(POC_RLF,    popGet(AOP(left),0));
1811                         emitpcode(POC_RLFW,   popGet(AOP(left),0));
1812                         emitpcode(POC_ANDLW,  popGetLit(0xc0));
1813                         emitpcode(POC_MOVWF,  popGet(AOP(left),0));
1814                         return;
1815                 case 128:
1816                         emitpcode(POC_RRFW,   popGet(AOP(left),0));
1817                         emitpcode(POC_CLRF,   popGet(AOP(left),0));
1818                         emitpcode(POC_RRF,    popGet(AOP(left),0));
1819                         return;
1820                         
1821                 }
1822         } else {
1823                 
1824                 switch(lit) {
1825                 case 0:
1826                         emitpcode(POC_CLRF,  popGet(AOP(result),0));
1827                         emitpcode(POC_CLRF,  popCopyReg(result_hi));
1828                         return;
1829                 case 2:
1830                         if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1831                                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1832                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
1833                         emitpcode(POC_ADDWF, popGet(AOP(result),0));
1834                         emitpcode(POC_CLRF,  popCopyReg(result_hi));
1835                         emitpcode(POC_RLF,   popCopyReg(result_hi));
1836                         return;
1837                 case 4:
1838                 case 8:
1839                         if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1840                                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1841                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
1842                         emitpcode(POC_CLRF,  popCopyReg(result_hi));
1843                         emitpcode(POC_BCF,   popCopyReg(&pc_status));
1844                         emitpcode(POC_RLF,   popGet(AOP(result),0));
1845                         emitpcode(POC_RLF,   popCopyReg(result_hi));
1846                         emitpcode(POC_RLF,   popGet(AOP(result),0));
1847                         emitpcode(POC_RLF,   popCopyReg(result_hi));
1848                         if (lit >= 8) {
1849                                 emitpcode(POC_RLF,   popGet(AOP(result),0));
1850                                 emitpcode(POC_RLF,   popCopyReg(result_hi));
1851                         }
1852                         return;
1853                 }
1854                 
1855         }
1856         
1857         if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1858                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1859         emitpcode(POC_CLRF,  popGet(AOP(result),0));
1860         emitpcode(POC_CLRF,  popCopyReg(result_hi));
1861
1862         have_first_bit = 0;
1863         for(i=0; i<8; i++) {
1864                 
1865                 if(lit & 1) {
1866                         emitpcode(POC_ADDWF, popCopyReg(result_hi));
1867                         have_first_bit = 1;
1868                 }
1869                 
1870                 if(have_first_bit) {
1871                         emitpcode(POC_RRF,   popCopyReg(result_hi));
1872                         emitpcode(POC_RRF,   popGet(AOP(result),0));
1873                 }
1874                 
1875                 lit >>= 1;
1876         }
1877 }
1878
1879 /*-----------------------------------------------------------------*
1880 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1881
1882
1883 *-----------------------------------------------------------------*/
1884 void genUMult8X8_16 (operand *left,
1885                                          operand *right,
1886                                          operand *result,
1887                                          pCodeOpReg *result_hi)
1888                                          
1889 {
1890         
1891         int i;
1892         int looped = 1;
1893         
1894         FENTRY;
1895         if(!result_hi) {
1896                 result_hi = PCOR(popGet(AOP(result),1));
1897         }
1898         
1899         if (AOP_TYPE(right) == AOP_LIT) {
1900                 genUMult8XLit_16(left,right,result,result_hi);
1901                 return;
1902         }
1903         
1904         if(!looped) {
1905                 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1906                 
1907                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1908                 emitpcode(POC_CLRF,  popGet(AOP(result),0));
1909                 emitpcode(POC_CLRF,  popCopyReg(result_hi));
1910                 emitCLRC;
1911                 
1912                 for(i=0; i<8; i++) {
1913                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1914                         emitpcode(POC_ADDWF, popCopyReg(result_hi));
1915                         emitpcode(POC_RRF,   popCopyReg(result_hi));
1916                         emitpcode(POC_RRF,   popGet(AOP(result),0));
1917                 }
1918                 
1919                 
1920                 /*
1921                 Here's another version that does the same thing and takes the 
1922                 same number of instructions. The one above is slightly better
1923                 because the entry instructions have a higher probability of
1924                 being optimized out.
1925                 */
1926                 /*
1927                 emitpcode(POC_CLRF,  popCopyReg(result_hi));
1928                 emitpcode(POC_RRFW,  popGet(AOP(left),0));
1929                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1930                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1931                 
1932                   for(i=0; i<8; i++) {
1933                   emitSKPNC;
1934                   emitpcode(POC_ADDWF, popCopyReg(result_hi));
1935                   emitpcode(POC_RRF,   popCopyReg(result_hi));
1936                   emitpcode(POC_RRF,   popGet(AOP(result),0));
1937                   }
1938                 */
1939                 
1940         } else {
1941                 symbol  *tlbl = newiTempLabel(NULL);
1942                 pCodeOp *temp;
1943                 
1944                 
1945                 pic14_emitcode(";","Looped 8 X 8 multiplication");
1946                 
1947                 emitpcode(POC_CLRF,  popGet(AOP(result),0));
1948                 emitpcode(POC_CLRF,  popCopyReg(result_hi));
1949                 
1950                 emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1951                 
1952                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1953                 
1954                 temp = popGetTempReg();
1955                 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1956                 
1957                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1958                 
1959                 emitpLabel(tlbl->key);
1960                 
1961                 emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1962                 emitSKPNC;
1963                 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1964                 
1965                 emitpcode(POC_RRF,   popCopyReg(result_hi));
1966                 emitpcode(POC_RRF,   popGet(AOP(result),0));
1967                 
1968                 emitSKPC;
1969                 emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1970                 
1971                 popReleaseTempReg(temp);
1972                 
1973         }
1974 }
1975
1976 /*-----------------------------------------------------------------*
1977 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1978 *
1979 *  this routine will call the unsigned multiply routine and then
1980 * post-fix the sign bit.
1981 *-----------------------------------------------------------------*/
1982 void genSMult8X8_16 (operand *left,
1983                                          operand *right,
1984                                          operand *result,
1985                                          pCodeOpReg *result_hi)
1986 {
1987         
1988         FENTRY;
1989         if(!result_hi) {
1990                 result_hi = PCOR(popGet(AOP(result),1));
1991         }
1992         
1993         genUMult8X8_16(left,right,result,result_hi);
1994         
1995         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1996         emitpcode(POC_SUBWF, popCopyReg(result_hi));
1997         emitpcode(POC_MOVFW, popGet(AOP(left),0));
1998         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1999         emitpcode(POC_SUBWF, popGet(AOP(result),1));
2000         
2001 }
2002
2003 /*-----------------------------------------------------------------*
2004 * genMult8X8_8 - multiplication of two 8-bit numbers
2005 *
2006 *  this routine will call the unsigned multiply 8X8=>16 routine and
2007 * then throw away the high byte of the result.
2008 *
2009 *-----------------------------------------------------------------*/
2010 void genMult8X8_8 (operand *left,
2011                                    operand *right,
2012                                    operand *result)
2013 {
2014         pCodeOp *result_hi;
2015         FENTRY;
2016         if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
2017                 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. */
2018         }
2019         result_hi = popGetTempReg();
2020         
2021         if (AOP_TYPE(right) == AOP_LIT)
2022                 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2023         else
2024                 genUMult8X8_16(left,right,result,PCOR(result_hi));
2025         
2026         popReleaseTempReg(result_hi);
2027 }
2028 #if 0
2029 /*-----------------------------------------------------------------*/
2030 /* constMult - generates code for multiplication by a constant     */
2031 /*-----------------------------------------------------------------*/
2032 void genMultConst(unsigned C)
2033 {
2034         
2035         unsigned lit;
2036         unsigned sr3; // Shift right 3
2037         unsigned mask;
2038         
2039         int size = 1;
2040         
2041         /*
2042         Convert a string of 3 binary 1's in the lit into
2043         0111 = 1000 - 1;
2044         */
2045         
2046         mask = 7 << ( (size*8) - 3);
2047         lit = C;
2048         sr3 = 0;
2049         
2050         while(mask < (1<<size*8)) {
2051                 
2052                 if( (mask & lit) == lit) {
2053                         unsigned lsb;
2054                         
2055                         /* We found 3 (or more) consecutive 1's */
2056                         
2057                         lsb = mask & ~(mask & (mask-1));  // lsb of mask.
2058                         
2059                         consecutive_bits = ((lit + lsb) & lit) ^ lit;
2060                         
2061                         lit ^= consecutive_bits;
2062                         
2063                         mask <<= 3;
2064                         
2065                         sr3 |= (consecutive + lsb);
2066                         
2067                 }
2068                 
2069                 mask >>= 1;
2070                 
2071         }
2072         
2073 }
2074
2075 #endif