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