PIC Port - fixed pointer/array accesses. Stream line comparisons. Started function...
[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_PCODE) ||
910               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
911             emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
912           } else {
913             emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
914           }
915           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
916             emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
917         }
918       }
919     }
920
921     size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
922     offset = 1;
923
924
925     while(size--){
926       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
927         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
928         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
929
930         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
931         pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
932       }
933
934       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
935       emitSKPNC;
936       emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
937       emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
938
939       /*
940         pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
941         emitSKPNC;
942         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
943         pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
944       */
945
946       offset++;
947     }
948
949   }
950
951   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
952     int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
953                   SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
954
955
956     /* Need to extend result to higher bytes */
957     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
958
959     /* First grab the carry from the lower bytes */
960     emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
961     emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
962
963
964     if(sign) {
965       /* Now this is really horrid. Gotta check the sign of the addends and propogate
966        * to the result */
967
968       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
969       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
970       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
971       emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
972
973       /* if chars or ints or being signed extended to longs: */
974       if(size) {
975         emitpcode(POC_MOVLW, popGetLit(0));
976         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
977         emitpcode(POC_MOVLW, popGetLit(0xff));
978       }
979     }
980
981     offset++;
982     while(size--) {
983       
984       if(sign)
985         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
986       else
987         emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
988
989       offset++;
990     }
991   }
992
993
994   //adjustArithmeticResult(ic);
995
996  release:
997   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
998   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
999   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1000 }
1001
1002 /*-----------------------------------------------------------------*/
1003 /* genMinusDec :- does subtraction with decrement if possible     */
1004 /*-----------------------------------------------------------------*/
1005 bool genMinusDec (iCode *ic)
1006 {
1007     unsigned int icount ;
1008     unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1009
1010     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1011     /* will try to generate an increment */
1012     /* if the right side is not a literal 
1013     we cannot */
1014     if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) || 
1015         (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) || 
1016         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1017         return FALSE ;
1018
1019     DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1020
1021     /* if the literal value of the right hand side
1022     is greater than 4 then it is not worth it */
1023     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1024         return FALSE ;
1025
1026     /* if decrement 16 bits in register */
1027     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1028         (size > 1) &&
1029         (icount == 1)) {
1030
1031       if(size == 2) { 
1032         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),LSB));
1033         emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1034         emitpcode(POC_INCF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1035         emitpcode(POC_DECF,    popGet(AOP(IC_RESULT(ic)),MSB16));
1036
1037         pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1038         pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1039         pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1040       } else {
1041         /* size is 3 or 4 */
1042         emitpcode(POC_MOVLW,  popGetLit(0xff));
1043         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),LSB));
1044         emitSKPNC;
1045         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB16));
1046         emitSKPNC;
1047         emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB24));
1048
1049         pic14_emitcode("movlw","0xff");
1050         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1051
1052         emitSKPNC;
1053         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1054         emitSKPNC;
1055         pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1056
1057         if(size > 3) {
1058           emitSKPNC;
1059           emitpcode(POC_ADDWF,  popGet(AOP(IC_RESULT(ic)),MSB32));
1060
1061           pic14_emitcode("skpnc","");
1062           emitSKPNC;
1063           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1064         }
1065
1066       }
1067
1068       return TRUE;
1069
1070     }
1071
1072     /* if the sizes are greater than 1 then we cannot */
1073     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1074         AOP_SIZE(IC_LEFT(ic)) > 1   )
1075         return FALSE ;
1076
1077     /* we can if the aops of the left & result match or
1078     if they are in registers and the registers are the
1079     same */
1080     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1081
1082       while (icount--) 
1083         emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1084
1085         //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1086
1087         return TRUE ;
1088     }
1089
1090     DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1091                    aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1092                    aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1093     if(size==1) {
1094
1095       pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1096       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1097
1098       emitpcode(POC_DECFW,  popGet(AOP(IC_LEFT(ic)),0));
1099       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1100
1101       return TRUE;
1102     }
1103
1104     return FALSE ;
1105 }
1106
1107 /*-----------------------------------------------------------------*/
1108 /* addSign - propogate sign bit to higher bytes                    */
1109 /*-----------------------------------------------------------------*/
1110 void addSign(operand *result, int offset, int sign)
1111 {
1112   int size = (pic14_getDataSize(result) - offset);
1113   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1114
1115   if(size > 0){
1116     if(sign && offset) {
1117
1118       if(size == 1) {
1119         emitpcode(POC_CLRF,popGet(AOP(result),offset));
1120         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1121         emitpcode(POC_DECF, popGet(AOP(result),offset));
1122       } else {
1123
1124         emitpcode(POC_MOVLW, popGetLit(0));
1125         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1126         emitpcode(POC_MOVLW, popGetLit(0xff));
1127         while(size--)
1128           emitpcode(POC_MOVWF, popGet(AOP(result),size));
1129
1130       }
1131     } else
1132       while(size--)
1133         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1134   }
1135 }
1136
1137 /*-----------------------------------------------------------------*/
1138 /* genMinusBits - generates code for subtraction  of two bits      */
1139 /*-----------------------------------------------------------------*/
1140 void genMinusBits (iCode *ic)
1141 {
1142     symbol *lbl = newiTempLabel(NULL);
1143     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1144     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1145         pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1146         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1147         pic14_emitcode("cpl","c");
1148         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1149         pic14_outBitC(IC_RESULT(ic));
1150     }
1151     else{
1152         pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1153         pic14_emitcode("subb","a,acc");
1154         pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1155         pic14_emitcode("inc","a");
1156         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1157         aopPut(AOP(IC_RESULT(ic)),"a",0);
1158         addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1159     }
1160 }
1161
1162 /*-----------------------------------------------------------------*/
1163 /* genMinus - generates code for subtraction                       */
1164 /*-----------------------------------------------------------------*/
1165 void genMinus (iCode *ic)
1166 {
1167   int size, offset = 0, same=0;
1168   unsigned long lit = 0L;
1169
1170   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1171   aopOp (IC_LEFT(ic),ic,FALSE);
1172   aopOp (IC_RIGHT(ic),ic,FALSE);
1173   aopOp (IC_RESULT(ic),ic,TRUE);
1174
1175   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY  &&
1176       AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1177     operand *t = IC_RIGHT(ic);
1178     IC_RIGHT(ic) = IC_LEFT(ic);
1179     IC_LEFT(ic) = t;
1180   }
1181
1182   DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1183                    AopType(AOP_TYPE(IC_RESULT(ic))),
1184                    AopType(AOP_TYPE(IC_LEFT(ic))),
1185                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1186
1187   /* special cases :- */
1188   /* if both left & right are in bit space */
1189   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1190       AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1191     genPlusBits (ic);
1192     goto release ;
1193   }
1194
1195   /* if I can do an decrement instead
1196      of subtract then GOOD for ME */
1197   //  if (genMinusDec (ic) == TRUE)
1198   //    goto release;   
1199
1200   size = pic14_getDataSize(IC_RESULT(ic));   
1201   same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1202
1203   if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1204     /* Add a literal to something else */
1205
1206     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1207     lit = - (long)lit;
1208
1209     genAddLit ( ic,  lit);
1210     
1211 #if 0
1212     /* add the first byte: */
1213     pic14_emitcode("movlw","0x%x", lit & 0xff);
1214     pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1215     emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1216     emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),0));
1217
1218
1219     offset = 1;
1220     size--;
1221
1222     while(size-- > 0) {
1223
1224       lit >>= 8;
1225
1226       if(lit & 0xff) {
1227
1228         if((lit & 0xff) == 0xff) {
1229           emitpcode(POC_MOVLW,  popGetLit(0xff));
1230           emitSKPC;
1231           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1232         } else {
1233           emitpcode(POC_MOVLW,  popGetLit(lit & 0xff));
1234           emitSKPNC;
1235           emitpcode(POC_MOVLW,  popGetLit((lit+1) & 0xff));
1236           emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1237         }
1238
1239       } else {
1240         /* do the rlf known zero trick here */
1241         emitpcode(POC_MOVLW,  popGetLit(1));
1242         emitSKPNC;
1243         emitpcode(POC_ADDWF,  popGet(AOP(IC_LEFT(ic)),offset));
1244       }
1245       offset++;
1246     }
1247 #endif
1248   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1249     // bit subtraction
1250
1251     pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1252     pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1253     pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1254
1255     /* here we are subtracting a bit from a char or int */
1256     if(size == 1) {
1257       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1258
1259         emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1260         emitpcode(POC_DECF ,  popGet(AOP(IC_RESULT(ic)),0));
1261
1262         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1263                  AOP(IC_RIGHT(ic))->aopu.aop_dir,
1264                  AOP(IC_RIGHT(ic))->aopu.aop_dir);
1265         pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1266       } else {
1267
1268         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1269           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1270           emitpcode(POC_XORLW , popGetLit(1));
1271         }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1272               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1273
1274           lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1275
1276           if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1277             if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1278               if(lit & 1) {
1279                 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1280                 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1281               }
1282             }else{
1283               emitpcode(POC_BCF ,     popGet(AOP(IC_RESULT(ic)),0));
1284               if(lit & 1) 
1285                 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1286               else
1287                 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1288               emitpcode(POC_BSF ,     popGet(AOP(IC_RESULT(ic)),0));
1289             }
1290             goto release;
1291           } else {
1292             emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1293             emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1294             emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1295             emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1296
1297           }
1298
1299         } else {
1300           emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1301           emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1302           emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1303         }
1304           
1305         if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1306             
1307           emitpcode(POC_MOVWF ,   popGet(AOP(IC_RESULT(ic)),0));
1308
1309         } else  {
1310           emitpcode(POC_ANDLW , popGetLit(1));
1311 /*
1312           emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1313           emitSKPZ;
1314           emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1315 */
1316         }
1317
1318       }
1319
1320     }
1321   } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || 
1322               (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1323               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1324
1325     lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1326     DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1327                    AopType(AOP_TYPE(IC_RESULT(ic))),
1328                    AopType(AOP_TYPE(IC_LEFT(ic))),
1329                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1330
1331
1332     if( (size == 1) && ((lit & 0xff) == 0) ) {
1333       /* res = 0 - right */
1334       if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1335         emitpcode(POC_COMF,  popGet(AOP(IC_RIGHT(ic)),0));
1336         emitpcode(POC_INCF,  popGet(AOP(IC_RIGHT(ic)),0));
1337       } else { 
1338         emitpcode(POC_COMFW,  popGet(AOP(IC_RIGHT(ic)),0));
1339         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0));
1340         emitpcode(POC_INCF,   popGet(AOP(IC_RESULT(ic)),0));
1341       }
1342       goto release;
1343     }
1344
1345     emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0));
1346     emitpcode(POC_SUBLW, popGetLit(lit & 0xff));    
1347     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1348
1349
1350     offset = 1;
1351     while(--size) {
1352       lit >>= 8;
1353
1354       if(size == 1) {
1355         /* This is the last byte in a multibyte subtraction 
1356          * There are a couple of tricks we can do by not worrying about 
1357          * propogating the carry */
1358         if(lit == 0xff) {
1359           /* 0xff - x == ~x */
1360           if(same) {
1361             emitpcode(POC_COMF,  popGet(AOP(IC_RESULT(ic)),offset));
1362             emitSKPC;
1363             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1364           } else {
1365             emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1366             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1367             emitSKPC;
1368             emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
1369           }
1370         } else {
1371             emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1372             emitSKPC;
1373             emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1374             emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1375             emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1376         }
1377
1378         goto release;
1379       }
1380
1381       if(same) {
1382
1383         if(lit & 0xff) {
1384           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1385           emitSKPC;
1386           emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1387           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1388         } else {
1389           emitSKPNC;
1390           emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1391
1392         }
1393       } else {
1394
1395         if(lit & 0xff) {
1396           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1397           emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1398         } else
1399           emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1400
1401         emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1402         emitSKPC;
1403         emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1404         emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1405       }
1406     }
1407   
1408
1409   } else {
1410
1411     DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1412                    AopType(AOP_TYPE(IC_RESULT(ic))),
1413                    AopType(AOP_TYPE(IC_LEFT(ic))),
1414                    AopType(AOP_TYPE(IC_RIGHT(ic))));
1415
1416     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1417       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1418       emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1419       emitpcode(POC_SUBLW, popGetLit(0));
1420       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1421     } else {
1422
1423       if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1424         emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1425         emitpcode(POC_SUBLW, popGetLit(0));
1426         if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1427           emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1428       } else {
1429
1430         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1431         if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
1432           emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1433
1434         if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1435           emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1436         else {
1437           if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1438               (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1439             emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1440           } else {
1441             emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1442           }
1443           if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1444             if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1445               emitpcode(POC_BCF ,   popGet(AOP(IC_RESULT(ic)),0));
1446               emitSKPZ;
1447               emitpcode(POC_BSF ,   popGet(AOP(IC_RESULT(ic)),0));
1448             }else
1449               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1450           }
1451         }
1452       }
1453     }
1454
1455     /*
1456       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1457
1458       if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1459       emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1460       } else {
1461       emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1462       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1463       }
1464     */
1465     offset = 1;
1466     size--;
1467
1468     while(size--){
1469       if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1470         emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
1471         emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
1472       }
1473       emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
1474       emitSKPC;
1475       emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1476       emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
1477
1478       offset++;
1479     }
1480
1481   }
1482
1483
1484   //    adjustArithmeticResult(ic);
1485         
1486  release:
1487   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1488   freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1489   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1490 }
1491 /*-----------------------------------------------------------------*
1492  * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1493  * 
1494  * 
1495  *-----------------------------------------------------------------*/
1496 void genUMult8XLit_16 (operand *left,
1497                        operand *right,
1498                        operand *result,
1499                        pCodeOpReg *result_hi)
1500
1501 {
1502
1503   unsigned int lit;
1504   unsigned int i,have_first_bit;
1505
1506   if (AOP_TYPE(right) != AOP_LIT){
1507     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1508     exit(1);
1509   }
1510
1511
1512   if(!result_hi) {
1513     result_hi = PCOR(popGet(AOP(result),1));
1514   }
1515
1516   lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1517   lit &= 0xff;
1518   pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1519
1520
1521   if(!lit) {
1522     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1523     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1524     return;
1525   }
1526
1527   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1528   emitpcode(POC_CLRF,  popGet(AOP(result),0));
1529   emitpcode(POC_CLRF,  popCopyReg(result_hi));
1530
1531   have_first_bit = 0;
1532   for(i=0; i<8; i++) {
1533
1534     if(lit & 1) {
1535       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1536       have_first_bit = 1;
1537     }
1538
1539     if(have_first_bit) {
1540       emitpcode(POC_RRF,   popCopyReg(result_hi));
1541       emitpcode(POC_RRF,   popGet(AOP(result),0));
1542     }
1543
1544     lit >>= 1;
1545   }
1546
1547 }
1548
1549 /*-----------------------------------------------------------------*
1550  * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1551  * 
1552  * 
1553  *-----------------------------------------------------------------*/
1554 void genUMult8X8_16 (operand *left,
1555                      operand *right,
1556                      operand *result,
1557                      pCodeOpReg *result_hi)
1558
1559 {
1560
1561   int i;
1562   int looped = 1;
1563
1564   if(!result_hi) {
1565     result_hi = PCOR(popGet(AOP(result),1));
1566   }
1567
1568   if(!looped) {
1569     pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1570
1571     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1572     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1573     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1574     emitCLRC;
1575
1576     for(i=0; i<8; i++) {
1577       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1578       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1579       emitpcode(POC_RRF,   popCopyReg(result_hi));
1580       emitpcode(POC_RRF,   popGet(AOP(result),0));
1581     }
1582
1583
1584     /*
1585       Here's another version that does the same thing and takes the 
1586       same number of instructions. The one above is slightly better
1587       because the entry instructions have a higher probability of
1588       being optimized out.
1589     */
1590     /*
1591       emitpcode(POC_CLRF,  popCopyReg(result_hi));
1592       emitpcode(POC_RRFW,  popGet(AOP(left),0));
1593       emitpcode(POC_MOVWF, popGet(AOP(result),0));
1594       emitpcode(POC_MOVFW, popGet(AOP(right),0));
1595
1596       for(i=0; i<8; i++) {
1597       emitSKPNC;
1598       emitpcode(POC_ADDWF, popCopyReg(result_hi));
1599       emitpcode(POC_RRF,   popCopyReg(result_hi));
1600       emitpcode(POC_RRF,   popGet(AOP(result),0));
1601       }
1602     */
1603
1604   } else {
1605     symbol  *tlbl = newiTempLabel(NULL);
1606     pCodeOp *temp = popGetTempReg();
1607
1608
1609     pic14_emitcode(";","Looped 8 X 8 multiplication");
1610
1611     emitpcode(POC_CLRF,  popGet(AOP(result),0));
1612     emitpcode(POC_CLRF,  popCopyReg(result_hi));
1613     emitpcode(POC_BSF,   newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1614
1615     emitpcode(POC_MOVFW, popGet(AOP(right),0));
1616     emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1617
1618     emitpcode(POC_MOVFW, popGet(AOP(left),0));
1619
1620     emitpLabel(tlbl->key);
1621
1622     emitpcode(POC_RRF,   popCopyReg(PCOR(temp)));
1623     emitSKPNC;
1624     emitpcode(POC_ADDWF, popCopyReg(result_hi));
1625
1626     emitpcode(POC_RRF,   popCopyReg(result_hi));
1627     emitpcode(POC_RRF,   popGet(AOP(result),0));
1628
1629     emitSKPC;
1630     emitpcode(POC_GOTO,  popGetLabel(tlbl->key));
1631
1632     popReleaseTempReg(temp);
1633
1634   }
1635 }
1636
1637 /*-----------------------------------------------------------------*
1638  * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1639  *
1640  *  this routine will call the unsigned multiply routine and then
1641  * post-fix the sign bit.
1642  *-----------------------------------------------------------------*/
1643 void genSMult8X8_16 (operand *left,
1644                      operand *right,
1645                      operand *result,
1646                      pCodeOpReg *result_hi)
1647 {
1648
1649   if(!result_hi) {
1650     result_hi = PCOR(popGet(AOP(result),1));
1651   }
1652
1653   genUMult8X8_16(left,right,result,result_hi);
1654
1655   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1656   emitpcode(POC_SUBWF, popCopyReg(result_hi));
1657   emitpcode(POC_MOVFW, popGet(AOP(left),0));
1658   emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1659   emitpcode(POC_SUBWF, popGet(AOP(result),1));
1660   
1661 }
1662
1663 /*-----------------------------------------------------------------*
1664  * genMult8X8_8 - multiplication of two 8-bit numbers
1665  *
1666  *  this routine will call the unsigned multiply 8X8=>16 routine and
1667  * then throw away the high byte of the result.
1668  *
1669  *-----------------------------------------------------------------*/
1670 void genMult8X8_8 (operand *left,
1671                    operand *right,
1672                    operand *result)
1673 {
1674   pCodeOp *result_hi = popGetTempReg();
1675
1676   if (AOP_TYPE(right) == AOP_LIT)
1677     genUMult8XLit_16(left,right,result,PCOR(result_hi));
1678   else
1679     genUMult8X8_16(left,right,result,PCOR(result_hi));
1680
1681   popReleaseTempReg(result_hi);
1682 }
1683 #if 0
1684 /*-----------------------------------------------------------------*/
1685 /* constMult - generates code for multiplication by a constant     */
1686 /*-----------------------------------------------------------------*/
1687 void genMultConst(unsigned C)
1688 {
1689
1690   unsigned lit;
1691   unsigned sr3; // Shift right 3
1692   unsigned mask;
1693
1694   int size = 1;
1695
1696   /*
1697     Convert a string of 3 binary 1's in the lit into
1698     0111 = 1000 - 1;
1699   */
1700
1701   mask = 7 << ( (size*8) - 3);
1702   lit = C;
1703   sr3 = 0;
1704
1705   while(mask < (1<<size*8)) {
1706
1707     if( (mask & lit) == lit) {
1708       unsigned lsb;
1709
1710       /* We found 3 (or more) consecutive 1's */
1711
1712       lsb = mask & ~(mask & (mask-1));  // lsb of mask.
1713
1714       consecutive_bits = ((lit + lsb) & lit) ^ lit;
1715
1716       lit ^= consecutive_bits;
1717
1718       mask <<= 3;
1719
1720       sr3 |= (consecutive + lsb);
1721
1722     }
1723
1724     mask >>= 1;
1725
1726   }
1727
1728 }
1729
1730 #endif