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