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