Fixed shifts by varaibles. Added rotate test code to src/regression
[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 - propogate sign bit to higher bytes                    */
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
1114   if(size > 0){
1115     if(sign && offset) {
1116
1117       if(size == 1) {
1118         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1119         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1120         emitpcode(POC_DECF, popGet(AOP(result),offset));
1121       } else {
1122
1123         emitpcode(POC_MOVLW, popGetLit(0));
1124         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1125         emitpcode(POC_MOVLW, popGetLit(0xff));
1126         while(size--)
1127           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1128
1129       }
1130     } else
1131       while(size--)
1132         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1133   }
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* genMinusBits - generates code for subtraction  of two bits      */
1138 /*-----------------------------------------------------------------*/
1139 void genMinusBits (iCode *ic)
1140 {
1141     symbol *lbl = newiTempLabel(NULL);
1142     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1143     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1144         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1145         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1146         pic14_emitcode("cpl","c");
1147         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1148         pic14_outBitC(IC_RESULT(ic));
1149     }
1150     else{
1151         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1152         pic14_emitcode("subb","a,acc");
1153         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1154         pic14_emitcode("inc","a");
1155         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1156         aopPut(AOP(IC_RESULT(ic)),"a",0);
1157         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1158     }
1159 }
1160
1161 /*-----------------------------------------------------------------*/
1162 /* genMinus - generates code for subtraction                       */
1163 /*-----------------------------------------------------------------*/
1164 void genMinus (iCode *ic)
1165 {
1166   int size, offset = 0, same=0;
1167   unsigned long lit = 0L;
1168
1169   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1170   aopOp (IC_LEFT(ic),ic,FALSE);
1171   aopOp (IC_RIGHT(ic),ic,FALSE);
1172   aopOp (IC_RESULT(ic),ic,TRUE);
1173
1174   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1175       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1176     operand *t = IC_RIGHT(ic);
1177     IC_RIGHT(ic) = IC_LEFT(ic);
1178     IC_LEFT(ic) = t;
1179   }
1180
1181   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1182                    AopType(AOP_TYPE(IC_RESULT(ic))),
1183                    AopType(AOP_TYPE(IC_LEFT(ic))),
1184                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1185
1186   /* special cases :- */
1187   /* if both left & right are in bit space */
1188   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1189       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1190     genPlusBits (ic);
1191     goto release ;
1192   }
1193
1194   /* if I can do an decrement instead
1195      of subtract then GOOD for ME */
1196   //  if (genMinusDec (ic) == TRUE)
1197   //    goto release;   
1198
1199   size = pic14_getDataSize(IC_RESULT(ic));   
1200   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1201
1202   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1203     /* Add a literal to something else */
1204
1205     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1206     lit = - (long)lit;
1207
1208     genAddLit ( ic,  lit);
1209     
1210 #if 0
1211     /* add the first byte: */
1212     pic14_emitcode("movlw","0x%x", lit & 0xff);
1213     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1214     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1215     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1216
1217
1218     offset = 1;
1219     size--;
1220
1221     while(size-- > 0) {
1222
1223       lit >>= 8;
1224
1225       if(lit & 0xff) {
1226
1227         if((lit & 0xff) == 0xff) {
1228           emitpcode(POC_MOVLW,  popGetLit(0xff));
1229           emitSKPC;
1230           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1231         } else {
1232           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1233           emitSKPNC;
1234           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1235           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1236         }
1237
1238       } else {
1239         /* do the rlf known zero trick here */
1240         emitpcode(POC_MOVLW,  popGetLit(1));
1241         emitSKPNC;
1242         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1243       }
1244       offset++;
1245     }
1246 #endif
1247   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1248     // bit subtraction
1249
1250     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1251     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1252     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1253
1254     /* here we are subtracting a bit from a char or int */
1255     if(size == 1) {
1256       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1257
1258         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1259         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1260
1261         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1262                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1263                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1264         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1265       } else {
1266
1267         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1268           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1269           emitpcode(POC_XORLW , popGetLit(1));
1270         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1271               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1272
1273           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1274
1275           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1276             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1277               if(lit & 1) {
1278                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1279                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1280               }
1281             }else{
1282               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1283               if(lit & 1) 
1284                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1285               else
1286                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1287               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1288             }
1289             goto release;
1290           } else {
1291             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1292             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1293             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1294             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1295
1296           }
1297
1298         } else {
1299           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1300           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1301           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1302         }
1303           
1304         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1305             
1306           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1307
1308         } else  {
1309           emitpcode(POC_ANDLW , popGetLit(1));
1310 /*
1311           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1312           emitSKPZ;
1313           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1314 */
1315         }
1316
1317       }
1318
1319     }
1320   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1321               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1322               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1323
1324     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1325     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1326                    AopType(AOP_TYPE(IC_RESULT(ic))),
1327                    AopType(AOP_TYPE(IC_LEFT(ic))),
1328                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1329
1330
1331     if( (size == 1) && ((lit & 0xff) == 0) ) {
1332       /* res = 0 - right */
1333       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1334         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1335         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1336       } else { 
1337         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1338         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1339         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1340       }
1341       goto release;
1342     }
1343
1344     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1345     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1346     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1347
1348
1349     offset = 1;
1350     while(--size) {
1351       lit >>= 8;
1352
1353       if(size == 1) {
1354         /* This is the last byte in a multibyte subtraction 
1355          * There are a couple of tricks we can do by not worrying about 
1356          * propogating the carry */
1357         if(lit == 0xff) {
1358           /* 0xff - x == ~x */
1359           if(same) {
1360             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1361             emitSKPC;
1362             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1363           } else {
1364             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1365             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1366             emitSKPC;
1367             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1368           }
1369         } else {
1370             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1371             emitSKPC;
1372             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1373             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1374             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1375         }
1376
1377         goto release;
1378       }
1379
1380       if(same) {
1381
1382         if(lit & 0xff) {
1383           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1384           emitSKPC;
1385           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1386           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1387         } else {
1388           emitSKPNC;
1389           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1390
1391         }
1392       } else {
1393
1394         if(lit & 0xff) {
1395           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1396           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1397         } else
1398           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1399
1400         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1401         emitSKPC;
1402         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1403         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1404       }
1405     }
1406   
1407
1408   } else {
1409
1410     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1411                    AopType(AOP_TYPE(IC_RESULT(ic))),
1412                    AopType(AOP_TYPE(IC_LEFT(ic))),
1413                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1414
1415     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1416       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1417       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1418       emitpcode(POC_SUBLW, popGetLit(0));
1419       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1420     } else {
1421
1422       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1423         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1424         emitpcode(POC_SUBLW, popGetLit(0));
1425         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1426           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1427       } else {
1428
1429         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1430         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1431           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1432
1433         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1434           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1435         else {
1436           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1437               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1438             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1439           } else {
1440             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1441           }
1442           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1443             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1444               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1445               emitSKPZ;
1446               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1447             }else
1448               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1449           }
1450         }
1451       }
1452     }
1453
1454     /*
1455       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1456
1457       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1458       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1459       } else {
1460       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1461       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1462       }
1463     */
1464     offset = 1;
1465     size--;
1466
1467     while(size--){
1468       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1469         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1470         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1471       }
1472       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1473       emitSKPC;
1474       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1475       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1476
1477       offset++;
1478     }
1479
1480   }
1481
1482
1483   //    adjustArithmeticResult(ic);
1484         
1485  release:
1486   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1487   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1488   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1489 }
1490 /*-----------------------------------------------------------------*
1491  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1492  * 
1493  * 
1494  *-----------------------------------------------------------------*/
1495 void genUMult8XLit_16 (operand *left,
1496                        operand *right,
1497                        operand *result,
1498                        pCodeOpReg *result_hi)
1499
1500 {
1501
1502   unsigned int lit;
1503   unsigned int i,have_first_bit;
1504
1505   if (AOP_TYPE(right) != AOP_LIT){
1506     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1507     exit(1);
1508   }
1509
1510
1511   if(!result_hi) {
1512     result_hi = PCOR(popGet(AOP(result),1));
1513   }
1514
1515   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1516   lit &= 0xff;
1517   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1518
1519
1520   if(!lit) {
1521     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1522     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1523     return;
1524   }
1525
1526   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1527   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1528   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1529
1530   have_first_bit = 0;
1531   for(i=0; i<8; i++) {
1532
1533     if(lit & 1) {
1534       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1535       have_first_bit = 1;
1536     }
1537
1538     if(have_first_bit) {
1539       emitpcode(POC_RRF,   popCopyReg(result_hi));
1540       emitpcode(POC_RRF,   popGet(AOP(result),0));
1541     }
1542
1543     lit >>= 1;
1544   }
1545
1546 }
1547
1548 /*-----------------------------------------------------------------*
1549  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1550  * 
1551  * 
1552  *-----------------------------------------------------------------*/
1553 void genUMult8X8_16 (operand *left,
1554                      operand *right,
1555                      operand *result,
1556                      pCodeOpReg *result_hi)
1557
1558 {
1559
1560   int i;
1561   int looped = 1;
1562
1563   if(!result_hi) {
1564     result_hi = PCOR(popGet(AOP(result),1));
1565   }
1566
1567   if(!looped) {
1568     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1569
1570     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1571     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1572     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1573     emitCLRC;
1574
1575     for(i=0; i<8; i++) {
1576       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1577       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1578       emitpcode(POC_RRF,   popCopyReg(result_hi));
1579       emitpcode(POC_RRF,   popGet(AOP(result),0));
1580     }
1581
1582
1583     /*
1584       Here's another version that does the same thing and takes the 
1585       same number of instructions. The one above is slightly better
1586       because the entry instructions have a higher probability of
1587       being optimized out.
1588     */
1589     /*
1590       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1591       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1592       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1593       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1594
1595       for(i=0; i<8; i++) {
1596       emitSKPNC;
1597       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1598       emitpcode(POC_RRF,   popCopyReg(result_hi));
1599       emitpcode(POC_RRF,   popGet(AOP(result),0));
1600       }
1601     */
1602
1603   } else {
1604     symbol  *tlbl = newiTempLabel(NULL);
1605     pCodeOp *temp = popGetTempReg();
1606
1607
1608     pic14_emitcode(";","Looped 8 X 8 multiplication");
1609
1610     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1611     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1612     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1613
1614     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1615     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1616
1617     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1618
1619     emitpLabel(tlbl->key);
1620
1621     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1622     emitSKPNC;
1623     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1624
1625     emitpcode(POC_RRF,   popCopyReg(result_hi));
1626     emitpcode(POC_RRF,   popGet(AOP(result),0));
1627
1628     emitSKPC;
1629     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1630
1631     popReleaseTempReg(temp);
1632
1633   }
1634 }
1635
1636 /*-----------------------------------------------------------------*
1637  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1638  *
1639  *  this routine will call the unsigned multiply routine and then
1640  * post-fix the sign bit.
1641  *-----------------------------------------------------------------*/
1642 void genSMult8X8_16 (operand *left,
1643                      operand *right,
1644                      operand *result,
1645                      pCodeOpReg *result_hi)
1646 {
1647
1648   if(!result_hi) {
1649     result_hi = PCOR(popGet(AOP(result),1));
1650   }
1651
1652   genUMult8X8_16(left,right,result,result_hi);
1653
1654   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1655   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1656   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1657   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1658   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1659   
1660 }
1661
1662 /*-----------------------------------------------------------------*
1663  * genMult8X8_8 - multiplication of two 8-bit numbers
1664  *
1665  *  this routine will call the unsigned multiply 8X8=>16 routine and
1666  * then throw away the high byte of the result.
1667  *
1668  *-----------------------------------------------------------------*/
1669 void genMult8X8_8 (operand *left,
1670                    operand *right,
1671                    operand *result)
1672 {
1673   pCodeOp *result_hi = popGetTempReg();
1674
1675   if (AOP_TYPE(right) == AOP_LIT)
1676     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1677   else
1678     genUMult8X8_16(left,right,result,PCOR(result_hi));
1679
1680   popReleaseTempReg(result_hi);
1681 }
1682 #if 0
1683 /*-----------------------------------------------------------------*/
1684 /* constMult - generates code for multiplication by a constant     */
1685 /*-----------------------------------------------------------------*/
1686 void genMultConst(unsigned C)
1687 {
1688
1689   unsigned lit;
1690   unsigned sr3; // Shift right 3
1691   unsigned mask;
1692
1693   int size = 1;
1694
1695   /*
1696     Convert a string of 3 binary 1's in the lit into
1697     0111 = 1000 - 1;
1698   */
1699
1700   mask = 7 << ( (size*8) - 3);
1701   lit = C;
1702   sr3 = 0;
1703
1704   while(mask < (1<<size*8)) {
1705
1706     if( (mask & lit) == lit) {
1707       unsigned lsb;
1708
1709       /* We found 3 (or more) consecutive 1's */
1710
1711       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1712
1713       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1714
1715       lit ^= consecutive_bits;
1716
1717       mask <<= 3;
1718
1719       sr3 |= (consecutive + lsb);
1720
1721     }
1722
1723     mask >>= 1;
1724
1725   }
1726
1727 }
1728
1729 #endif