1741ad978be83da47c3551c1e7df64ca41ed8027
[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)
40 #define __FUNCTION__            __FILE__
41 #endif
42
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
45 #else
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
48 #else
49 #ifdef HAVE_ENDIAN_H
50 #include <endian.h>
51 #else
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
55 #endif
56 #endif
57 #endif
58 #endif
59
60 #include "common.h"
61 #include "SDCCpeeph.h"
62 #include "ralloc.h"
63 #include "pcode.h"
64 #include "gen.h"
65
66
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
69
70 const char *AopType(short type)
71 {
72   switch(type) {
73   case AOP_LIT:
74     return "AOP_LIT";
75     break;
76   case AOP_REG:
77     return "AOP_REG";
78     break;
79   case AOP_DIR:
80     return "AOP_DIR";
81     break;
82   case AOP_DPTR:
83     return "AOP_DPTR";
84     break;
85   case AOP_DPTR2:
86     return "AOP_DPTR2";
87     break;
88   case AOP_R0:
89     return "AOP_R0";
90     break;
91   case AOP_R1:
92     return "AOP_R1";
93     break;
94   case AOP_STK:
95     return "AOP_STK";
96     break;
97   case AOP_IMMD:
98     return "AOP_IMMD";
99     break;
100   case AOP_STR:
101     return "AOP_STR";
102     break;
103   case AOP_CRY:
104     return "AOP_CRY";
105     break;
106   case AOP_ACC:
107     return "AOP_ACC";
108     break;
109   case AOP_PCODE:
110     return "AOP_PCODE";
111     break;
112   }
113
114   return "BAD TYPE";
115 }
116 /*-----------------------------------------------------------------*/
117 /* genPlusIncr :- does addition with increment if possible         */
118 /*-----------------------------------------------------------------*/
119 bool genPlusIncr (iCode *ic)
120 {
121     unsigned int icount ;
122     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
123
124     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
125     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
126                          AopType(AOP_TYPE(IC_RESULT(ic))),
127                          AopType(AOP_TYPE(IC_LEFT(ic))),
128                          AopType(AOP_TYPE(IC_RIGHT(ic))));
129
130     /* will try to generate an increment */
131     /* if the right side is not a literal 
132        we cannot */
133     if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
134         return FALSE ;
135     
136     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
137     /* if the literal value of the right hand side
138        is greater than 1 then it is faster to add */
139     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
140         return FALSE ;
141     
142     /* if increment 16 bits in register */
143     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
144         (icount == 1)) {
145
146       int offset = MSB16;
147
148       emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
149       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
150
151       while(--size) {
152         emitSKPNZ;
153         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
154         //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
155       }
156
157       return TRUE;
158     }
159     
160     DEBUGpic14_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
161     /* if left is in accumulator  - probably a bit operation*/
162     if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a")  &&
163         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
164       
165       emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
166       pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
167                AOP(IC_RESULT(ic))->aopu.aop_dir,
168                AOP(IC_RESULT(ic))->aopu.aop_dir);
169       if(icount)
170         emitpcode(POC_XORLW,popGetLit(1));
171       //pic14_emitcode("xorlw","1");
172       else
173         emitpcode(POC_ANDLW,popGetLit(1));
174       //pic14_emitcode("andlw","1");
175
176       emitSKPZ;
177       emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
178       pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
179                AOP(IC_RESULT(ic))->aopu.aop_dir,
180                AOP(IC_RESULT(ic))->aopu.aop_dir);
181
182       return TRUE;
183     }
184
185
186
187     /* if the sizes are greater than 1 then we cannot */
188     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
189         AOP_SIZE(IC_LEFT(ic)) > 1   )
190         return FALSE ;
191     
192     /* If we are incrementing the same register by two: */
193
194     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
195         
196       while (icount--) 
197         emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
198       //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
199         
200       return TRUE ;
201     }
202     
203     DEBUGpic14_emitcode ("; ","couldn't increment ");
204
205     return FALSE ;
206 }
207
208 /*-----------------------------------------------------------------*/
209 /* pic14_outBitAcc - output a bit in acc                                 */
210 /*-----------------------------------------------------------------*/
211 void pic14_outBitAcc(operand *result)
212 {
213     symbol *tlbl = newiTempLabel(NULL);
214     /* if the result is a bit */
215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
216
217     if (AOP_TYPE(result) == AOP_CRY){
218         aopPut(AOP(result),"a",0);
219     }
220     else {
221         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
222         pic14_emitcode("mov","a,#01");
223         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
224         pic14_outAcc(result);
225     }
226 }
227
228 /*-----------------------------------------------------------------*/
229 /* genPlusBits - generates code for addition of two bits           */
230 /*-----------------------------------------------------------------*/
231 void genPlusBits (iCode *ic)
232 {
233
234   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
235
236   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
237                        AopType(AOP_TYPE(IC_RESULT(ic))),
238                        AopType(AOP_TYPE(IC_LEFT(ic))),
239                        AopType(AOP_TYPE(IC_RIGHT(ic))));
240   /*
241     The following block of code will add two bits. 
242     Note that it'll even work if the destination is
243     the carry (C in the status register).
244     It won't work if the 'Z' bit is a source or destination.
245   */
246
247   /* If the result is stored in the accumulator (w) */
248   //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
249   switch(AOP_TYPE(IC_RESULT(ic))) {
250   case AOP_ACC:
251     emitpcode(POC_CLRW, NULL);
252     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
253     emitpcode(POC_XORLW, popGetLit(1));
254     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
255     emitpcode(POC_XORLW, popGetLit(1));
256
257     pic14_emitcode("clrw","");
258     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
259                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
260                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
261     pic14_emitcode("xorlw","1");
262     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
263                    AOP(IC_LEFT(ic))->aopu.aop_dir,
264                    AOP(IC_LEFT(ic))->aopu.aop_dir);
265     pic14_emitcode("xorlw","1");
266     break;
267   case AOP_REG:
268     emitpcode(POC_MOVLW, popGetLit(0));
269     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
270     emitpcode(POC_XORLW, popGetLit(1));
271     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
272     emitpcode(POC_XORLW, popGetLit(1));
273     emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
274     break;
275   default:
276     emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
277     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
278     emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
279     emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
280     emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
281     emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
282
283     pic14_emitcode("movlw","(1 << (%s & 7))",
284                    AOP(IC_RESULT(ic))->aopu.aop_dir,
285                    AOP(IC_RESULT(ic))->aopu.aop_dir);
286     pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
287                    AOP(IC_RESULT(ic))->aopu.aop_dir,
288                    AOP(IC_RESULT(ic))->aopu.aop_dir);
289     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
290                    AOP(IC_RIGHT(ic))->aopu.aop_dir,
291                    AOP(IC_RIGHT(ic))->aopu.aop_dir);
292     pic14_emitcode("xorwf","(%s >>3),f",
293                    AOP(IC_RESULT(ic))->aopu.aop_dir);
294     pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
295                    AOP(IC_LEFT(ic))->aopu.aop_dir,
296                    AOP(IC_LEFT(ic))->aopu.aop_dir);
297     pic14_emitcode("xorwf","(%s>>3),f",
298                    AOP(IC_RESULT(ic))->aopu.aop_dir);
299     break;
300   }
301
302 }
303
304 #if 0
305 /* This is the original version of this code.
306  *
307  * This is being kept around for reference, 
308  * because I am not entirely sure I got it right...
309  */
310 static void adjustArithmeticResult(iCode *ic)
311 {
312     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
313         AOP_SIZE(IC_LEFT(ic)) == 3   &&
314         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
315         aopPut(AOP(IC_RESULT(ic)),
316                aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
317                2);
318
319     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
320         AOP_SIZE(IC_RIGHT(ic)) == 3   &&
321         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
322         aopPut(AOP(IC_RESULT(ic)),
323                aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
324                2);
325     
326     if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
327         AOP_SIZE(IC_LEFT(ic)) < 3    &&
328         AOP_SIZE(IC_RIGHT(ic)) < 3   &&
329         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
330         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
331         char buffer[5];
332         sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
333         aopPut(AOP(IC_RESULT(ic)),buffer,2);
334     }
335 }
336 //#else
337 /* This is the pure and virtuous version of this code.
338  * I'm pretty certain it's right, but not enough to toss the old 
339  * code just yet...
340  */
341 static void adjustArithmeticResult(iCode *ic)
342 {
343     if (opIsGptr(IC_RESULT(ic)) &&
344         opIsGptr(IC_LEFT(ic))   &&
345         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
346     {
347         aopPut(AOP(IC_RESULT(ic)),
348                aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
349                GPTRSIZE - 1);
350     }
351
352     if (opIsGptr(IC_RESULT(ic)) &&
353         opIsGptr(IC_RIGHT(ic))   &&
354         !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
355     {
356         aopPut(AOP(IC_RESULT(ic)),
357                aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
358                GPTRSIZE - 1);
359     }
360
361     if (opIsGptr(IC_RESULT(ic))            &&
362         AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
363         AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
364          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
365          !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
366          char buffer[5];
367          sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
368          aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
369      }
370 }
371 #endif
372
373 /*-----------------------------------------------------------------*/
374 /* genAddlit - generates code for addition                         */
375 /*-----------------------------------------------------------------*/
376 static void genAddLit2byte (operand *result, int offr, int lit)
377 {
378
379   switch(lit & 0xff) {
380   case 0:
381     break;
382   case 1:
383     emitpcode(POC_INCF, popGet(AOP(result),offr));
384     break;
385   case 0xff:
386     emitpcode(POC_DECF, popGet(AOP(result),offr));
387     break;
388   default:
389     emitpcode(POC_MOVLW,popGetLit(lit&0xff));
390     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
391   }
392
393 }
394
395 static void emitMOVWF(operand *reg, int offset)
396 {
397   if(!reg)
398     return;
399
400   if (AOP_TYPE(reg) == AOP_ACC) {
401     DEBUGpic14_emitcode ("; ***","%s  %d ignoring mov into W",__FUNCTION__,__LINE__);
402     return;
403   }
404
405   emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
406
407 }
408
409 static void genAddLit (iCode *ic, int lit)
410 {
411
412   int size,same;
413   int lo;
414
415   operand *result;
416   operand *left;
417
418   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
419
420
421   left = IC_LEFT(ic);
422   result = IC_RESULT(ic);
423   same = pic14_sameRegs(AOP(left), AOP(result));
424   size = pic14_getDataSize(result);
425
426   if(same) {
427
428     /* Handle special cases first */
429     if(size == 1) 
430       genAddLit2byte (result, 0, lit);
431      
432     else if(size == 2) {
433       int hi = 0xff & (lit >> 8);
434       lo = lit & 0xff;
435
436       switch(hi) {
437       case 0: 
438
439         /* lit = 0x00LL */
440         DEBUGpic14_emitcode ("; hi = 0","%s  %d",__FUNCTION__,__LINE__);
441         switch(lo) {
442         case 0:
443           break;
444         case 1:
445           emitpcode(POC_INCF, popGet(AOP(result),0));
446           emitSKPNZ;
447           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
448           break;
449         case 0xff:
450           emitpcode(POC_DECF, popGet(AOP(result),0));
451           emitpcode(POC_INCFSZW, popGet(AOP(result),0));
452           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
453
454           break;
455         default:
456           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
457           emitpcode(POC_ADDWF,popGet(AOP(result),0));
458           emitSKPNC;
459           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
460
461
462         }
463         break;
464
465       case 1:
466         /* lit = 0x01LL */
467         DEBUGpic14_emitcode ("; hi = 1","%s  %d",__FUNCTION__,__LINE__);
468         switch(lo) {
469         case 0:  /* 0x0100 */
470           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
471           break;
472         case 1:  /* 0x0101  */
473           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
474           emitpcode(POC_INCF, popGet(AOP(result),0));
475           emitSKPNZ;
476           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
477           break;
478         case 0xff: /* 0x01ff */
479           emitpcode(POC_DECF, popGet(AOP(result),0));
480           emitpcode(POC_INCFSZW, popGet(AOP(result),0));
481           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
482           emitpcode(POC_INCF, popGet(AOP(result),MSB16));
483         }         
484         break;
485
486       case 0xff:
487         DEBUGpic14_emitcode ("; hi = ff","%s  %d",__FUNCTION__,__LINE__);
488         /* lit = 0xffLL */
489         switch(lo) {
490         case 0:  /* 0xff00 */
491           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
492           break;
493         case 1:  /*0xff01 */
494           emitpcode(POC_INCFSZ, popGet(AOP(result),0));
495           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
496           break;
497 /*      case 0xff: * 0xffff *
498           emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
499           emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
500           emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
501           break;
502 */
503         default:
504           emitpcode(POC_MOVLW,popGetLit(lo));
505           emitpcode(POC_ADDWF,popGet(AOP(result),0));
506           emitSKPC;
507           emitpcode(POC_DECF, popGet(AOP(result),MSB16));
508           
509         }
510
511         break;
512         
513       default:
514         DEBUGpic14_emitcode ("; hi is generic","%d   %s  %d",hi,__FUNCTION__,__LINE__);
515
516         /* lit = 0xHHLL */
517         switch(lo) {
518         case 0:  /* 0xHH00 */
519           genAddLit2byte (result, MSB16, hi);
520           break;
521         case 1:  /* 0xHH01 */
522           emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
523           emitpcode(POC_INCFSZ, popGet(AOP(result),0));
524           emitpcode(POC_MOVLW,popGetLit(hi));
525           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
526           break;
527 /*      case 0xff: * 0xHHff *
528           emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
529           emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
530           emitpcode(POC_MOVLW,popGetLit(hi));
531           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
532           break;
533 */      default:  /* 0xHHLL */
534           emitpcode(POC_MOVLW,popGetLit(lo));
535           emitpcode(POC_ADDWF, popGet(AOP(result),0));
536           emitpcode(POC_MOVLW,popGetLit(hi));
537           emitSKPNC;
538           emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
539           emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
540           break;
541         }
542
543       }
544     } else {
545       int carry_info = 0;
546       int offset = 0;
547       /* size > 2 */
548       DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
549
550       while(size--) {
551         lo = BYTEofLONG(lit,0);
552
553         if(carry_info) {
554           switch(lo) {
555           case 0:
556             switch(carry_info) {
557             case 1:
558               emitSKPNZ;
559               emitpcode(POC_INCF, popGet(AOP(result),offset));
560               break;
561             case 2:
562               emitpcode(POC_RLFW, popGet(AOP(result),offset));
563               emitpcode(POC_ANDLW,popGetLit(1));
564               emitpcode(POC_ADDWF, popGet(AOP(result),offset));
565               break;
566             default: /* carry_info = 3  */
567               emitSKPNC;
568               emitpcode(POC_INCF, popGet(AOP(result),offset));
569               carry_info = 1;
570               break;
571             }
572             break;
573           case 0xff:
574             emitpcode(POC_MOVLW,popGetLit(lo));
575             if(carry_info==1) 
576               emitSKPZ;
577             else
578               emitSKPC;
579             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
580             break;
581           default:
582             emitpcode(POC_MOVLW,popGetLit(lo));
583             if(carry_info==1) 
584               emitSKPNZ;
585             else
586               emitSKPNC;
587             emitpcode(POC_MOVLW,popGetLit(lo+1));
588             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
589             carry_info=2;
590             break;
591           }
592         }else {
593           /* no carry info from previous step */
594           /* this means this is the first time to add */
595           switch(lo) {
596           case 0:
597             break;
598           case 1:
599             emitpcode(POC_INCF, popGet(AOP(result),offset));
600             carry_info=1;
601             break;
602           default:
603             emitpcode(POC_MOVLW,popGetLit(lo));
604             emitpcode(POC_ADDWF, popGet(AOP(result),offset));
605             if(lit <0x100) 
606               carry_info = 3;  /* Were adding only one byte and propogating the carry */
607             else
608               carry_info = 2;
609             break;
610           }
611         }
612         offset++;
613         lit >>= 8;
614       }
615     
616 /*
617       lo = BYTEofLONG(lit,0);
618
619       if(lit < 0x100) {
620         if(lo) {
621           if(lo == 1) {
622             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
623             emitSKPNZ;
624           } else {
625             emitpcode(POC_MOVLW,popGetLit(lo));
626             emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
627             emitSKPNC;
628           }
629           emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
630           emitSKPNZ;
631           emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
632           emitSKPNZ;
633           emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
634
635         } 
636       } 
637     }
638
639 */
640     }
641   } else {
642     int offset = 1;
643     DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
644
645     if(size == 1) {
646
647       if(AOP_TYPE(left) == AOP_ACC) {
648         /* left addend is already in accumulator */
649         switch(lit & 0xff) {
650         case 0:
651           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
652           emitMOVWF(result,0);
653           break;
654         default:
655           emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
656           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
657           emitMOVWF(result,0);
658         }
659       } else {
660         /* left addend is in a register */
661         switch(lit & 0xff) {
662         case 0:
663           emitpcode(POC_MOVFW, popGet(AOP(left),0));
664           emitMOVWF(result, 0);
665           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
666           emitMOVWF(result,0);
667           break;
668         case 1:
669           emitpcode(POC_INCFW, popGet(AOP(left),0));
670           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
671           emitMOVWF(result,0);
672           break;
673         case 0xff:
674           emitpcode(POC_DECFW, popGet(AOP(left),0));
675           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
676           emitMOVWF(result,0);
677           break;
678         default:
679           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
680           emitpcode(POC_ADDFW, popGet(AOP(left),0));
681           //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
682           emitMOVWF(result,0);
683         }
684       }
685
686     } else {
687
688       /* left is not the accumulator */
689       if(lit & 0xff) {
690         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
691         emitpcode(POC_ADDFW, popGet(AOP(left),0));
692       } else
693         emitpcode(POC_MOVFW, popGet(AOP(left),0));
694
695       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
696       emitMOVWF(result,0);
697       lit >>= 8;
698       while(--size) {
699       
700         if(lit & 0xff) {
701           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
702           //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
703           emitMOVWF(result,offset);
704           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
705           emitSKPNC;
706           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
707           emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
708         } else {
709           emitpcode(POC_CLRF,  popGet(AOP(result),offset));
710           emitpcode(POC_RLF,   popGet(AOP(result),offset));
711           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
712           emitpcode(POC_ADDWF, popGet(AOP(result),offset));
713         }
714       offset++;
715       }
716     }
717   }
718 }
719
720 /*-----------------------------------------------------------------*/
721 /* genPlus - generates code for addition                           */
722 /*-----------------------------------------------------------------*/
723 void genPlus (iCode *ic)
724 {
725   int size, offset = 0;
726
727   /* special cases :- */
728   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
729
730   aopOp (IC_LEFT(ic),ic,FALSE);
731   aopOp (IC_RIGHT(ic),ic,FALSE);
732   aopOp (IC_RESULT(ic),ic,TRUE);
733
734   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
735
736   /* if literal, literal on the right or
737      if left requires ACC or right is already
738      in ACC */
739
740   if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
741     operand *t = IC_RIGHT(ic);
742     IC_RIGHT(ic) = IC_LEFT(ic);
743     IC_LEFT(ic) = t;
744   }
745
746   /* if both left & right are in bit space */
747   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
748       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
749     genPlusBits (ic);
750     goto release ;
751   }
752
753   /* if left in bit space & right literal */
754   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
755       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
756     /* if result in bit space */
757     if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
758       if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
759         emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
760         if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
761           emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
762         emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
763       }
764     } else {
765       size = pic14_getDataSize(IC_RESULT(ic));
766       while (size--) {
767         MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));  
768         pic14_emitcode("addc","a,#00  ;%d",__LINE__);
769         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
770       }
771     }
772     goto release ;
773   }
774
775   /* if I can do an increment instead
776      of add then GOOD for ME */
777   if (genPlusIncr (ic) == TRUE)
778     goto release;   
779
780   size = pic14_getDataSize(IC_RESULT(ic));
781
782   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
783     /* Add a literal to something else */
784     //bool know_W=0;
785     unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
786     //      unsigned l1=0;
787
788     //      offset = 0;
789     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
790
791     genAddLit (ic,  lit);
792     goto release;
793
794   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
795
796     pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
797     pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
798     pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
799
800     /* here we are adding a bit to a char or int */
801     if(size == 1) {
802       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
803
804         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
805         emitpcode(POC_INCF ,  popGet(AOP(IC_RESULT(ic)),0));
806
807         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
808                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
809                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
810         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
811       } else {
812
813         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
814           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
815           emitpcode(POC_XORLW , popGetLit(1));
816
817           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
818                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
819                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
820           pic14_emitcode(" xorlw","1");
821         } else {
822           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
823           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
824           emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
825
826           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
827           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
828                          AOP(IC_RIGHT(ic))->aopu.aop_dir,
829                          AOP(IC_RIGHT(ic))->aopu.aop_dir);
830           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
831         }
832           
833         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
834             
835           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
836             emitpcode(POC_ANDLW , popGetLit(1));
837             emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
838             emitSKPZ;
839             emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
840           } else {
841             emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
842             pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
843           }
844         }
845       }
846
847     } else {
848       int offset = 1;
849       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
850       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
851         emitCLRZ;
852         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
853         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
854
855         pic14_emitcode("clrz","");
856
857         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
858                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
859                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
860         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
861
862       } else {
863
864         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
865         emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
866         emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
867         //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
868         emitMOVWF(IC_RIGHT(ic),0);
869
870         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
871         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
872                        AOP(IC_RIGHT(ic))->aopu.aop_dir,
873                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
874         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
875         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
876
877       }
878
879       while(--size){
880         emitSKPZ;
881         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),offset++));
882         //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
883       }
884
885     }
886       
887   } else {
888     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
889
890     /* Add the first bytes */
891
892     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
893       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
894       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
895     } else {
896
897       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
898         emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
899         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
900           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
901       } else {
902
903         emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
904
905         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
906           emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
907         else {
908           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
909               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
910             emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
911           } else {
912             emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
913             if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
914               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
915           }
916         }
917       }
918     }
919
920     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
921     offset = 1;
922
923
924     while(size--){
925       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
926         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
927         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
928
929         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
930         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
931       }
932
933       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
934       emitSKPNC;
935       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
936       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
937
938       /*
939         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
940         emitSKPNC;
941         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
942         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
943       */
944
945       offset++;
946     }
947
948   }
949
950   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
951     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
952                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
953
954
955     /* Need to extend result to higher bytes */
956     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
957
958     /* First grab the carry from the lower bytes */
959     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
960     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
961
962
963     if(sign) {
964       /* Now this is really horrid. Gotta check the sign of the addends and propogate
965        * to the result */
966
967       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
968       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
969       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
970       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
971
972       /* if chars or ints or being signed extended to longs: */
973       if(size) {
974         emitpcode(POC_MOVLW, popGetLit(0));
975         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
976         emitpcode(POC_MOVLW, popGetLit(0xff));
977       }
978     }
979
980     offset++;
981     while(size--) {
982       
983       if(sign)
984         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
985       else
986         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
987
988       offset++;
989     }
990   }
991
992
993   //adjustArithmeticResult(ic);
994
995  release:
996   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
997   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
998   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
999 }
1000
1001 /*-----------------------------------------------------------------*/
1002 /* genMinusDec :- does subtraction with decrement if possible     */
1003 /*-----------------------------------------------------------------*/
1004 bool genMinusDec (iCode *ic)
1005 {
1006     unsigned int icount ;
1007     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1008
1009     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1010     /* will try to generate an increment */
1011     /* if the right side is not a literal 
1012     we cannot */
1013     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1014         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1015         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1016         return FALSE ;
1017
1018     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1019
1020     /* if the literal value of the right hand side
1021     is greater than 4 then it is not worth it */
1022     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1023         return FALSE ;
1024
1025     /* if decrement 16 bits in register */
1026     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1027         (size > 1) &&
1028         (icount == 1)) {
1029
1030       if(size == 2) { 
1031         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1032         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1033         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1034         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1035
1036         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1037         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1038         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1039       } else {
1040         /* size is 3 or 4 */
1041         emitpcode(POC_MOVLW,  popGetLit(0xff));
1042         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1043         emitSKPNC;
1044         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1045         emitSKPNC;
1046         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1047
1048         pic14_emitcode("movlw","0xff");
1049         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1050
1051         emitSKPNC;
1052         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1053         emitSKPNC;
1054         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1055
1056         if(size > 3) {
1057           emitSKPNC;
1058           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1059
1060           pic14_emitcode("skpnc","");
1061           emitSKPNC;
1062           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1063         }
1064
1065       }
1066
1067       return TRUE;
1068
1069     }
1070
1071     /* if the sizes are greater than 1 then we cannot */
1072     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1073         AOP_SIZE(IC_LEFT(ic)) > 1   )
1074         return FALSE ;
1075
1076     /* we can if the aops of the left & result match or
1077     if they are in registers and the registers are the
1078     same */
1079     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1080
1081       while (icount--) 
1082         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1083
1084         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1085
1086         return TRUE ;
1087     }
1088
1089     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1090                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1091                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1092     if(size==1) {
1093
1094       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1095       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1096
1097       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1098       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1099
1100       return TRUE;
1101     }
1102
1103     return FALSE ;
1104 }
1105
1106 /*-----------------------------------------------------------------*/
1107 /* addSign - complete with sign                                    */
1108 /*-----------------------------------------------------------------*/
1109 void addSign(operand *result, int offset, int sign)
1110 {
1111     int size = (pic14_getDataSize(result) - offset);
1112     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1113     if(size > 0){
1114         if(sign){
1115             pic14_emitcode("rlc","a");
1116             pic14_emitcode("subb","a,acc");
1117             while(size--)
1118                 aopPut(AOP(result),"a",offset++); 
1119         } else
1120             while(size--)
1121                 aopPut(AOP(result),"#0",offset++);
1122     }
1123 }
1124
1125 /*-----------------------------------------------------------------*/
1126 /* genMinusBits - generates code for subtraction  of two bits      */
1127 /*-----------------------------------------------------------------*/
1128 void genMinusBits (iCode *ic)
1129 {
1130     symbol *lbl = newiTempLabel(NULL);
1131     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1132     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1133         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1134         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1135         pic14_emitcode("cpl","c");
1136         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1137         pic14_outBitC(IC_RESULT(ic));
1138     }
1139     else{
1140         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1141         pic14_emitcode("subb","a,acc");
1142         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1143         pic14_emitcode("inc","a");
1144         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1145         aopPut(AOP(IC_RESULT(ic)),"a",0);
1146         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1147     }
1148 }
1149
1150 /*-----------------------------------------------------------------*/
1151 /* genMinus - generates code for subtraction                       */
1152 /*-----------------------------------------------------------------*/
1153 void genMinus (iCode *ic)
1154 {
1155   int size, offset = 0, same=0;
1156   unsigned long lit = 0L;
1157
1158   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1159   aopOp (IC_LEFT(ic),ic,FALSE);
1160   aopOp (IC_RIGHT(ic),ic,FALSE);
1161   aopOp (IC_RESULT(ic),ic,TRUE);
1162
1163   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1164       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1165     operand *t = IC_RIGHT(ic);
1166     IC_RIGHT(ic) = IC_LEFT(ic);
1167     IC_LEFT(ic) = t;
1168   }
1169
1170   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1171                    AopType(AOP_TYPE(IC_RESULT(ic))),
1172                    AopType(AOP_TYPE(IC_LEFT(ic))),
1173                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1174
1175   /* special cases :- */
1176   /* if both left & right are in bit space */
1177   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1178       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1179     genPlusBits (ic);
1180     goto release ;
1181   }
1182
1183   /* if I can do an decrement instead
1184      of subtract then GOOD for ME */
1185   //  if (genMinusDec (ic) == TRUE)
1186   //    goto release;   
1187
1188   size = pic14_getDataSize(IC_RESULT(ic));   
1189   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1190
1191   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1192     /* Add a literal to something else */
1193
1194     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1195     lit = - (long)lit;
1196
1197     genAddLit ( ic,  lit);
1198     
1199 #if 0
1200     /* add the first byte: */
1201     pic14_emitcode("movlw","0x%x", lit & 0xff);
1202     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1203     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1204     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1205
1206
1207     offset = 1;
1208     size--;
1209
1210     while(size-- > 0) {
1211
1212       lit >>= 8;
1213
1214       if(lit & 0xff) {
1215
1216         if((lit & 0xff) == 0xff) {
1217           emitpcode(POC_MOVLW,  popGetLit(0xff));
1218           emitSKPC;
1219           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1220         } else {
1221           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1222           emitSKPNC;
1223           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1224           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1225         }
1226
1227       } else {
1228         /* do the rlf known zero trick here */
1229         emitpcode(POC_MOVLW,  popGetLit(1));
1230         emitSKPNC;
1231         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1232       }
1233       offset++;
1234     }
1235 #endif
1236   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1237     // bit subtraction
1238
1239     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1240     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1241     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1242
1243     /* here we are subtracting a bit from a char or int */
1244     if(size == 1) {
1245       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1246
1247         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1248         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1249
1250         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1251                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1252                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1253         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1254       } else {
1255
1256         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1257           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1258           emitpcode(POC_XORLW , popGetLit(1));
1259         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1260               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1261
1262           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1263
1264           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1265             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1266               if(lit & 1) {
1267                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1268                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1269               }
1270             }else{
1271               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1272               if(lit & 1) 
1273                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1274               else
1275                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1276               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1277             }
1278             goto release;
1279           } else {
1280             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1281             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1282             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1283             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1284
1285           }
1286
1287         } else {
1288           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1289           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1290           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1291         }
1292           
1293         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1294             
1295           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1296
1297         } else  {
1298           emitpcode(POC_ANDLW , popGetLit(1));
1299 /*
1300           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1301           emitSKPZ;
1302           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1303 */
1304         }
1305
1306       }
1307
1308     }
1309   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1310               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1311               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1312
1313     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1314     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1315                    AopType(AOP_TYPE(IC_RESULT(ic))),
1316                    AopType(AOP_TYPE(IC_LEFT(ic))),
1317                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1318
1319
1320     if( (size == 1) && ((lit & 0xff) == 0) ) {
1321       /* res = 0 - right */
1322       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1323         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1324         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1325       } else { 
1326         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1327         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1328         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1329       }
1330       goto release;
1331     }
1332
1333     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1334     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1335     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1336
1337
1338     offset = 1;
1339     while(--size) {
1340       lit >>= 8;
1341
1342       if(size == 1) {
1343         /* This is the last byte in a multibyte subtraction 
1344          * There are a couple of tricks we can do by not worrying about 
1345          * propogating the carry */
1346         if(lit == 0xff) {
1347           /* 0xff - x == ~x */
1348           if(same) {
1349             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1350             emitSKPC;
1351             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1352           } else {
1353             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1354             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1355             emitSKPC;
1356             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1357           }
1358         } else {
1359             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1360             emitSKPC;
1361             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1362             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1363             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1364         }
1365
1366         goto release;
1367       }
1368
1369       if(same) {
1370
1371         if(lit & 0xff) {
1372           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1373           emitSKPC;
1374           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1375           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1376         } else {
1377           emitSKPNC;
1378           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1379
1380         }
1381       } else {
1382
1383         if(lit & 0xff) {
1384           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1385           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1386         } else
1387           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1388
1389         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1390         emitSKPC;
1391         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1392         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1393       }
1394     }
1395   
1396
1397   } else {
1398
1399     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1400                    AopType(AOP_TYPE(IC_RESULT(ic))),
1401                    AopType(AOP_TYPE(IC_LEFT(ic))),
1402                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1403
1404     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1405       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1406       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1407       emitpcode(POC_SUBLW, popGetLit(0));
1408       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1409     } else {
1410
1411       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1412         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1413         emitpcode(POC_SUBLW, popGetLit(0));
1414         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1415           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1416       } else {
1417
1418         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1419         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1420           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1421
1422         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1423           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1424         else {
1425           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1426               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1427             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1428           } else {
1429             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1430           }
1431           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1432             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1433               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1434               emitSKPZ;
1435               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1436             }else
1437               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1438           }
1439         }
1440       }
1441     }
1442
1443     /*
1444       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1445
1446       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1447       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1448       } else {
1449       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1450       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1451       }
1452     */
1453     offset = 1;
1454     size--;
1455
1456     while(size--){
1457       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1458         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1459         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1460       }
1461       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1462       emitSKPC;
1463       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1464       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1465
1466       offset++;
1467     }
1468
1469   }
1470
1471
1472   //    adjustArithmeticResult(ic);
1473         
1474  release:
1475   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1476   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1477   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1478 }
1479 /*-----------------------------------------------------------------*
1480  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1481  * 
1482  * 
1483  *-----------------------------------------------------------------*/
1484 void genUMult8XLit_16 (operand *left,
1485                        operand *right,
1486                        operand *result,
1487                        pCodeOpReg *result_hi)
1488
1489 {
1490
1491   unsigned int lit;
1492   unsigned int i,have_first_bit;
1493
1494   if (AOP_TYPE(right) != AOP_LIT){
1495     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1496     exit(1);
1497   }
1498
1499
1500   if(!result_hi) {
1501     result_hi = PCOR(popGet(AOP(result),1));
1502   }
1503
1504   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1505   lit &= 0xff;
1506   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1507
1508
1509   if(!lit) {
1510     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1511     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1512     return;
1513   }
1514
1515   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1516   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1517   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1518
1519   have_first_bit = 0;
1520   for(i=0; i<8; i++) {
1521
1522     if(lit & 1) {
1523       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1524       have_first_bit = 1;
1525     }
1526
1527     if(have_first_bit) {
1528       emitpcode(POC_RRF,   popCopyReg(result_hi));
1529       emitpcode(POC_RRF,   popGet(AOP(result),0));
1530     }
1531
1532     lit >>= 1;
1533   }
1534
1535 }
1536
1537 /*-----------------------------------------------------------------*
1538  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1539  * 
1540  * 
1541  *-----------------------------------------------------------------*/
1542 void genUMult8X8_16 (operand *left,
1543                      operand *right,
1544                      operand *result,
1545                      pCodeOpReg *result_hi)
1546
1547 {
1548
1549   int i;
1550   int looped = 1;
1551
1552   if(!result_hi) {
1553     result_hi = PCOR(popGet(AOP(result),1));
1554   }
1555
1556   if(!looped) {
1557     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1558
1559     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1560     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1561     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1562     emitCLRC;
1563
1564     for(i=0; i<8; i++) {
1565       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1566       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1567       emitpcode(POC_RRF,   popCopyReg(result_hi));
1568       emitpcode(POC_RRF,   popGet(AOP(result),0));
1569     }
1570
1571
1572     /*
1573       Here's another version that does the same thing and takes the 
1574       same number of instructions. The one above is slightly better
1575       because the entry instructions have a higher probability of
1576       being optimized out.
1577     */
1578     /*
1579       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1580       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1581       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1582       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1583
1584       for(i=0; i<8; i++) {
1585       emitSKPNC;
1586       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1587       emitpcode(POC_RRF,   popCopyReg(result_hi));
1588       emitpcode(POC_RRF,   popGet(AOP(result),0));
1589       }
1590     */
1591
1592   } else {
1593     symbol  *tlbl = newiTempLabel(NULL);
1594     pCodeOp *temp = popGetTempReg();
1595
1596
1597     pic14_emitcode(";","Looped 8 X 8 multiplication");
1598
1599     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1600     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1601     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1602
1603     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1604     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1605
1606     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1607
1608     emitpLabel(tlbl->key);
1609
1610     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1611     emitSKPNC;
1612     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1613
1614     emitpcode(POC_RRF,   popCopyReg(result_hi));
1615     emitpcode(POC_RRF,   popGet(AOP(result),0));
1616
1617     emitSKPC;
1618     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1619
1620     popReleaseTempReg(temp);
1621
1622   }
1623 }
1624
1625 /*-----------------------------------------------------------------*
1626  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1627  *
1628  *  this routine will call the unsigned multiply routine and then
1629  * post-fix the sign bit.
1630  *-----------------------------------------------------------------*/
1631 void genSMult8X8_16 (operand *left,
1632                      operand *right,
1633                      operand *result,
1634                      pCodeOpReg *result_hi)
1635 {
1636
1637   if(!result_hi) {
1638     result_hi = PCOR(popGet(AOP(result),1));
1639   }
1640
1641   genUMult8X8_16(left,right,result,result_hi);
1642
1643   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1644   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1645   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1646   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1647   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1648   
1649 }
1650
1651 /*-----------------------------------------------------------------*
1652  * genMult8X8_8 - multiplication of two 8-bit numbers
1653  *
1654  *  this routine will call the unsigned multiply 8X8=>16 routine and
1655  * then throw away the high byte of the result.
1656  *
1657  *-----------------------------------------------------------------*/
1658 void genMult8X8_8 (operand *left,
1659                    operand *right,
1660                    operand *result)
1661 {
1662   pCodeOp *result_hi = popGetTempReg();
1663
1664   if (AOP_TYPE(right) == AOP_LIT)
1665     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1666   else
1667     genUMult8X8_16(left,right,result,PCOR(result_hi));
1668
1669   popReleaseTempReg(result_hi);
1670 }
1671 #if 0
1672 /*-----------------------------------------------------------------*/
1673 /* constMult - generates code for multiplication by a constant     */
1674 /*-----------------------------------------------------------------*/
1675 void genMultConst(unsigned C)
1676 {
1677
1678   unsigned lit;
1679   unsigned sr3; // Shift right 3
1680   unsigned mask;
1681
1682   int size = 1;
1683
1684   /*
1685     Convert a string of 3 binary 1's in the lit into
1686     0111 = 1000 - 1;
1687   */
1688
1689   mask = 7 << ( (size*8) - 3);
1690   lit = C;
1691   sr3 = 0;
1692
1693   while(mask < (1<<size*8)) {
1694
1695     if( (mask & lit) == lit) {
1696       unsigned lsb;
1697
1698       /* We found 3 (or more) consecutive 1's */
1699
1700       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1701
1702       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1703
1704       lit ^= consecutive_bits;
1705
1706       mask <<= 3;
1707
1708       sr3 |= (consecutive + lsb);
1709
1710     }
1711
1712     mask >>= 1;
1713
1714   }
1715
1716 }
1717
1718 #endif