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