The PIC Port was assuming ifx was always true. (A recent [valid] change
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
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 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
41 #else
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
51 #endif
52 #endif
53 #endif
54 #endif
55
56 #include "common.h"
57 #include "SDCCpeeph.h"
58 #include "ralloc.h"
59 #include "pcode.h"
60 #include "gen.h"
61
62 /*
63   if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
64     DEBUGpic14_emitcode ("; ","result %s",
65                          AopType(AOP_TYPE(IC_RESULT(ic))));
66
67   if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
68     DEBUGpic14_emitcode ("; ","left %s",
69                        AopType(AOP_TYPE(IC_LEFT(ic))));
70
71   if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
72     DEBUGpic14_emitcode ("; ","right %s",
73                        AopType(AOP_TYPE(IC_RIGHT(ic))));
74 */
75
76
77 static int labelOffset=0;
78 static int debug_verbose=1;
79 static int optimized_for_speed = 0;
80
81 /* max_key keeps track of the largest label number used in 
82    a function. This is then used to adjust the label offset
83    for the next function.
84 */
85 static int max_key=0;
86 unsigned int pic14aopLiteral (value *val, int offset);
87 const char *AopType(short type);
88
89 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
90
91 /* this is the down and dirty file with all kinds of 
92    kludgy & hacky stuff. This is what it is all about
93    CODE GENERATION for a specific MCU . some of the
94    routines may be reusable, will have to see */
95
96 static char *zero = "#0x00";
97 static char *one  = "#0x01";
98 static char *spname = "sp";
99
100 char *fReturnpic14[] = {"FSR","dph","b","a" };
101 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
102 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
103 static char **fReturn = fReturnpic14;
104
105 static char *accUse[] = {"a","b"};
106
107 //static short rbank = -1;
108
109 static struct {
110     short r0Pushed;
111     short r1Pushed;
112     short accInUse;
113     short inLine;
114     short debugLine;
115     short nRegsSaved;
116     set *sendSet;
117 } _G;
118
119 /* Resolved ifx structure. This structure stores information
120    about an iCode ifx that makes it easier to generate code.
121 */
122 typedef struct resolvedIfx {
123   symbol *lbl;     /* pointer to a label */
124   int condition;   /* true or false ifx */
125   int generated;   /* set true when the code associated with the ifx
126                     * is generated */
127 } resolvedIfx;
128
129 extern int pic14_ptrRegReq ;
130 extern int pic14_nRegs;
131 extern FILE *codeOutFile;
132 static void saverbank (int, iCode *,bool);
133
134 static lineNode *lineHead = NULL;
135 static lineNode *lineCurr = NULL;
136
137 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
138 0xE0, 0xC0, 0x80, 0x00};
139 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
140 0x07, 0x03, 0x01, 0x00};
141
142 static  pBlock *pb;
143
144 /*-----------------------------------------------------------------*/
145 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
146 /*                 exponent of 2 is returned, otherwise -1 is      */
147 /*                 returned.                                       */
148 /* note that this is similar to the function `powof2' in SDCCsymt  */
149 /* if(n == 2^y)                                                    */
150 /*   return y;                                                     */
151 /* return -1;                                                      */
152 /*-----------------------------------------------------------------*/
153 static int my_powof2 (unsigned long num)
154 {
155   if(num) {
156     if( (num & (num-1)) == 0) {
157       int nshifts = -1;
158       while(num) {
159         num>>=1;
160         nshifts++;
161       }
162       return nshifts;
163     }
164   }
165
166   return -1;
167 }
168
169 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
170 {
171     va_list ap;
172     char lb[INITIAL_INLINEASM];  
173     char *lbp = lb;
174
175     if(!debug_verbose)
176       return;
177
178     va_start(ap,fmt);   
179
180     if (inst && *inst) {
181         if (fmt && *fmt)
182             sprintf(lb,"%s\t",inst);
183         else
184             sprintf(lb,"%s",inst);
185         vsprintf(lb+(strlen(lb)),fmt,ap);
186     }  else
187         vsprintf(lb,fmt,ap);
188
189     while (isspace(*lbp)) lbp++;
190
191     if (lbp && *lbp) 
192         lineCurr = (lineCurr ?
193                     connectLine(lineCurr,newLineNode(lb)) :
194                     (lineHead = newLineNode(lb)));
195     lineCurr->isInline = _G.inLine;
196     lineCurr->isDebug  = _G.debugLine;
197
198     addpCode2pBlock(pb,newpCodeCharP(lb));
199
200     va_end(ap);
201 }
202
203
204 static void emitpLabel(int key)
205 {
206   addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
207 }
208
209 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
210 {
211
212   if(pcop)
213     addpCode2pBlock(pb,newpCode(poc,pcop));
214   else
215     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
216 }
217
218 void emitpcodeNULLop(PIC_OPCODE poc)
219 {
220
221   addpCode2pBlock(pb,newpCode(poc,NULL));
222
223 }
224
225 /*-----------------------------------------------------------------*/
226 /* pic14_emitcode - writes the code into a file : for now it is simple    */
227 /*-----------------------------------------------------------------*/
228 void pic14_emitcode (char *inst,char *fmt, ...)
229 {
230     va_list ap;
231     char lb[INITIAL_INLINEASM];  
232     char *lbp = lb;
233
234     va_start(ap,fmt);   
235
236     if (inst && *inst) {
237         if (fmt && *fmt)
238             sprintf(lb,"%s\t",inst);
239         else
240             sprintf(lb,"%s",inst);
241         vsprintf(lb+(strlen(lb)),fmt,ap);
242     }  else
243         vsprintf(lb,fmt,ap);
244
245     while (isspace(*lbp)) lbp++;
246
247     if (lbp && *lbp) 
248         lineCurr = (lineCurr ?
249                     connectLine(lineCurr,newLineNode(lb)) :
250                     (lineHead = newLineNode(lb)));
251     lineCurr->isInline = _G.inLine;
252     lineCurr->isDebug  = _G.debugLine;
253
254     if(debug_verbose)
255       addpCode2pBlock(pb,newpCodeCharP(lb));
256
257     va_end(ap);
258 }
259
260
261 /*-----------------------------------------------------------------*/
262 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
263 /*-----------------------------------------------------------------*/
264 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
265 {
266     bool r0iu = FALSE , r1iu = FALSE;
267     bool r0ou = FALSE , r1ou = FALSE;
268
269     /* the logic: if r0 & r1 used in the instruction
270     then we are in trouble otherwise */
271
272     /* first check if r0 & r1 are used by this
273     instruction, in which case we are in trouble */
274     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
275         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
276     {
277         goto endOfWorld;      
278     }
279
280     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
281     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
282
283     /* if no usage of r0 then return it */
284     if (!r0iu && !r0ou) {
285         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
286         (*aopp)->type = AOP_R0;
287         
288         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
289     }
290
291     /* if no usage of r1 then return it */
292     if (!r1iu && !r1ou) {
293         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
294         (*aopp)->type = AOP_R1;
295
296         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
297     }    
298
299     /* now we know they both have usage */
300     /* if r0 not used in this instruction */
301     if (!r0iu) {
302         /* push it if not already pushed */
303         if (!_G.r0Pushed) {
304             pic14_emitcode ("push","%s",
305                       pic14_regWithIdx(R0_IDX)->dname);
306             _G.r0Pushed++ ;
307         }
308         
309         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
310         (*aopp)->type = AOP_R0;
311
312         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
313     }
314
315     /* if r1 not used then */
316
317     if (!r1iu) {
318         /* push it if not already pushed */
319         if (!_G.r1Pushed) {
320             pic14_emitcode ("push","%s",
321                       pic14_regWithIdx(R1_IDX)->dname);
322             _G.r1Pushed++ ;
323         }
324         
325         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
326         (*aopp)->type = AOP_R1;
327         return pic14_regWithIdx(R1_IDX);
328     }
329
330 endOfWorld :
331     /* I said end of world but not quite end of world yet */
332     /* if this is a result then we can push it on the stack*/
333     if (result) {
334         (*aopp)->type = AOP_STK;    
335         return NULL;
336     }
337
338     /* other wise this is true end of the world */
339     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
340            "getFreePtr should never reach here");
341     exit(0);
342 }
343
344 /*-----------------------------------------------------------------*/
345 /* newAsmop - creates a new asmOp                                  */
346 /*-----------------------------------------------------------------*/
347 asmop *newAsmop (short type)
348 {
349     asmop *aop;
350
351     aop = Safe_calloc(1,sizeof(asmop));
352     aop->type = type;
353     return aop;
354 }
355
356 static void genSetDPTR(int n)
357 {
358     if (!n)
359     {
360         pic14_emitcode(";", "Select standard DPTR");
361         pic14_emitcode("mov", "dps, #0x00");
362     }
363     else
364     {
365         pic14_emitcode(";", "Select alternate DPTR");
366         pic14_emitcode("mov", "dps, #0x01");
367     }
368 }
369
370 /*-----------------------------------------------------------------*/
371 /* resolveIfx - converts an iCode ifx into a form more useful for  */
372 /*              generating code                                    */
373 /*-----------------------------------------------------------------*/
374 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
375 {
376   if(!resIfx) 
377     return;
378
379   DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
380
381   resIfx->condition = 1;    /* assume that the ifx is true */
382   resIfx->generated = 0;    /* indicate that the ifx has not been used */
383
384   if(!ifx) {
385     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
386     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
387                         __FUNCTION__,__LINE__,resIfx->lbl->key);
388   } else {
389     if(IC_TRUE(ifx)) {
390       resIfx->lbl = IC_TRUE(ifx);
391     } else {
392       resIfx->lbl = IC_FALSE(ifx);
393       resIfx->condition = 0;
394     }
395   }
396
397   DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
398
399 }
400 /*-----------------------------------------------------------------*/
401 /* pointerCode - returns the code for a pointer type               */
402 /*-----------------------------------------------------------------*/
403 static int pointerCode (sym_link *etype)
404 {
405
406     return PTR_TYPE(SPEC_OCLS(etype));
407
408 }
409
410 /*-----------------------------------------------------------------*/
411 /* aopForSym - for a true symbol                                   */
412 /*-----------------------------------------------------------------*/
413 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
414 {
415     asmop *aop;
416     memmap *space= SPEC_OCLS(sym->etype);
417
418     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
419     /* if already has one */
420     if (sym->aop)
421         return sym->aop;
422
423     /* assign depending on the storage class */
424     /* if it is on the stack or indirectly addressable */
425     /* space we need to assign either r0 or r1 to it   */    
426     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
427         sym->aop = aop = newAsmop(0);
428         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
429         aop->size = getSize(sym->type);
430
431         /* now assign the address of the variable to 
432         the pointer register */
433         if (aop->type != AOP_STK) {
434
435             if (sym->onStack) {
436                     if ( _G.accInUse )
437                         pic14_emitcode("push","acc");
438
439                     pic14_emitcode("mov","a,_bp");
440                     pic14_emitcode("add","a,#0x%02x",
441                              ((sym->stack < 0) ?
442                               ((char)(sym->stack - _G.nRegsSaved )) :
443                               ((char)sym->stack)) & 0xff);
444                     pic14_emitcode("mov","%s,a",
445                              aop->aopu.aop_ptr->name);
446
447                     if ( _G.accInUse )
448                         pic14_emitcode("pop","acc");
449             } else
450                 pic14_emitcode("mov","%s,#%s",
451                          aop->aopu.aop_ptr->name,
452                          sym->rname);
453             aop->paged = space->paged;
454         } else
455             aop->aopu.aop_stk = sym->stack;
456         return aop;
457     }
458     
459     if (sym->onStack && options.stack10bit)
460     {
461         /* It's on the 10 bit stack, which is located in
462          * far data space.
463          */
464          
465       //DEBUGpic14_emitcode(";","%d",__LINE__);
466
467         if ( _G.accInUse )
468                 pic14_emitcode("push","acc");
469
470         pic14_emitcode("mov","a,_bp");
471         pic14_emitcode("add","a,#0x%02x",
472                  ((sym->stack < 0) ?
473                    ((char)(sym->stack - _G.nRegsSaved )) :
474                    ((char)sym->stack)) & 0xff);
475         
476         genSetDPTR(1);
477         pic14_emitcode ("mov","dpx1,#0x40");
478         pic14_emitcode ("mov","dph1,#0x00");
479         pic14_emitcode ("mov","dpl1, a");
480         genSetDPTR(0);
481         
482         if ( _G.accInUse )
483             pic14_emitcode("pop","acc");
484             
485         sym->aop = aop = newAsmop(AOP_DPTR2);
486         aop->size = getSize(sym->type); 
487         return aop;
488     }
489
490     //DEBUGpic14_emitcode(";","%d",__LINE__);
491     /* if in bit space */
492     if (IN_BITSPACE(space)) {
493         sym->aop = aop = newAsmop (AOP_CRY);
494         aop->aopu.aop_dir = sym->rname ;
495         aop->size = getSize(sym->type);
496         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
497         return aop;
498     }
499     /* if it is in direct space */
500     if (IN_DIRSPACE(space)) {
501         sym->aop = aop = newAsmop (AOP_DIR);
502         aop->aopu.aop_dir = sym->rname ;
503         aop->size = getSize(sym->type);
504         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
505         return aop;
506     }
507
508     /* special case for a function */
509     if (IS_FUNC(sym->type)) {   
510         sym->aop = aop = newAsmop(AOP_IMMD);    
511         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
512         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
513         strcpy(aop->aopu.aop_immd,sym->rname);
514         aop->size = FPTRSIZE; 
515         return aop;
516     }
517
518
519     /* only remaining is far space */
520     /* in which case DPTR gets the address */
521     sym->aop = aop = newAsmop(AOP_DPTR);
522     pic14_emitcode ("mov","dptr,#%s", sym->rname);
523     aop->size = getSize(sym->type);
524
525     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
526     /* if it is in code space */
527     if (IN_CODESPACE(space))
528         aop->code = 1;
529
530     return aop;     
531 }
532
533 /*-----------------------------------------------------------------*/
534 /* aopForRemat - rematerialzes an object                           */
535 /*-----------------------------------------------------------------*/
536 static asmop *aopForRemat (symbol *sym)
537 {
538     iCode *ic = sym->rematiCode;
539     asmop *aop = newAsmop(AOP_IMMD);
540     int val = 0;
541     DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
542     for (;;) {
543         if (ic->op == '+')
544             val += (int) operandLitValue(IC_RIGHT(ic));
545         else if (ic->op == '-')
546             val -= (int) operandLitValue(IC_RIGHT(ic));
547         else
548             break;
549         
550         ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
551     }
552
553     if (val)
554         sprintf(buffer,"(%s %c 0x%04x)",
555                 OP_SYMBOL(IC_LEFT(ic))->rname, 
556                 val >= 0 ? '+' : '-',
557                 abs(val) & 0xffff);
558     else
559         strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
560
561     //DEBUGpic14_emitcode(";","%s",buffer);
562     aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
563     strcpy(aop->aopu.aop_immd,buffer);    
564     return aop;        
565 }
566
567 int aopIdx (asmop *aop, int offset)
568 {
569   if(!aop)
570     return -1;
571
572   if(aop->type !=  AOP_REG)
573     return -2;
574         
575   return aop->aopu.aop_reg[offset]->rIdx;
576
577 }
578 /*-----------------------------------------------------------------*/
579 /* regsInCommon - two operands have some registers in common       */
580 /*-----------------------------------------------------------------*/
581 static bool regsInCommon (operand *op1, operand *op2)
582 {
583     symbol *sym1, *sym2;
584     int i;
585
586     /* if they have registers in common */
587     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
588         return FALSE ;
589
590     sym1 = OP_SYMBOL(op1);
591     sym2 = OP_SYMBOL(op2);
592
593     if (sym1->nRegs == 0 || sym2->nRegs == 0)
594         return FALSE ;
595
596     for (i = 0 ; i < sym1->nRegs ; i++) {
597         int j;
598         if (!sym1->regs[i])
599             continue ;
600
601         for (j = 0 ; j < sym2->nRegs ;j++ ) {
602             if (!sym2->regs[j])
603                 continue ;
604
605             if (sym2->regs[j] == sym1->regs[i])
606                 return TRUE ;
607         }
608     }
609
610     return FALSE ;
611 }
612
613 /*-----------------------------------------------------------------*/
614 /* operandsEqu - equivalent                                        */
615 /*-----------------------------------------------------------------*/
616 static bool operandsEqu ( operand *op1, operand *op2)
617 {
618     symbol *sym1, *sym2;
619
620     /* if they not symbols */
621     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
622         return FALSE;
623
624     sym1 = OP_SYMBOL(op1);
625     sym2 = OP_SYMBOL(op2);
626
627     /* if both are itemps & one is spilt
628        and the other is not then false */
629     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
630         sym1->isspilt != sym2->isspilt )
631         return FALSE ;
632
633     /* if they are the same */
634     if (sym1 == sym2)
635         return TRUE ;
636
637     if (strcmp(sym1->rname,sym2->rname) == 0)
638         return TRUE;
639
640
641     /* if left is a tmp & right is not */
642     if (IS_ITEMP(op1)  && 
643         !IS_ITEMP(op2) &&
644         sym1->isspilt  &&
645         (sym1->usl.spillLoc == sym2))
646         return TRUE;
647
648     if (IS_ITEMP(op2)  && 
649         !IS_ITEMP(op1) &&
650         sym2->isspilt  &&
651         sym1->level > 0 &&
652         (sym2->usl.spillLoc == sym1))
653         return TRUE ;
654
655     return FALSE ;
656 }
657
658 /*-----------------------------------------------------------------*/
659 /* pic14_sameRegs - two asmops have the same registers                   */
660 /*-----------------------------------------------------------------*/
661 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
662 {
663     int i;
664
665     if (aop1 == aop2)
666         return TRUE ;
667
668     if (aop1->type != AOP_REG ||
669         aop2->type != AOP_REG )
670         return FALSE ;
671
672     if (aop1->size != aop2->size )
673         return FALSE ;
674
675     for (i = 0 ; i < aop1->size ; i++ )
676         if (aop1->aopu.aop_reg[i] !=
677             aop2->aopu.aop_reg[i] )
678             return FALSE ;
679
680     return TRUE ;
681 }
682
683 /*-----------------------------------------------------------------*/
684 /* aopOp - allocates an asmop for an operand  :                    */
685 /*-----------------------------------------------------------------*/
686 void aopOp (operand *op, iCode *ic, bool result)
687 {
688     asmop *aop;
689     symbol *sym;
690     int i;
691
692     if (!op)
693         return ;
694
695     DEBUGpic14_emitcode(";","%d",__LINE__);
696     /* if this a literal */
697     if (IS_OP_LITERAL(op)) {
698         op->aop = aop = newAsmop(AOP_LIT);
699         aop->aopu.aop_lit = op->operand.valOperand;
700         aop->size = getSize(operandType(op));
701       DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
702         return;
703     }
704
705     /* if already has a asmop then continue */
706     if (op->aop)
707         return ;
708
709     /* if the underlying symbol has a aop */
710     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
711       DEBUGpic14_emitcode(";","%d",__LINE__);
712         op->aop = OP_SYMBOL(op)->aop;
713         return;
714     }
715
716     /* if this is a true symbol */
717     if (IS_TRUE_SYMOP(op)) {    
718       DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
719         op->aop = aopForSym(ic,OP_SYMBOL(op),result);
720         return ;
721     }
722
723     /* this is a temporary : this has
724     only four choices :
725     a) register
726     b) spillocation
727     c) rematerialize 
728     d) conditional   
729     e) can be a return use only */
730
731     sym = OP_SYMBOL(op);
732
733
734     /* if the type is a conditional */
735     if (sym->regType == REG_CND) {
736       DEBUGpic14_emitcode(";","%d",__LINE__);
737         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
738         aop->size = 0;
739         return;
740     }
741
742     /* if it is spilt then two situations
743     a) is rematerialize 
744     b) has a spill location */
745     if (sym->isspilt || sym->nRegs == 0) {
746
747       DEBUGpic14_emitcode(";","%d",__LINE__);
748         /* rematerialize it NOW */
749         if (sym->remat) {
750             sym->aop = op->aop = aop =
751                                       aopForRemat (sym);
752             aop->size = getSize(sym->type);
753             DEBUGpic14_emitcode(";","%d",__LINE__);
754             return;
755         }
756
757         if (sym->accuse) {
758             int i;
759             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
760             aop->size = getSize(sym->type);
761             for ( i = 0 ; i < 2 ; i++ )
762                 aop->aopu.aop_str[i] = accUse[i];
763             DEBUGpic14_emitcode(";","%d",__LINE__);
764             return;  
765         }
766
767         if (sym->ruonly ) {
768             unsigned i;
769             aop = op->aop = sym->aop = newAsmop(AOP_STR);
770             aop->size = getSize(sym->type);
771             for ( i = 0 ; i < fReturnSizePic ; i++ )
772               aop->aopu.aop_str[i] = fReturn[i];
773             DEBUGpic14_emitcode(";","%d",__LINE__);
774             return;
775         }
776
777         /* else spill location  */
778         DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
779         sym->aop = op->aop = aop = 
780                                   aopForSym(ic,sym->usl.spillLoc,result);
781         aop->size = getSize(sym->type);
782         return;
783     }
784
785     /* must be in a register */
786     sym->aop = op->aop = aop = newAsmop(AOP_REG);
787     aop->size = sym->nRegs;
788     for ( i = 0 ; i < sym->nRegs ;i++)
789         aop->aopu.aop_reg[i] = sym->regs[i];
790 }
791
792 /*-----------------------------------------------------------------*/
793 /* freeAsmop - free up the asmop given to an operand               */
794 /*----------------------------------------------------------------*/
795 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
796 {   
797     asmop *aop ;
798
799     if (!op)
800         aop = aaop;
801     else 
802         aop = op->aop;
803
804     if (!aop)
805         return ;
806
807     if (aop->freed)
808         goto dealloc; 
809
810     aop->freed = 1;
811
812     /* depending on the asmop type only three cases need work AOP_RO
813        , AOP_R1 && AOP_STK */
814     switch (aop->type) {
815         case AOP_R0 :
816             if (_G.r0Pushed ) {
817                 if (pop) {
818                     pic14_emitcode ("pop","ar0");     
819                     _G.r0Pushed--;
820                 }
821             }
822             bitVectUnSetBit(ic->rUsed,R0_IDX);
823             break;
824
825         case AOP_R1 :
826             if (_G.r1Pushed ) {
827                 if (pop) {
828                     pic14_emitcode ("pop","ar1");
829                     _G.r1Pushed--;
830                 }
831             }
832             bitVectUnSetBit(ic->rUsed,R1_IDX);          
833             break;
834
835         case AOP_STK :
836         {
837             int sz = aop->size;    
838             int stk = aop->aopu.aop_stk + aop->size;
839             bitVectUnSetBit(ic->rUsed,R0_IDX);
840             bitVectUnSetBit(ic->rUsed,R1_IDX);          
841
842             getFreePtr(ic,&aop,FALSE);
843             
844             if (options.stack10bit)
845             {
846                 /* I'm not sure what to do here yet... */
847                 /* #STUB */
848                 fprintf(stderr, 
849                         "*** Warning: probably generating bad code for "
850                         "10 bit stack mode.\n");
851             }
852             
853             if (stk) {
854                 pic14_emitcode ("mov","a,_bp");
855                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
856                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
857             } else {
858                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
859             }
860
861             while (sz--) {
862                 pic14_emitcode("pop","acc");
863                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
864                 if (!sz) break;
865                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
866             }
867             op->aop = aop;
868             freeAsmop(op,NULL,ic,TRUE);
869             if (_G.r0Pushed) {
870                 pic14_emitcode("pop","ar0");
871                 _G.r0Pushed--;
872             }
873
874             if (_G.r1Pushed) {
875                 pic14_emitcode("pop","ar1");
876                 _G.r1Pushed--;
877             }       
878         }
879     }
880
881 dealloc:
882     /* all other cases just dealloc */
883     if (op ) {
884         op->aop = NULL;
885         if (IS_SYMOP(op)) {
886             OP_SYMBOL(op)->aop = NULL;    
887             /* if the symbol has a spill */
888             if (SPIL_LOC(op))
889                 SPIL_LOC(op)->aop = NULL;
890         }
891     }
892 }
893
894 /*-----------------------------------------------------------------*/
895 /* aopGet - for fetching value of the aop                          */
896 /*-----------------------------------------------------------------*/
897 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
898 {
899     char *s = buffer ;
900     char *rs;
901
902     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
903     /* offset is greater than
904     size then zero */
905     if (offset > (aop->size - 1) &&
906         aop->type != AOP_LIT)
907         return zero;
908
909     /* depending on type */
910     switch (aop->type) {
911         
912     case AOP_R0:
913     case AOP_R1:
914         DEBUGpic14_emitcode(";","%d",__LINE__);
915         /* if we need to increment it */       
916         while (offset > aop->coff) {        
917             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
918             aop->coff++;
919         }
920         
921         while (offset < aop->coff) {
922             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
923             aop->coff--;
924         }
925         
926         aop->coff = offset ;
927         if (aop->paged) {
928             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
929             return (dname ? "acc" : "a");
930         }       
931         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
932         rs = Safe_calloc(1,strlen(s)+1);
933         strcpy(rs,s);   
934         return rs;
935         
936     case AOP_DPTR:
937     case AOP_DPTR2:
938         DEBUGpic14_emitcode(";","%d",__LINE__);
939     if (aop->type == AOP_DPTR2)
940     {
941         genSetDPTR(1);
942     }
943     
944         while (offset > aop->coff) {
945             pic14_emitcode ("inc","dptr");
946             aop->coff++;
947         }
948         
949         while (offset < aop->coff) {        
950             pic14_emitcode("lcall","__decdptr");
951             aop->coff--;
952         }
953         
954         aop->coff = offset;
955         if (aop->code) {
956             pic14_emitcode("clr","a");
957             pic14_emitcode("movc","a,@a+dptr");
958         }
959     else {
960             pic14_emitcode("movx","a,@dptr");
961     }
962             
963     if (aop->type == AOP_DPTR2)
964     {
965         genSetDPTR(0);
966     }
967             
968     return (dname ? "acc" : "a");
969         
970         
971     case AOP_IMMD:
972       DEBUGpic14_emitcode(";","%d",__LINE__);
973         if (bit16) 
974             sprintf (s,"%s",aop->aopu.aop_immd);
975         else
976             if (offset) 
977                 sprintf(s,"(%s >> %d)",
978                         aop->aopu.aop_immd,
979                         offset*8);
980             else
981                 sprintf(s,"%s",
982                         aop->aopu.aop_immd);
983         rs = Safe_calloc(1,strlen(s)+1);
984         strcpy(rs,s);   
985         return rs;
986         
987     case AOP_DIR:
988         if (offset)
989             sprintf(s,"(%s + %d)",
990                     aop->aopu.aop_dir,
991                     offset);
992         else
993             sprintf(s,"%s",aop->aopu.aop_dir);
994         rs = Safe_calloc(1,strlen(s)+1);
995         strcpy(rs,s);   
996         return rs;
997         
998     case AOP_REG:
999       DEBUGpic14_emitcode(";","%d",__LINE__);
1000         if (dname) 
1001             return aop->aopu.aop_reg[offset]->dname;
1002         else
1003             return aop->aopu.aop_reg[offset]->name;
1004         
1005     case AOP_CRY:
1006       pic14_emitcode(";","%d",__LINE__);
1007       //pic14_emitcode("clr","a");
1008       //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1009       //pic14_emitcode("rlc","a") ;
1010       //return (dname ? "acc" : "a");
1011       return aop->aopu.aop_dir;
1012         
1013     case AOP_ACC:
1014         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1015         //if (!offset && dname)
1016         //    return "acc";
1017         //return aop->aopu.aop_str[offset];
1018         return "AOP_accumulator_bug";
1019
1020     case AOP_LIT:
1021         DEBUGpic14_emitcode(";","%d",__LINE__);
1022         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1023         rs = Safe_calloc(1,strlen(s)+1);
1024         strcpy(rs,s);   
1025         return rs;
1026         
1027     case AOP_STR:
1028         DEBUGpic14_emitcode(";","%d",__LINE__);
1029         aop->coff = offset ;
1030         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1031             dname)
1032             return "acc";
1033         
1034         return aop->aopu.aop_str[offset];
1035         
1036     }
1037
1038     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1039            "aopget got unsupported aop->type");
1040     exit(0);
1041 }
1042
1043 /*-----------------------------------------------------------------*/
1044 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1045 /*-----------------------------------------------------------------*/
1046 pCodeOp *popGetLabel(unsigned int key)
1047 {
1048
1049   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1050
1051   if(key>max_key)
1052     max_key = key;
1053
1054   return newpCodeOpLabel(key+100+labelOffset);
1055 }
1056
1057 /*-----------------------------------------------------------------*/
1058 /* popCopyReg - copy a pcode operator                              */
1059 /*-----------------------------------------------------------------*/
1060 pCodeOp *popCopyReg(pCodeOpReg *pc)
1061 {
1062   pCodeOpReg *pcor;
1063
1064   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1065   pcor->pcop.type = pc->pcop.type;
1066   if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1067     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1068   pcor->r = pc->r;
1069   pcor->rIdx = pc->rIdx;
1070
1071
1072   return PCOP(pcor);
1073 }
1074
1075 /*-----------------------------------------------------------------*/
1076 /* popCopy - copy a pcode operator                                 */
1077 /*-----------------------------------------------------------------*/
1078 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1079 {
1080   pCodeOp *pcop;
1081
1082   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1083   pcop->type = PO_BIT;
1084   if(!(pcop->name = Safe_strdup(pc->name)))
1085     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1086   ((pCodeOpBit *)pcop)->bit = bitval;
1087
1088   ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1089
1090   return pcop;
1091 }
1092
1093 /*-----------------------------------------------------------------*/
1094 /* popGet - asm operator to pcode operator conversion              */
1095 /*-----------------------------------------------------------------*/
1096 pCodeOp *popGetLit(unsigned int lit)
1097 {
1098
1099   return newpCodeOpLit(lit);
1100 }
1101
1102
1103 /*-----------------------------------------------------------------*/
1104 /* popGet - asm operator to pcode operator conversion              */
1105 /*-----------------------------------------------------------------*/
1106 pCodeOp *popGetWithString(char *str)
1107 {
1108   pCodeOp *pcop;
1109
1110
1111   if(!str) {
1112     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1113     exit (1);
1114   }
1115
1116   pcop = newpCodeOp(str,PO_STR);
1117
1118   return pcop;
1119 }
1120
1121 pCodeOp *popRegFromString(char *str)
1122 {
1123
1124   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1125   pcop->type = PO_GPR_REGISTER;
1126
1127   PCOR(pcop)->rIdx = -1;
1128   PCOR(pcop)->r = NULL;
1129
1130   DEBUGpic14_emitcode(";","%d",__LINE__);
1131   pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1132
1133   return pcop;
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* popGet - asm operator to pcode operator conversion              */
1138 /*-----------------------------------------------------------------*/
1139 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1140 {
1141     char *s = buffer ;
1142     char *rs;
1143
1144     pCodeOp *pcop;
1145
1146     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1147     /* offset is greater than
1148     size then zero */
1149
1150     if (offset > (aop->size - 1) &&
1151         aop->type != AOP_LIT)
1152       return NULL;  //zero;
1153
1154     /* depending on type */
1155     switch (aop->type) {
1156         
1157     case AOP_R0:
1158     case AOP_R1:
1159     case AOP_DPTR:
1160     case AOP_DPTR2:
1161     case AOP_ACC:
1162         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1163         //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1164         //pcop->type = PO_SFR_REGISTER;
1165
1166         //PCOR(pcop)->rIdx = -1;
1167         //PCOR(pcop)->r = NULL;
1168         // Really nasty hack to check for temporary registers
1169
1170         //pcop->name = Safe_strdup("BAD_REGISTER");
1171
1172         return NULL;
1173         
1174     case AOP_IMMD:
1175       DEBUGpic14_emitcode(";","%d",__LINE__);
1176         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1177         pcop->type = PO_IMMEDIATE;
1178         if (bit16) 
1179             sprintf (s,"%s",aop->aopu.aop_immd);
1180         else
1181             if (offset) 
1182                 sprintf(s,"(%s >> %d)",
1183                         aop->aopu.aop_immd,
1184                         offset*8);
1185             else
1186                 sprintf(s,"%s",
1187                         aop->aopu.aop_immd);
1188         pcop->name = Safe_calloc(1,strlen(s)+1);
1189         strcpy(pcop->name,s);   
1190         return pcop;
1191         
1192     case AOP_DIR:
1193         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1194         pcop->type = PO_DIR;
1195         if (offset)
1196             sprintf(s,"(%s + %d)",
1197                     aop->aopu.aop_dir,
1198                     offset);
1199         else
1200             sprintf(s,"%s",aop->aopu.aop_dir);
1201         pcop->name = Safe_calloc(1,strlen(s)+1);
1202         strcpy(pcop->name,s);   
1203         return pcop;
1204         
1205     case AOP_REG:
1206       {
1207         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1208
1209         DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1210         if(bit16)
1211           pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1212         else
1213           pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1214         //pcop->type = PO_GPR_REGISTER;
1215         PCOR(pcop)->rIdx = rIdx;
1216         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1217         pcop->type = PCOR(pcop)->r->pc_type;
1218
1219         if (dname)
1220           rs = aop->aopu.aop_reg[offset]->dname;
1221         else 
1222           rs = aop->aopu.aop_reg[offset]->name;
1223
1224         DEBUGpic14_emitcode(";","%d  %s",__LINE__,rs);
1225
1226         return pcop;
1227       }
1228
1229     case AOP_CRY:
1230       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1231       return pcop;
1232         
1233     case AOP_LIT:
1234       DEBUGpic14_emitcode(";","%d",__LINE__);
1235       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1236
1237     case AOP_STR:
1238       DEBUGpic14_emitcode(";","%d",__LINE__);
1239
1240       pcop = Safe_calloc(1,sizeof(pCodeOp) );
1241       pcop->type = PO_STR;
1242
1243       //aop->coff = offset ;
1244         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1245           sprintf(s,"%s","acc");
1246         else
1247           sprintf(s,"%s",aop->aopu.aop_str[offset]);
1248         pcop->name = Safe_calloc(1,strlen(s)+1);
1249         strcpy(pcop->name,s);   
1250         return pcop;
1251         
1252     }
1253
1254     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1255            "popGet got unsupported aop->type");
1256     exit(0);
1257 }
1258 /*-----------------------------------------------------------------*/
1259 /* aopPut - puts a string for a aop                                */
1260 /*-----------------------------------------------------------------*/
1261 void aopPut (asmop *aop, char *s, int offset)
1262 {
1263     char *d = buffer ;
1264     symbol *lbl ;
1265
1266     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1267
1268     if (aop->size && offset > ( aop->size - 1)) {
1269         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1270                "aopPut got offset > aop->size");
1271         exit(0);
1272     }
1273
1274     /* will assign value to value */
1275     /* depending on where it is ofcourse */
1276     switch (aop->type) {
1277     case AOP_DIR:
1278         if (offset)
1279             sprintf(d,"(%s + %d)",
1280                     aop->aopu.aop_dir,offset);
1281         else
1282             sprintf(d,"%s",aop->aopu.aop_dir);
1283         
1284         if (strcmp(d,s)) {
1285           DEBUGpic14_emitcode(";","%d",__LINE__);
1286           if(strcmp(s,"W"))
1287             pic14_emitcode("movf","%s,w",s);
1288           pic14_emitcode("movwf","%s",d);
1289
1290           if(strcmp(s,"W"))
1291             pic14_emitcode(";BUG! should have this:movf","%s,w   %d",s,__LINE__);
1292           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1293
1294
1295         }
1296         break;
1297         
1298     case AOP_REG:
1299         if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1300             strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1301           /*
1302             if (*s == '@'           ||
1303                 strcmp(s,"r0") == 0 ||
1304                 strcmp(s,"r1") == 0 ||
1305                 strcmp(s,"r2") == 0 ||
1306                 strcmp(s,"r3") == 0 ||
1307                 strcmp(s,"r4") == 0 ||
1308                 strcmp(s,"r5") == 0 ||
1309                 strcmp(s,"r6") == 0 || 
1310                 strcmp(s,"r7") == 0 )
1311                 pic14_emitcode("mov","%s,%s  ; %d",
1312                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1313             else
1314           */
1315
1316           if(strcmp(s,"W"))
1317             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1318
1319           pic14_emitcode("movwf","%s",
1320                    aop->aopu.aop_reg[offset]->name);
1321
1322           if(strcmp(s,"W")) {
1323             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1324             pcop->type = PO_GPR_REGISTER;
1325
1326             PCOR(pcop)->rIdx = -1;
1327             PCOR(pcop)->r = NULL;
1328
1329             DEBUGpic14_emitcode(";","%d",__LINE__);
1330             pcop->name = Safe_strdup(s);
1331             emitpcode(POC_MOVFW,pcop);
1332           }
1333           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1334
1335         }
1336         break;
1337         
1338     case AOP_DPTR:
1339     case AOP_DPTR2:
1340     
1341     if (aop->type == AOP_DPTR2)
1342     {
1343         genSetDPTR(1);
1344     }
1345     
1346         if (aop->code) {
1347             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1348                    "aopPut writting to code space");
1349             exit(0);
1350         }
1351         
1352         while (offset > aop->coff) {
1353             aop->coff++;
1354             pic14_emitcode ("inc","dptr");
1355         }
1356         
1357         while (offset < aop->coff) {
1358             aop->coff-- ;
1359             pic14_emitcode("lcall","__decdptr");
1360         }
1361         
1362         aop->coff = offset;
1363         
1364         /* if not in accumulater */
1365         MOVA(s);        
1366         
1367         pic14_emitcode ("movx","@dptr,a");
1368         
1369     if (aop->type == AOP_DPTR2)
1370     {
1371         genSetDPTR(0);
1372     }
1373         break;
1374         
1375     case AOP_R0:
1376     case AOP_R1:
1377         while (offset > aop->coff) {
1378             aop->coff++;
1379             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1380         }
1381         while (offset < aop->coff) {
1382             aop->coff-- ;
1383             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1384         }
1385         aop->coff = offset;
1386         
1387         if (aop->paged) {
1388             MOVA(s);           
1389             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1390             
1391         } else
1392             if (*s == '@') {
1393                 MOVA(s);
1394                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1395             } else
1396                 if (strcmp(s,"r0") == 0 ||
1397                     strcmp(s,"r1") == 0 ||
1398                     strcmp(s,"r2") == 0 ||
1399                     strcmp(s,"r3") == 0 ||
1400                     strcmp(s,"r4") == 0 ||
1401                     strcmp(s,"r5") == 0 ||
1402                     strcmp(s,"r6") == 0 || 
1403                     strcmp(s,"r7") == 0 ) {
1404                     char buffer[10];
1405                     sprintf(buffer,"a%s",s);
1406                     pic14_emitcode("mov","@%s,%s",
1407                              aop->aopu.aop_ptr->name,buffer);
1408                 } else
1409                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1410         
1411         break;
1412         
1413     case AOP_STK:
1414         if (strcmp(s,"a") == 0)
1415             pic14_emitcode("push","acc");
1416         else
1417             pic14_emitcode("push","%s",s);
1418         
1419         break;
1420         
1421     case AOP_CRY:
1422         /* if bit variable */
1423         if (!aop->aopu.aop_dir) {
1424             pic14_emitcode("clr","a");
1425             pic14_emitcode("rlc","a");
1426         } else {
1427             if (s == zero) 
1428                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1429             else
1430                 if (s == one)
1431                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1432                 else
1433                     if (!strcmp(s,"c"))
1434                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1435                     else {
1436                         lbl = newiTempLabel(NULL);
1437                         
1438                         if (strcmp(s,"a")) {
1439                             MOVA(s);
1440                         }
1441                         pic14_emitcode("clr","c");
1442                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1443                         pic14_emitcode("cpl","c");
1444                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1445                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1446                     }
1447         }
1448         break;
1449         
1450     case AOP_STR:
1451         aop->coff = offset;
1452         if (strcmp(aop->aopu.aop_str[offset],s))
1453             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1454         break;
1455         
1456     case AOP_ACC:
1457         aop->coff = offset;
1458         if (!offset && (strcmp(s,"acc") == 0))
1459             break;
1460         
1461         if (strcmp(aop->aopu.aop_str[offset],s))
1462             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1463         break;
1464
1465     default :
1466         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1467                "aopPut got unsupported aop->type");
1468         exit(0);    
1469     }    
1470
1471 }
1472
1473 /*-----------------------------------------------------------------*/
1474 /* reAdjustPreg - points a register back to where it should        */
1475 /*-----------------------------------------------------------------*/
1476 static void reAdjustPreg (asmop *aop)
1477 {
1478     int size ;
1479
1480     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1481     aop->coff = 0;
1482     if ((size = aop->size) <= 1)
1483         return ;
1484     size-- ;
1485     switch (aop->type) {
1486         case AOP_R0 :
1487         case AOP_R1 :
1488             while (size--)
1489                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1490             break;          
1491         case AOP_DPTR :
1492         case AOP_DPTR2:
1493             if (aop->type == AOP_DPTR2)
1494             {
1495                 genSetDPTR(1);
1496             } 
1497             while (size--)
1498             {
1499                 pic14_emitcode("lcall","__decdptr");
1500             }
1501                 
1502             if (aop->type == AOP_DPTR2)
1503             {
1504                 genSetDPTR(0);
1505             }                
1506             break;  
1507
1508     }   
1509
1510 }
1511
1512 /*-----------------------------------------------------------------*/
1513 /* genNotFloat - generates not for float operations              */
1514 /*-----------------------------------------------------------------*/
1515 static void genNotFloat (operand *op, operand *res)
1516 {
1517     int size, offset;
1518     char *l;
1519     symbol *tlbl ;
1520
1521     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1522     /* we will put 127 in the first byte of 
1523     the result */
1524     aopPut(AOP(res),"#127",0);
1525     size = AOP_SIZE(op) - 1;
1526     offset = 1;
1527
1528     l = aopGet(op->aop,offset++,FALSE,FALSE);
1529     MOVA(l);    
1530
1531     while(size--) {
1532         pic14_emitcode("orl","a,%s",
1533                  aopGet(op->aop,
1534                         offset++,FALSE,FALSE));
1535     }
1536     tlbl = newiTempLabel(NULL);
1537
1538     tlbl = newiTempLabel(NULL);
1539     aopPut(res->aop,one,1);
1540     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1541     aopPut(res->aop,zero,1);
1542     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1543
1544     size = res->aop->size - 2;
1545     offset = 2;    
1546     /* put zeros in the rest */
1547     while (size--) 
1548         aopPut(res->aop,zero,offset++);
1549 }
1550
1551 #if 0
1552 /*-----------------------------------------------------------------*/
1553 /* opIsGptr: returns non-zero if the passed operand is             */   
1554 /* a generic pointer type.                                         */
1555 /*-----------------------------------------------------------------*/ 
1556 static int opIsGptr(operand *op)
1557 {
1558     sym_link *type = operandType(op);
1559     
1560     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1561     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1562     {
1563         return 1;
1564     }
1565     return 0;        
1566 }
1567 #endif
1568
1569 /*-----------------------------------------------------------------*/
1570 /* pic14_getDataSize - get the operand data size                         */
1571 /*-----------------------------------------------------------------*/
1572 int pic14_getDataSize(operand *op)
1573 {
1574     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1575
1576
1577     return AOP_SIZE(op);
1578
1579     // tsd- in the pic port, the genptr size is 1, so this code here
1580     // fails. ( in the 8051 port, the size was 4).
1581 #if 0
1582     int size;
1583     size = AOP_SIZE(op);
1584     if (size == GPTRSIZE)
1585     {
1586         sym_link *type = operandType(op);
1587         if (IS_GENPTR(type))
1588         {
1589             /* generic pointer; arithmetic operations
1590              * should ignore the high byte (pointer type).
1591              */
1592             size--;
1593     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1594         }
1595     }
1596     return size;
1597 #endif
1598 }
1599
1600 /*-----------------------------------------------------------------*/
1601 /* pic14_outAcc - output Acc                                             */
1602 /*-----------------------------------------------------------------*/
1603 void pic14_outAcc(operand *result)
1604 {
1605
1606     DEBUGpic14_emitcode ("; ***","%s  %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1607
1608 #if 0
1609     size = pic14_getDataSize(result);
1610     if(size){
1611         aopPut(AOP(result),"a",0);
1612         size--;
1613         offset = 1;
1614         /* unsigned or positive */
1615         while(size--){
1616             aopPut(AOP(result),zero,offset++);
1617         }
1618     }
1619 #endif
1620 }
1621
1622 /*-----------------------------------------------------------------*/
1623 /* pic14_outBitC - output a bit C                                        */
1624 /*-----------------------------------------------------------------*/
1625 void pic14_outBitC(operand *result)
1626 {
1627
1628     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1629     /* if the result is bit */
1630     if (AOP_TYPE(result) == AOP_CRY) 
1631         aopPut(AOP(result),"c",0);
1632     else {
1633         pic14_emitcode("clr","a  ; %d", __LINE__);
1634         pic14_emitcode("rlc","a");
1635         pic14_outAcc(result);
1636     }
1637 }
1638
1639 /*-----------------------------------------------------------------*/
1640 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1641 /*-----------------------------------------------------------------*/
1642 void pic14_toBoolean(operand *oper)
1643 {
1644     int size = AOP_SIZE(oper) - 1;
1645     int offset = 1;
1646
1647     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1648
1649     if ( AOP_TYPE(oper) != AOP_ACC) {
1650       emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1651       pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1652     }
1653     while (size--) {
1654       pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1655       emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1656     }
1657 }
1658
1659
1660 /*-----------------------------------------------------------------*/
1661 /* genNot - generate code for ! operation                          */
1662 /*-----------------------------------------------------------------*/
1663 static void genNot (iCode *ic)
1664 {
1665     symbol *tlbl;
1666     sym_link *optype = operandType(IC_LEFT(ic));
1667
1668     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1669     /* assign asmOps to operand & result */
1670     aopOp (IC_LEFT(ic),ic,FALSE);
1671     aopOp (IC_RESULT(ic),ic,TRUE);
1672
1673     /* if in bit space then a special case */
1674     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1675       pic14_emitcode("movlw","1<<%s");
1676       //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1677       //pic14_emitcode("cpl","c"); 
1678       //pic14_outBitC(IC_RESULT(ic));
1679       goto release;
1680     }
1681
1682     /* if type float then do float */
1683     if (IS_FLOAT(optype)) {
1684         genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1685         goto release;
1686     }
1687
1688     pic14_toBoolean(IC_LEFT(ic));
1689
1690     tlbl = newiTempLabel(NULL);
1691     pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1692     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1693     pic14_outBitC(IC_RESULT(ic));
1694
1695 release:    
1696     /* release the aops */
1697     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1698     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1699 }
1700
1701
1702 /*-----------------------------------------------------------------*/
1703 /* genCpl - generate code for complement                           */
1704 /*-----------------------------------------------------------------*/
1705 static void genCpl (iCode *ic)
1706 {
1707     int offset = 0;
1708     int size ;
1709
1710
1711     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1712     /* assign asmOps to operand & result */
1713     aopOp (IC_LEFT(ic),ic,FALSE);
1714     aopOp (IC_RESULT(ic),ic,TRUE);
1715
1716     /* if both are in bit space then 
1717     a special case */
1718     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1719         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1720
1721         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1722         pic14_emitcode("cpl","c"); 
1723         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1724         goto release; 
1725     } 
1726
1727     size = AOP_SIZE(IC_RESULT(ic));
1728     while (size--) {
1729         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1730         MOVA(l);       
1731         pic14_emitcode("cpl","a");
1732         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1733     }
1734
1735
1736 release:
1737     /* release the aops */
1738     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1739     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1740 }
1741
1742 /*-----------------------------------------------------------------*/
1743 /* genUminusFloat - unary minus for floating points                */
1744 /*-----------------------------------------------------------------*/
1745 static void genUminusFloat(operand *op,operand *result)
1746 {
1747     int size ,offset =0 ;
1748     char *l;
1749
1750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1751     /* for this we just need to flip the 
1752     first it then copy the rest in place */
1753     size = AOP_SIZE(op) - 1;
1754     l = aopGet(AOP(op),3,FALSE,FALSE);
1755
1756     MOVA(l);    
1757
1758     pic14_emitcode("cpl","acc.7");
1759     aopPut(AOP(result),"a",3);    
1760
1761     while(size--) {
1762         aopPut(AOP(result),
1763                aopGet(AOP(op),offset,FALSE,FALSE),
1764                offset);
1765         offset++;
1766     }          
1767 }
1768
1769 /*-----------------------------------------------------------------*/
1770 /* genUminus - unary minus code generation                         */
1771 /*-----------------------------------------------------------------*/
1772 static void genUminus (iCode *ic)
1773 {
1774     int offset ,size ;
1775     sym_link *optype, *rtype;
1776
1777
1778     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1779     /* assign asmops */
1780     aopOp(IC_LEFT(ic),ic,FALSE);
1781     aopOp(IC_RESULT(ic),ic,TRUE);
1782
1783     /* if both in bit space then special
1784     case */
1785     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1786         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1787
1788         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1789         pic14_emitcode("cpl","c"); 
1790         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1791         goto release; 
1792     } 
1793
1794     optype = operandType(IC_LEFT(ic));
1795     rtype = operandType(IC_RESULT(ic));
1796
1797     /* if float then do float stuff */
1798     if (IS_FLOAT(optype)) {
1799         genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1800         goto release;
1801     }
1802
1803     /* otherwise subtract from zero */
1804     size = AOP_SIZE(IC_LEFT(ic));
1805     offset = 0 ;
1806     CLRC ;
1807     while(size--) {
1808         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1809         if (!strcmp(l,"a")) {
1810             pic14_emitcode("cpl","a");
1811             pic14_emitcode("inc","a");
1812         } else {
1813             pic14_emitcode("clr","a");
1814             pic14_emitcode("subb","a,%s",l);
1815         }       
1816         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1817     }
1818
1819     /* if any remaining bytes in the result */
1820     /* we just need to propagate the sign   */
1821     if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1822         pic14_emitcode("rlc","a");
1823         pic14_emitcode("subb","a,acc");
1824         while (size--) 
1825             aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1826     }       
1827
1828 release:
1829     /* release the aops */
1830     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1831     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1832 }
1833
1834 /*-----------------------------------------------------------------*/
1835 /* saveRegisters - will look for a call and save the registers     */
1836 /*-----------------------------------------------------------------*/
1837 static void saveRegisters(iCode *lic) 
1838 {
1839     int i;
1840     iCode *ic;
1841     bitVect *rsave;
1842     sym_link *dtype;
1843
1844     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1845     /* look for call */
1846     for (ic = lic ; ic ; ic = ic->next) 
1847         if (ic->op == CALL || ic->op == PCALL)
1848             break;
1849
1850     if (!ic) {
1851         fprintf(stderr,"found parameter push with no function call\n");
1852         return ;
1853     }
1854
1855     /* if the registers have been saved already then
1856     do nothing */
1857     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1858         return ;
1859
1860     /* find the registers in use at this time 
1861     and push them away to safety */
1862     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1863                           ic->rUsed);
1864
1865     ic->regsSaved = 1;
1866     if (options.useXstack) {
1867         if (bitVectBitValue(rsave,R0_IDX))
1868             pic14_emitcode("mov","b,r0");
1869         pic14_emitcode("mov","r0,%s",spname);
1870         for (i = 0 ; i < pic14_nRegs ; i++) {
1871             if (bitVectBitValue(rsave,i)) {
1872                 if (i == R0_IDX)
1873                     pic14_emitcode("mov","a,b");
1874                 else
1875                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1876                 pic14_emitcode("movx","@r0,a");
1877                 pic14_emitcode("inc","r0");
1878             }
1879         }
1880         pic14_emitcode("mov","%s,r0",spname);
1881         if (bitVectBitValue(rsave,R0_IDX))
1882             pic14_emitcode("mov","r0,b");           
1883     } else
1884         for (i = 0 ; i < pic14_nRegs ; i++) {
1885             if (bitVectBitValue(rsave,i))
1886                 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1887         }
1888
1889     dtype = operandType(IC_LEFT(ic));
1890     if (dtype        && 
1891         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1892         IFFUNC_ISISR(currFunc->type) &&
1893         !ic->bankSaved) 
1894
1895         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1896
1897 }
1898 /*-----------------------------------------------------------------*/
1899 /* unsaveRegisters - pop the pushed registers                      */
1900 /*-----------------------------------------------------------------*/
1901 static void unsaveRegisters (iCode *ic)
1902 {
1903     int i;
1904     bitVect *rsave;
1905
1906     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1907     /* find the registers in use at this time 
1908     and push them away to safety */
1909     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1910                           ic->rUsed);
1911     
1912     if (options.useXstack) {
1913         pic14_emitcode("mov","r0,%s",spname);   
1914         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1915             if (bitVectBitValue(rsave,i)) {
1916                 pic14_emitcode("dec","r0");
1917                 pic14_emitcode("movx","a,@r0");
1918                 if (i == R0_IDX)
1919                     pic14_emitcode("mov","b,a");
1920                 else
1921                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1922             }       
1923
1924         }
1925         pic14_emitcode("mov","%s,r0",spname);
1926         if (bitVectBitValue(rsave,R0_IDX))
1927             pic14_emitcode("mov","r0,b");
1928     } else
1929         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1930             if (bitVectBitValue(rsave,i))
1931                 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1932         }
1933
1934 }  
1935
1936
1937 /*-----------------------------------------------------------------*/
1938 /* pushSide -                                                      */
1939 /*-----------------------------------------------------------------*/
1940 static void pushSide(operand * oper, int size)
1941 {
1942         int offset = 0;
1943     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1944         while (size--) {
1945                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1946                 if (AOP_TYPE(oper) != AOP_REG &&
1947                     AOP_TYPE(oper) != AOP_DIR &&
1948                     strcmp(l,"a") ) {
1949                         pic14_emitcode("mov","a,%s",l);
1950                         pic14_emitcode("push","acc");
1951                 } else
1952                         pic14_emitcode("push","%s",l);
1953         }
1954 }
1955
1956 /*-----------------------------------------------------------------*/
1957 /* assignResultValue -                                             */
1958 /*-----------------------------------------------------------------*/
1959 static void assignResultValue(operand * oper)
1960 {
1961         int offset = 0;
1962         int size = AOP_SIZE(oper);
1963
1964     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1965
1966     // The last byte in the assignment is in W
1967     aopPut(AOP(oper),"W",size-1);
1968
1969     if(size>1) {
1970       while (--size) {
1971         aopPut(AOP(oper),fReturn[offset],offset);
1972         offset++;
1973
1974       }
1975     }
1976 }
1977
1978
1979 /*-----------------------------------------------------------------*/
1980 /* genXpush - pushes onto the external stack                       */
1981 /*-----------------------------------------------------------------*/
1982 static void genXpush (iCode *ic)
1983 {
1984     asmop *aop = newAsmop(0);
1985     regs *r ;
1986     int size,offset = 0;
1987
1988     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1989     aopOp(IC_LEFT(ic),ic,FALSE);
1990     r = getFreePtr(ic,&aop,FALSE);
1991
1992     
1993     pic14_emitcode("mov","%s,_spx",r->name);
1994
1995     size = AOP_SIZE(IC_LEFT(ic));
1996     while(size--) {
1997
1998         char *l = aopGet(AOP(IC_LEFT(ic)),
1999                          offset++,FALSE,FALSE); 
2000         MOVA(l);            
2001         pic14_emitcode("movx","@%s,a",r->name); 
2002         pic14_emitcode("inc","%s",r->name);
2003
2004     }
2005
2006         
2007     pic14_emitcode("mov","_spx,%s",r->name);
2008
2009     freeAsmop(NULL,aop,ic,TRUE);
2010     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2011 }
2012
2013 /*-----------------------------------------------------------------*/
2014 /* genIpush - genrate code for pushing this gets a little complex  */
2015 /*-----------------------------------------------------------------*/
2016 static void genIpush (iCode *ic)
2017 {
2018     int size, offset = 0 ;
2019     char *l;
2020
2021
2022     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2023     /* if this is not a parm push : ie. it is spill push 
2024     and spill push is always done on the local stack */
2025     if (!ic->parmPush) {
2026
2027         /* and the item is spilt then do nothing */
2028         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2029             return ;
2030
2031         aopOp(IC_LEFT(ic),ic,FALSE);
2032         size = AOP_SIZE(IC_LEFT(ic));
2033         /* push it on the stack */
2034         while(size--) {
2035             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2036             if (*l == '#') {
2037                 MOVA(l);
2038                 l = "acc";
2039             }
2040             pic14_emitcode("push","%s",l);
2041         }
2042         return ;        
2043     }
2044
2045     /* this is a paramter push: in this case we call
2046     the routine to find the call and save those
2047     registers that need to be saved */   
2048     saveRegisters(ic);
2049
2050     /* if use external stack then call the external
2051     stack pushing routine */
2052     if (options.useXstack) {
2053         genXpush(ic);
2054         return ;
2055     }
2056
2057     /* then do the push */
2058     aopOp(IC_LEFT(ic),ic,FALSE);
2059
2060
2061         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2062     size = AOP_SIZE(IC_LEFT(ic));
2063
2064     while (size--) {
2065         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2066         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2067             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2068             strcmp(l,"a") ) {
2069             pic14_emitcode("mov","a,%s",l);
2070             pic14_emitcode("push","acc");
2071         } else
2072             pic14_emitcode("push","%s",l);
2073     }       
2074
2075     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2076 }
2077
2078 /*-----------------------------------------------------------------*/
2079 /* genIpop - recover the registers: can happen only for spilling   */
2080 /*-----------------------------------------------------------------*/
2081 static void genIpop (iCode *ic)
2082 {
2083     int size,offset ;
2084
2085
2086     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2087     /* if the temp was not pushed then */
2088     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2089         return ;
2090
2091     aopOp(IC_LEFT(ic),ic,FALSE);
2092     size = AOP_SIZE(IC_LEFT(ic));
2093     offset = (size-1);
2094     while (size--) 
2095         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2096                                    FALSE,TRUE));
2097
2098     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2099 }
2100
2101 /*-----------------------------------------------------------------*/
2102 /* unsaverbank - restores the resgister bank from stack            */
2103 /*-----------------------------------------------------------------*/
2104 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2105 {
2106     int i;
2107     asmop *aop ;
2108     regs *r = NULL;
2109
2110     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2111     if (popPsw) {
2112         if (options.useXstack) {
2113             aop = newAsmop(0);
2114             r = getFreePtr(ic,&aop,FALSE);
2115             
2116             
2117             pic14_emitcode("mov","%s,_spx",r->name);
2118             pic14_emitcode("movx","a,@%s",r->name);
2119             pic14_emitcode("mov","psw,a");
2120             pic14_emitcode("dec","%s",r->name);
2121             
2122         }else
2123             pic14_emitcode ("pop","psw");
2124     }
2125
2126     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2127         if (options.useXstack) {       
2128             pic14_emitcode("movx","a,@%s",r->name);
2129             //pic14_emitcode("mov","(%s+%d),a",
2130             //       regspic14[i].base,8*bank+regspic14[i].offset);
2131             pic14_emitcode("dec","%s",r->name);
2132
2133         } else 
2134           pic14_emitcode("pop",""); //"(%s+%d)",
2135         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2136     }
2137
2138     if (options.useXstack) {
2139
2140         pic14_emitcode("mov","_spx,%s",r->name);
2141         freeAsmop(NULL,aop,ic,TRUE);
2142
2143     } 
2144 }
2145
2146 /*-----------------------------------------------------------------*/
2147 /* saverbank - saves an entire register bank on the stack          */
2148 /*-----------------------------------------------------------------*/
2149 static void saverbank (int bank, iCode *ic, bool pushPsw)
2150 {
2151     int i;
2152     asmop *aop ;
2153     regs *r = NULL;
2154
2155     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2156     if (options.useXstack) {
2157
2158         aop = newAsmop(0);
2159         r = getFreePtr(ic,&aop,FALSE);  
2160         pic14_emitcode("mov","%s,_spx",r->name);
2161
2162     }
2163
2164     for (i = 0 ; i < pic14_nRegs ;i++) {
2165         if (options.useXstack) {
2166             pic14_emitcode("inc","%s",r->name);
2167             //pic14_emitcode("mov","a,(%s+%d)",
2168             //         regspic14[i].base,8*bank+regspic14[i].offset);
2169             pic14_emitcode("movx","@%s,a",r->name);           
2170         } else 
2171           pic14_emitcode("push","");// "(%s+%d)",
2172                      //regspic14[i].base,8*bank+regspic14[i].offset);
2173     }
2174     
2175     if (pushPsw) {
2176         if (options.useXstack) {
2177             pic14_emitcode("mov","a,psw");
2178             pic14_emitcode("movx","@%s,a",r->name);     
2179             pic14_emitcode("inc","%s",r->name);
2180             pic14_emitcode("mov","_spx,%s",r->name);       
2181             freeAsmop (NULL,aop,ic,TRUE);
2182             
2183         } else
2184             pic14_emitcode("push","psw");
2185         
2186         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2187     }
2188     ic->bankSaved = 1;
2189
2190 }
2191
2192 /*-----------------------------------------------------------------*/
2193 /* genCall - generates a call statement                            */
2194 /*-----------------------------------------------------------------*/
2195 static void genCall (iCode *ic)
2196 {
2197     sym_link *dtype;   
2198
2199     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2200
2201     /* if caller saves & we have not saved then */
2202     if (!ic->regsSaved)
2203         saveRegisters(ic);
2204
2205     /* if we are calling a function that is not using
2206     the same register bank then we need to save the
2207     destination registers on the stack */
2208     dtype = operandType(IC_LEFT(ic));
2209     if (dtype        && 
2210         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2211         IFFUNC_ISISR(currFunc->type) &&
2212         !ic->bankSaved) 
2213
2214         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2215
2216     /* if send set is not empty the assign */
2217     if (_G.sendSet) {
2218         iCode *sic ;
2219
2220         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2221              sic = setNextItem(_G.sendSet)) {
2222             int size, offset = 0;
2223
2224             aopOp(IC_LEFT(sic),sic,FALSE);
2225             size = AOP_SIZE(IC_LEFT(sic));
2226             while (size--) {
2227                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2228                                 FALSE,FALSE);
2229                 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2230
2231                 if (strcmp(l,fReturn[offset])) {
2232
2233                   if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2234                        ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2235                     emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2236                   //pic14_emitcode("movlw","%s",l);
2237                   else
2238                     emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2239                   //pic14_emitcode("movf","%s,w",l);
2240
2241                   // The last one is passed in W
2242                   if(size)
2243                     pic14_emitcode("movwf","%s",fReturn[offset]);
2244                 }
2245                 offset++;
2246             }
2247             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2248         }
2249         _G.sendSet = NULL;
2250     }
2251     /* make the call */
2252     emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2253                                         OP_SYMBOL(IC_LEFT(ic))->rname :
2254                                         OP_SYMBOL(IC_LEFT(ic))->name));
2255
2256     pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2257                            OP_SYMBOL(IC_LEFT(ic))->rname :
2258                            OP_SYMBOL(IC_LEFT(ic))->name));
2259
2260     /* if we need assign a result value */
2261     if ((IS_ITEMP(IC_RESULT(ic)) && 
2262          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2263           OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2264         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2265
2266         _G.accInUse++;
2267         aopOp(IC_RESULT(ic),ic,FALSE);
2268         _G.accInUse--;
2269
2270         assignResultValue(IC_RESULT(ic));
2271                 
2272         freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2273     }
2274
2275     /* adjust the stack for parameters if 
2276     required */
2277     if (ic->parmBytes) {
2278         int i;
2279         if (ic->parmBytes > 3) {
2280             pic14_emitcode("mov","a,%s",spname);
2281             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2282             pic14_emitcode("mov","%s,a",spname);
2283         } else 
2284             for ( i = 0 ; i <  ic->parmBytes ;i++)
2285                 pic14_emitcode("dec","%s",spname);
2286
2287     }
2288
2289     /* if register bank was saved then pop them */
2290     if (ic->bankSaved)
2291         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2292
2293     /* if we hade saved some registers then unsave them */
2294     if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2295         unsaveRegisters (ic);
2296
2297
2298 }
2299
2300 /*-----------------------------------------------------------------*/
2301 /* genPcall - generates a call by pointer statement                */
2302 /*-----------------------------------------------------------------*/
2303 static void genPcall (iCode *ic)
2304 {
2305     sym_link *dtype;
2306     symbol *rlbl = newiTempLabel(NULL);
2307
2308
2309     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2310     /* if caller saves & we have not saved then */
2311     if (!ic->regsSaved)
2312         saveRegisters(ic);
2313
2314     /* if we are calling a function that is not using
2315     the same register bank then we need to save the
2316     destination registers on the stack */
2317     dtype = operandType(IC_LEFT(ic));
2318     if (dtype        && 
2319         IFFUNC_ISISR(currFunc->type) &&
2320         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2321         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2322
2323
2324     /* push the return address on to the stack */
2325     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2326     pic14_emitcode("push","acc");    
2327     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2328     pic14_emitcode("push","acc");
2329     
2330     if (options.model == MODEL_FLAT24)
2331     {
2332         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2333         pic14_emitcode("push","acc");    
2334     }
2335
2336     /* now push the calling address */
2337     aopOp(IC_LEFT(ic),ic,FALSE);
2338
2339     pushSide(IC_LEFT(ic), FPTRSIZE);
2340
2341     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2342
2343     /* if send set is not empty the assign */
2344     if (_G.sendSet) {
2345         iCode *sic ;
2346
2347         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2348              sic = setNextItem(_G.sendSet)) {
2349             int size, offset = 0;
2350             aopOp(IC_LEFT(sic),sic,FALSE);
2351             size = AOP_SIZE(IC_LEFT(sic));
2352             while (size--) {
2353                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2354                                 FALSE,FALSE);
2355                 if (strcmp(l,fReturn[offset]))
2356                     pic14_emitcode("mov","%s,%s",
2357                              fReturn[offset],
2358                              l);
2359                 offset++;
2360             }
2361             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2362         }
2363         _G.sendSet = NULL;
2364     }
2365
2366     pic14_emitcode("ret","");
2367     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2368
2369
2370     /* if we need assign a result value */
2371     if ((IS_ITEMP(IC_RESULT(ic)) &&
2372          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2373           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2374         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2375
2376         _G.accInUse++;
2377         aopOp(IC_RESULT(ic),ic,FALSE);
2378         _G.accInUse--;
2379         
2380         assignResultValue(IC_RESULT(ic));
2381
2382         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2383     }
2384
2385     /* adjust the stack for parameters if 
2386     required */
2387     if (ic->parmBytes) {
2388         int i;
2389         if (ic->parmBytes > 3) {
2390             pic14_emitcode("mov","a,%s",spname);
2391             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2392             pic14_emitcode("mov","%s,a",spname);
2393         } else 
2394             for ( i = 0 ; i <  ic->parmBytes ;i++)
2395                 pic14_emitcode("dec","%s",spname);
2396
2397     }
2398
2399     /* if register bank was saved then unsave them */
2400     if (dtype        && 
2401         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2402         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2403
2404     /* if we hade saved some registers then
2405     unsave them */
2406     if (ic->regsSaved)
2407         unsaveRegisters (ic);
2408
2409 }
2410
2411 /*-----------------------------------------------------------------*/
2412 /* resultRemat - result  is rematerializable                       */
2413 /*-----------------------------------------------------------------*/
2414 static int resultRemat (iCode *ic)
2415 {
2416     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2417     if (SKIP_IC(ic) || ic->op == IFX)
2418         return 0;
2419
2420     if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2421         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2422         if (sym->remat && !POINTER_SET(ic)) 
2423             return 1;
2424     }
2425
2426     return 0;
2427 }
2428
2429 #if defined(__BORLANDC__) || defined(_MSC_VER)
2430 #define STRCASECMP stricmp
2431 #else
2432 #define STRCASECMP strcasecmp
2433 #endif
2434
2435 /*-----------------------------------------------------------------*/
2436 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2437 /*-----------------------------------------------------------------*/
2438 static bool inExcludeList(char *s)
2439 {
2440     int i =0;
2441     
2442     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2443     if (options.excludeRegs[i] &&
2444     STRCASECMP(options.excludeRegs[i],"none") == 0)
2445         return FALSE ;
2446
2447     for ( i = 0 ; options.excludeRegs[i]; i++) {
2448         if (options.excludeRegs[i] &&
2449         STRCASECMP(s,options.excludeRegs[i]) == 0)
2450             return TRUE;
2451     }
2452     return FALSE ;
2453 }
2454
2455 /*-----------------------------------------------------------------*/
2456 /* genFunction - generated code for function entry                 */
2457 /*-----------------------------------------------------------------*/
2458 static void genFunction (iCode *ic)
2459 {
2460     symbol *sym;
2461     sym_link *ftype;
2462
2463     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2464
2465     labelOffset += (max_key+4);
2466     max_key=0;
2467
2468     _G.nRegsSaved = 0;
2469     /* create the function header */
2470     pic14_emitcode(";","-----------------------------------------");
2471     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2472     pic14_emitcode(";","-----------------------------------------");
2473
2474     pic14_emitcode("","%s:",sym->rname);
2475     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2476
2477     ftype = operandType(IC_LEFT(ic));
2478
2479     /* if critical function then turn interrupts off */
2480     if (IFFUNC_ISCRITICAL(ftype))
2481         pic14_emitcode("clr","ea");
2482
2483     /* here we need to generate the equates for the
2484        register bank if required */
2485 #if 0
2486     if (FUNC_REGBANK(ftype) != rbank) {
2487         int i ;
2488
2489         rbank = FUNC_REGBANK(ftype);
2490         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2491             if (strcmp(regspic14[i].base,"0") == 0)
2492                 pic14_emitcode("","%s = 0x%02x",
2493                          regspic14[i].dname,
2494                          8*rbank+regspic14[i].offset);
2495             else
2496                 pic14_emitcode ("","%s = %s + 0x%02x",
2497                           regspic14[i].dname,
2498                           regspic14[i].base,
2499                           8*rbank+regspic14[i].offset);
2500         }
2501     }
2502 #endif
2503
2504     /* if this is an interrupt service routine then
2505     save acc, b, dpl, dph  */
2506     if (IFFUNC_ISISR(sym->type)) {
2507         
2508         if (!inExcludeList("acc"))          
2509             pic14_emitcode ("push","acc");      
2510         if (!inExcludeList("b"))
2511             pic14_emitcode ("push","b");
2512         if (!inExcludeList("dpl"))
2513             pic14_emitcode ("push","dpl");
2514         if (!inExcludeList("dph"))
2515             pic14_emitcode ("push","dph");
2516         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2517         {
2518             pic14_emitcode ("push", "dpx");
2519             /* Make sure we're using standard DPTR */
2520             pic14_emitcode ("push", "dps");
2521             pic14_emitcode ("mov", "dps, #0x00");
2522             if (options.stack10bit)
2523             {   
2524                 /* This ISR could conceivably use DPTR2. Better save it. */
2525                 pic14_emitcode ("push", "dpl1");
2526                 pic14_emitcode ("push", "dph1");
2527                 pic14_emitcode ("push", "dpx1");
2528             }
2529         }
2530         /* if this isr has no bank i.e. is going to
2531            run with bank 0 , then we need to save more
2532            registers :-) */
2533         if (!FUNC_REGBANK(sym->type)) {
2534
2535             /* if this function does not call any other
2536                function then we can be economical and
2537                save only those registers that are used */
2538             if (! IFFUNC_HASFCALL(sym->type)) {
2539                 int i;
2540
2541                 /* if any registers used */
2542                 if (sym->regsUsed) {
2543                     /* save the registers used */
2544                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2545                         if (bitVectBitValue(sym->regsUsed,i) ||
2546                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2547                             pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);                         
2548                     }
2549                 }
2550                 
2551             } else {
2552                 /* this function has  a function call cannot
2553                    determines register usage so we will have the
2554                    entire bank */
2555                 saverbank(0,ic,FALSE);
2556             }       
2557         }
2558     } else {
2559         /* if callee-save to be used for this function
2560            then save the registers being used in this function */
2561         if (IFFUNC_CALLEESAVES(sym->type)) {
2562             int i;
2563             
2564             /* if any registers used */
2565             if (sym->regsUsed) {
2566                 /* save the registers used */
2567                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2568                     if (bitVectBitValue(sym->regsUsed,i) ||
2569                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2570                         pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2571                         _G.nRegsSaved++;
2572                     }
2573                 }
2574             }
2575         }
2576     }
2577
2578     /* set the register bank to the desired value */
2579     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2580         pic14_emitcode("push","psw");
2581         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2582     }
2583
2584     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2585
2586         if (options.useXstack) {
2587             pic14_emitcode("mov","r0,%s",spname);
2588             pic14_emitcode("mov","a,_bp");
2589             pic14_emitcode("movx","@r0,a");
2590             pic14_emitcode("inc","%s",spname);
2591         }
2592         else
2593         {
2594             /* set up the stack */
2595             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2596         }
2597         pic14_emitcode ("mov","_bp,%s",spname);
2598     }
2599
2600     /* adjust the stack for the function */
2601     if (sym->stack) {
2602
2603         int i = sym->stack;
2604         if (i > 256 ) 
2605             werror(W_STACK_OVERFLOW,sym->name);
2606
2607         if (i > 3 && sym->recvSize < 4) {              
2608
2609             pic14_emitcode ("mov","a,sp");
2610             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2611             pic14_emitcode ("mov","sp,a");
2612            
2613         }
2614         else
2615             while(i--)
2616                 pic14_emitcode("inc","sp");
2617     }
2618
2619      if (sym->xstack) {
2620
2621         pic14_emitcode ("mov","a,_spx");
2622         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2623         pic14_emitcode ("mov","_spx,a");
2624     }    
2625
2626 }
2627
2628 /*-----------------------------------------------------------------*/
2629 /* genEndFunction - generates epilogue for functions               */
2630 /*-----------------------------------------------------------------*/
2631 static void genEndFunction (iCode *ic)
2632 {
2633     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2634
2635     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2636
2637     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2638     {
2639         pic14_emitcode ("mov","%s,_bp",spname);
2640     }
2641
2642     /* if use external stack but some variables were
2643     added to the local stack then decrement the
2644     local stack */
2645     if (options.useXstack && sym->stack) {      
2646         pic14_emitcode("mov","a,sp");
2647         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2648         pic14_emitcode("mov","sp,a");
2649     }
2650
2651
2652     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2653         if (options.useXstack) {
2654             pic14_emitcode("mov","r0,%s",spname);
2655             pic14_emitcode("movx","a,@r0");
2656             pic14_emitcode("mov","_bp,a");
2657             pic14_emitcode("dec","%s",spname);
2658         }
2659         else
2660         {
2661             pic14_emitcode ("pop","_bp");
2662         }
2663     }
2664
2665     /* restore the register bank  */    
2666     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2667         pic14_emitcode ("pop","psw");
2668
2669     if (IFFUNC_ISISR(sym->type)) {
2670
2671         /* now we need to restore the registers */
2672         /* if this isr has no bank i.e. is going to
2673            run with bank 0 , then we need to save more
2674            registers :-) */
2675         if (!FUNC_REGBANK(sym->type)) {
2676             
2677             /* if this function does not call any other
2678                function then we can be economical and
2679                save only those registers that are used */
2680             if (! IFFUNC_HASFCALL(sym->type)) {
2681                 int i;
2682                 
2683                 /* if any registers used */
2684                 if (sym->regsUsed) {
2685                     /* save the registers used */
2686                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2687                         if (bitVectBitValue(sym->regsUsed,i) ||
2688                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2689                             pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2690                     }
2691                 }
2692                 
2693             } else {
2694                 /* this function has  a function call cannot
2695                    determines register usage so we will have the
2696                    entire bank */
2697                 unsaverbank(0,ic,FALSE);
2698             }       
2699         }
2700
2701         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2702         {
2703             if (options.stack10bit)
2704             {
2705                 pic14_emitcode ("pop", "dpx1");
2706                 pic14_emitcode ("pop", "dph1");
2707                 pic14_emitcode ("pop", "dpl1");
2708             }   
2709             pic14_emitcode ("pop", "dps");
2710             pic14_emitcode ("pop", "dpx");
2711         }
2712         if (!inExcludeList("dph"))
2713             pic14_emitcode ("pop","dph");
2714         if (!inExcludeList("dpl"))
2715             pic14_emitcode ("pop","dpl");
2716         if (!inExcludeList("b"))
2717             pic14_emitcode ("pop","b");
2718         if (!inExcludeList("acc"))
2719             pic14_emitcode ("pop","acc");
2720
2721         if (IFFUNC_ISCRITICAL(sym->type))
2722             pic14_emitcode("setb","ea");
2723
2724         /* if debug then send end of function */
2725 /*      if (options.debug && currFunc) { */
2726         if (currFunc) {
2727             _G.debugLine = 1;
2728             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2729                      FileBaseName(ic->filename),currFunc->lastLine,
2730                      ic->level,ic->block); 
2731             if (IS_STATIC(currFunc->etype))         
2732                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2733             else
2734                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2735             _G.debugLine = 0;
2736         }
2737         
2738         pic14_emitcode ("reti","");
2739     }
2740     else {
2741         if (IFFUNC_ISCRITICAL(sym->type))
2742             pic14_emitcode("setb","ea");
2743         
2744         if (IFFUNC_CALLEESAVES(sym->type)) {
2745             int i;
2746             
2747             /* if any registers used */
2748             if (sym->regsUsed) {
2749                 /* save the registers used */
2750                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2751                     if (bitVectBitValue(sym->regsUsed,i) ||
2752                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753                         pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2754                 }
2755             }
2756             
2757         }
2758
2759         /* if debug then send end of function */
2760         if (currFunc) {
2761             _G.debugLine = 1;
2762             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2763                      FileBaseName(ic->filename),currFunc->lastLine,
2764                      ic->level,ic->block); 
2765             if (IS_STATIC(currFunc->etype))         
2766                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2767             else
2768                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2769             _G.debugLine = 0;
2770         }
2771
2772         pic14_emitcode ("return","");
2773         emitpcodeNULLop(POC_RETURN);
2774
2775         /* Mark the end of a function */
2776         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2777     }
2778
2779 }
2780
2781 /*-----------------------------------------------------------------*/
2782 /* genRet - generate code for return statement                     */
2783 /*-----------------------------------------------------------------*/
2784 static void genRet (iCode *ic)
2785 {
2786     int size,offset = 0 , pushed = 0;
2787     
2788     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2789     /* if we have no return value then
2790        just generate the "ret" */
2791     if (!IC_LEFT(ic)) 
2792         goto jumpret;       
2793     
2794     /* we have something to return then
2795        move the return value into place */
2796     aopOp(IC_LEFT(ic),ic,FALSE);
2797     size = AOP_SIZE(IC_LEFT(ic));
2798     
2799     while (size--) {
2800             char *l ;
2801             if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2802                     /* #NOCHANGE */
2803                     l = aopGet(AOP(IC_LEFT(ic)),offset++,
2804                            FALSE,TRUE);
2805                     pic14_emitcode("push","%s",l);
2806                     pushed++;
2807             } else {
2808                     l = aopGet(AOP(IC_LEFT(ic)),offset,
2809                                FALSE,FALSE);
2810                     if (strcmp(fReturn[offset],l)) {
2811                       if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2812                           ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2813                         pic14_emitcode("movlw","%s",l);
2814                       else
2815                         pic14_emitcode("movf","%s,w",l);
2816                       if(size)
2817                         pic14_emitcode("movwf","%s",fReturn[offset]);
2818                       offset++;
2819                     }
2820             }
2821     }    
2822
2823     if (pushed) {
2824         while(pushed) {
2825             pushed--;
2826             if (strcmp(fReturn[pushed],"a"))
2827                 pic14_emitcode("pop",fReturn[pushed]);
2828             else
2829                 pic14_emitcode("pop","acc");
2830         }
2831     }
2832     freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2833     
2834  jumpret:
2835         /* generate a jump to the return label
2836            if the next is not the return statement */
2837     if (!(ic->next && ic->next->op == LABEL &&
2838           IC_LABEL(ic->next) == returnLabel)) {
2839         
2840         emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2841         pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2842     }
2843     
2844 }
2845
2846 /*-----------------------------------------------------------------*/
2847 /* genLabel - generates a label                                    */
2848 /*-----------------------------------------------------------------*/
2849 static void genLabel (iCode *ic)
2850 {
2851     /* special case never generate */
2852     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2853     if (IC_LABEL(ic) == entryLabel)
2854         return ;
2855
2856     emitpLabel(IC_LABEL(ic)->key);
2857     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2858 }
2859
2860 /*-----------------------------------------------------------------*/
2861 /* genGoto - generates a goto                                      */
2862 /*-----------------------------------------------------------------*/
2863 //tsd
2864 static void genGoto (iCode *ic)
2865 {
2866   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2867   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2868 }
2869
2870 /*-----------------------------------------------------------------*/
2871 /* findLabelBackwards: walks back through the iCode chain looking  */
2872 /* for the given label. Returns number of iCode instructions       */
2873 /* between that label and given ic.                                */
2874 /* Returns zero if label not found.                                */
2875 /*-----------------------------------------------------------------*/
2876 #if 0
2877 static int findLabelBackwards(iCode *ic, int key)
2878 {
2879     int count = 0;
2880     
2881     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2882     while (ic->prev)
2883     {
2884         ic = ic->prev;
2885         count++;
2886         
2887         if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2888         {
2889             /* printf("findLabelBackwards = %d\n", count); */
2890             return count;
2891         }
2892     }
2893     
2894     return 0;
2895 }
2896 #endif
2897
2898 /*-----------------------------------------------------------------*/
2899 /* genMultbits :- multiplication of bits                           */
2900 /*-----------------------------------------------------------------*/
2901 static void genMultbits (operand *left, 
2902                          operand *right, 
2903                          operand *result)
2904 {
2905     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2906
2907     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2908     pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2909     pic14_outBitC(result);
2910 }
2911
2912
2913 /*-----------------------------------------------------------------*/
2914 /* genMultOneByte : 8 bit multiplication & division                */
2915 /*-----------------------------------------------------------------*/
2916 static void genMultOneByte (operand *left,
2917                             operand *right,
2918                             operand *result)
2919 {
2920     sym_link *opetype = operandType(result);
2921     char *l ;
2922     symbol *lbl ;
2923     int size,offset;
2924
2925     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2926     /* (if two literals, the value is computed before) */
2927     /* if one literal, literal on the right */
2928     if (AOP_TYPE(left) == AOP_LIT){
2929         operand *t = right;
2930         right = left;
2931         left = t;
2932     }
2933
2934     size = AOP_SIZE(result);
2935     /* signed or unsigned */
2936     pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2937     l = aopGet(AOP(left),0,FALSE,FALSE);
2938     MOVA(l);       
2939     pic14_emitcode("mul","ab");
2940     /* if result size = 1, mul signed = mul unsigned */
2941     aopPut(AOP(result),"a",0);
2942     if (size > 1){
2943         if (SPEC_USIGN(opetype)){
2944             aopPut(AOP(result),"b",1);
2945             if (size > 2)
2946                 /* for filling the MSBs */
2947                 pic14_emitcode("clr","a");
2948         }
2949         else{
2950             pic14_emitcode("mov","a,b");
2951
2952             /* adjust the MSB if left or right neg */
2953
2954             /* if one literal */
2955             if (AOP_TYPE(right) == AOP_LIT){
2956                 /* AND literal negative */
2957                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2958                     /* adjust MSB (c==0 after mul) */
2959                     pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2960                 }
2961             }
2962             else{
2963                 lbl = newiTempLabel(NULL);
2964                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2965                 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2966                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2967                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2968                 lbl = newiTempLabel(NULL);      
2969                 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
2970                 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2971                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2972             }
2973
2974             lbl = newiTempLabel(NULL);
2975             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2976             pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2977             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2978             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2979             lbl = newiTempLabel(NULL);      
2980             pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
2981             pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2982             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2983
2984             aopPut(AOP(result),"a",1);
2985             if(size > 2){
2986                 /* get the sign */
2987                 pic14_emitcode("rlc","a");
2988                 pic14_emitcode("subb","a,acc");
2989             }
2990         }
2991         size -= 2;   
2992         offset = 2;
2993         if (size > 0)
2994             while (size--)
2995                 aopPut(AOP(result),"a",offset++);
2996     }
2997 }
2998
2999 /*-----------------------------------------------------------------*/
3000 /* genMult - generates code for multiplication                     */
3001 /*-----------------------------------------------------------------*/
3002 static void genMult (iCode *ic)
3003 {
3004     operand *left = IC_LEFT(ic);
3005     operand *right = IC_RIGHT(ic);
3006     operand *result= IC_RESULT(ic);   
3007
3008     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3009     /* assign the amsops */
3010     aopOp (left,ic,FALSE);
3011     aopOp (right,ic,FALSE);
3012     aopOp (result,ic,TRUE);
3013
3014     /* special cases first */
3015     /* both are bits */
3016     if (AOP_TYPE(left) == AOP_CRY &&
3017         AOP_TYPE(right)== AOP_CRY) {
3018         genMultbits(left,right,result);
3019         goto release ;
3020     }
3021
3022     /* if both are of size == 1 */
3023     if (AOP_SIZE(left) == 1 &&
3024         AOP_SIZE(right) == 1 ) {
3025         genMultOneByte(left,right,result);
3026         goto release ;
3027     }
3028
3029     /* should have been converted to function call */       
3030     assert(1) ;
3031
3032 release :
3033     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3034     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3035     freeAsmop(result,NULL,ic,TRUE); 
3036 }
3037
3038 /*-----------------------------------------------------------------*/
3039 /* genDivbits :- division of bits                                  */
3040 /*-----------------------------------------------------------------*/
3041 static void genDivbits (operand *left, 
3042                         operand *right, 
3043                         operand *result)
3044 {
3045
3046     char *l;
3047
3048     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3049     /* the result must be bit */    
3050     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3051     l = aopGet(AOP(left),0,FALSE,FALSE);
3052
3053     MOVA(l);    
3054
3055     pic14_emitcode("div","ab");
3056     pic14_emitcode("rrc","a");
3057     aopPut(AOP(result),"c",0);
3058 }
3059
3060 /*-----------------------------------------------------------------*/
3061 /* genDivOneByte : 8 bit division                                  */
3062 /*-----------------------------------------------------------------*/
3063 static void genDivOneByte (operand *left,
3064                            operand *right,
3065                            operand *result)
3066 {
3067     sym_link *opetype = operandType(result);
3068     char *l ;
3069     symbol *lbl ;
3070     int size,offset;
3071
3072     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3073     size = AOP_SIZE(result) - 1;
3074     offset = 1;
3075     /* signed or unsigned */
3076     if (SPEC_USIGN(opetype)) {
3077         /* unsigned is easy */
3078         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3079         l = aopGet(AOP(left),0,FALSE,FALSE);
3080         MOVA(l);        
3081         pic14_emitcode("div","ab");
3082         aopPut(AOP(result),"a",0);
3083         while (size--)
3084             aopPut(AOP(result),zero,offset++);
3085         return ;
3086     }
3087
3088     /* signed is a little bit more difficult */
3089
3090     /* save the signs of the operands */
3091     l = aopGet(AOP(left),0,FALSE,FALSE);    
3092     MOVA(l);    
3093     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3094     pic14_emitcode("push","acc"); /* save it on the stack */
3095
3096     /* now sign adjust for both left & right */
3097     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3098     MOVA(l);       
3099     lbl = newiTempLabel(NULL);
3100     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3101     pic14_emitcode("cpl","a");   
3102     pic14_emitcode("inc","a");
3103     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3104     pic14_emitcode("mov","b,a");
3105
3106     /* sign adjust left side */
3107     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3108     MOVA(l);
3109
3110     lbl = newiTempLabel(NULL);
3111     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3112     pic14_emitcode("cpl","a");
3113     pic14_emitcode("inc","a");
3114     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3115
3116     /* now the division */
3117     pic14_emitcode("div","ab");
3118     /* we are interested in the lower order
3119     only */
3120     pic14_emitcode("mov","b,a");
3121     lbl = newiTempLabel(NULL);
3122     pic14_emitcode("pop","acc");   
3123     /* if there was an over flow we don't 
3124     adjust the sign of the result */
3125     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3126     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3127     CLRC;
3128     pic14_emitcode("clr","a");
3129     pic14_emitcode("subb","a,b");
3130     pic14_emitcode("mov","b,a");
3131     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3132
3133     /* now we are done */
3134     aopPut(AOP(result),"b",0);
3135     if(size > 0){
3136         pic14_emitcode("mov","c,b.7");
3137         pic14_emitcode("subb","a,acc");   
3138     }
3139     while (size--)
3140         aopPut(AOP(result),"a",offset++);
3141
3142 }
3143
3144 /*-----------------------------------------------------------------*/
3145 /* genDiv - generates code for division                            */
3146 /*-----------------------------------------------------------------*/
3147 static void genDiv (iCode *ic)
3148 {
3149     operand *left = IC_LEFT(ic);
3150     operand *right = IC_RIGHT(ic);
3151     operand *result= IC_RESULT(ic);   
3152
3153     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3154     /* assign the amsops */
3155     aopOp (left,ic,FALSE);
3156     aopOp (right,ic,FALSE);
3157     aopOp (result,ic,TRUE);
3158
3159     /* special cases first */
3160     /* both are bits */
3161     if (AOP_TYPE(left) == AOP_CRY &&
3162         AOP_TYPE(right)== AOP_CRY) {
3163         genDivbits(left,right,result);
3164         goto release ;
3165     }
3166
3167     /* if both are of size == 1 */
3168     if (AOP_SIZE(left) == 1 &&
3169         AOP_SIZE(right) == 1 ) {
3170         genDivOneByte(left,right,result);
3171         goto release ;
3172     }
3173
3174     /* should have been converted to function call */
3175     assert(1);
3176 release :
3177     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3178     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179     freeAsmop(result,NULL,ic,TRUE); 
3180 }
3181
3182 /*-----------------------------------------------------------------*/
3183 /* genModbits :- modulus of bits                                   */
3184 /*-----------------------------------------------------------------*/
3185 static void genModbits (operand *left, 
3186                         operand *right, 
3187                         operand *result)
3188 {
3189
3190     char *l;
3191
3192     /* the result must be bit */    
3193     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3194     l = aopGet(AOP(left),0,FALSE,FALSE);
3195
3196     MOVA(l);       
3197
3198     pic14_emitcode("div","ab");
3199     pic14_emitcode("mov","a,b");
3200     pic14_emitcode("rrc","a");
3201     aopPut(AOP(result),"c",0);
3202 }
3203
3204 /*-----------------------------------------------------------------*/
3205 /* genModOneByte : 8 bit modulus                                   */
3206 /*-----------------------------------------------------------------*/
3207 static void genModOneByte (operand *left,
3208                            operand *right,
3209                            operand *result)
3210 {
3211     sym_link *opetype = operandType(result);
3212     char *l ;
3213     symbol *lbl ;
3214
3215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3216     /* signed or unsigned */
3217     if (SPEC_USIGN(opetype)) {
3218         /* unsigned is easy */
3219         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3220         l = aopGet(AOP(left),0,FALSE,FALSE);
3221         MOVA(l);    
3222         pic14_emitcode("div","ab");
3223         aopPut(AOP(result),"b",0);
3224         return ;
3225     }
3226
3227     /* signed is a little bit more difficult */
3228
3229     /* save the signs of the operands */
3230     l = aopGet(AOP(left),0,FALSE,FALSE);    
3231     MOVA(l);
3232
3233     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3234     pic14_emitcode("push","acc"); /* save it on the stack */
3235
3236     /* now sign adjust for both left & right */
3237     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3238     MOVA(l);
3239
3240     lbl = newiTempLabel(NULL);
3241     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3242     pic14_emitcode("cpl","a");   
3243     pic14_emitcode("inc","a");
3244     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3245     pic14_emitcode("mov","b,a"); 
3246
3247     /* sign adjust left side */
3248     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3249     MOVA(l);
3250
3251     lbl = newiTempLabel(NULL);
3252     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3253     pic14_emitcode("cpl","a");   
3254     pic14_emitcode("inc","a");
3255     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3256
3257     /* now the multiplication */
3258     pic14_emitcode("div","ab");
3259     /* we are interested in the lower order
3260     only */
3261     lbl = newiTempLabel(NULL);
3262     pic14_emitcode("pop","acc");   
3263     /* if there was an over flow we don't 
3264     adjust the sign of the result */
3265     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3266     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3267     CLRC ;
3268     pic14_emitcode("clr","a");
3269     pic14_emitcode("subb","a,b");
3270     pic14_emitcode("mov","b,a");
3271     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3272
3273     /* now we are done */
3274     aopPut(AOP(result),"b",0);
3275
3276 }
3277
3278 /*-----------------------------------------------------------------*/
3279 /* genMod - generates code for division                            */
3280 /*-----------------------------------------------------------------*/
3281 static void genMod (iCode *ic)
3282 {
3283     operand *left = IC_LEFT(ic);
3284     operand *right = IC_RIGHT(ic);
3285     operand *result= IC_RESULT(ic);  
3286
3287     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3288     /* assign the amsops */
3289     aopOp (left,ic,FALSE);
3290     aopOp (right,ic,FALSE);
3291     aopOp (result,ic,TRUE);
3292
3293     /* special cases first */
3294     /* both are bits */
3295     if (AOP_TYPE(left) == AOP_CRY &&
3296         AOP_TYPE(right)== AOP_CRY) {
3297         genModbits(left,right,result);
3298         goto release ;
3299     }
3300
3301     /* if both are of size == 1 */
3302     if (AOP_SIZE(left) == 1 &&
3303         AOP_SIZE(right) == 1 ) {
3304         genModOneByte(left,right,result);
3305         goto release ;
3306     }
3307
3308     /* should have been converted to function call */
3309     assert(1);
3310
3311 release :
3312     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3313     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3314     freeAsmop(result,NULL,ic,TRUE); 
3315 }
3316
3317 /*-----------------------------------------------------------------*/
3318 /* genIfxJump :- will create a jump depending on the ifx           */
3319 /*-----------------------------------------------------------------*/
3320 /*
3321   note: May need to add parameter to indicate when a variable is in bit space.
3322 */
3323 static void genIfxJump (iCode *ic, char *jval)
3324 {
3325
3326     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3327     /* if true label then we jump if condition
3328     supplied is true */
3329     if ( IC_TRUE(ic) ) {
3330
3331         if(strcmp(jval,"a") == 0)
3332           emitSKPZ;
3333         else if (strcmp(jval,"c") == 0)
3334           emitSKPC;
3335         else {
3336           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3337           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3338         }
3339
3340         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3341         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3342
3343     }
3344     else {
3345         /* false label is present */
3346         if(strcmp(jval,"a") == 0)
3347           emitSKPNZ;
3348         else if (strcmp(jval,"c") == 0)
3349           emitSKPNC;
3350         else {
3351           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3352           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3353         }
3354
3355         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3356         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3357
3358     }
3359
3360
3361     /* mark the icode as generated */
3362     ic->generated = 1;
3363 }
3364
3365 /*-----------------------------------------------------------------*/
3366 /* genSkip                                                         */
3367 /*-----------------------------------------------------------------*/
3368 static void genSkip(iCode *ifx,int status_bit)
3369 {
3370   if(!ifx)
3371     return;
3372
3373   if ( IC_TRUE(ifx) ) {
3374     switch(status_bit) {
3375     case 'z':
3376       emitSKPNZ;
3377       break;
3378
3379     case 'c':
3380       emitSKPNC;
3381       break;
3382
3383     case 'd':
3384       emitSKPDC;
3385       break;
3386
3387     }
3388
3389     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3390     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3391
3392   } else {
3393
3394     switch(status_bit) {
3395
3396     case 'z':
3397       emitSKPZ;
3398       break;
3399
3400     case 'c':
3401       emitSKPC;
3402       break;
3403
3404     case 'd':
3405       emitSKPDC;
3406       break;
3407     }
3408     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3409     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3410
3411   }
3412
3413 }
3414
3415 /*-----------------------------------------------------------------*/
3416 /* genSkipc                                                        */
3417 /*-----------------------------------------------------------------*/
3418 static void genSkipc(resolvedIfx *rifx)
3419 {
3420   if(!rifx)
3421     return;
3422
3423   if(rifx->condition)
3424     emitSKPC;
3425   else
3426     emitSKPNC;
3427
3428   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3429   rifx->generated = 1;
3430 }
3431
3432 /*-----------------------------------------------------------------*/
3433 /* genSkipz                                                        */
3434 /*-----------------------------------------------------------------*/
3435 static void genSkipz(iCode *ifx, int condition)
3436 {
3437   if(!ifx)
3438     return;
3439
3440   if(condition)
3441     emitSKPNZ;
3442   else
3443     emitSKPZ;
3444
3445   if ( IC_TRUE(ifx) )
3446     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3447   else
3448     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3449
3450   if ( IC_TRUE(ifx) )
3451     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3452   else
3453     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3454
3455 }
3456 /*-----------------------------------------------------------------*/
3457 /* genCmp :- greater or less than comparison                       */
3458 /*-----------------------------------------------------------------*/
3459 static void genCmp (operand *left,operand *right,
3460                     operand *result, iCode *ifx, int sign)
3461 {
3462   int size, offset = 0 ;
3463   unsigned long lit = 0L,i = 0;
3464   resolvedIfx rIfx;
3465
3466   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3467   if(ifx) {
3468   DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3469   DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3470   }
3471
3472   resolveIfx(&rIfx,ifx);
3473
3474   /* if left & right are bit variables */
3475   if (AOP_TYPE(left) == AOP_CRY &&
3476       AOP_TYPE(right) == AOP_CRY ) {
3477     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3478     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3479   } else {
3480     /* subtract right from left if at the
3481        end the carry flag is set then we know that
3482        left is greater than right */
3483     size = max(AOP_SIZE(left),AOP_SIZE(right));
3484
3485     /* if unsigned char cmp with lit, do cjne left,#right,zz */
3486     if((size == 1) && !sign &&
3487        (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3488       symbol *lbl  = newiTempLabel(NULL);
3489       pic14_emitcode("cjne","%s,%s,%05d_DS_",
3490                aopGet(AOP(left),offset,FALSE,FALSE),
3491                aopGet(AOP(right),offset,FALSE,FALSE),
3492                lbl->key+100);
3493       pic14_emitcode("","%05d_DS_:",lbl->key+100);
3494     } else {
3495
3496       if(AOP_TYPE(right) == AOP_LIT) {
3497         symbol *lbl = newiTempLabel(NULL);
3498
3499         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3500
3501         DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3502
3503         size--;
3504         i = (lit >> (size*8)) & 0xff;
3505         if(sign) {
3506           if(i & 0x80) {
3507             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3508           } else {
3509             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3510           }
3511           emitpcode(POC_GOTO,popGetLabel(lbl->key));
3512         }
3513
3514         emitpcode(POC_MOVLW, popGetLit(i));
3515         emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3516         while(size--) {
3517           i = (lit >> (size*8)) & 0xff;
3518           emitpcode(POC_MOVLW, popGetLit(i));
3519           emitSKPNC;
3520           emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3521         }
3522
3523         if(ifx) {
3524           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3525           //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3526           genSkipc(&rIfx);
3527           //if(sign)
3528             emitpLabel(lbl->key);
3529
3530           ifx->generated = 1;
3531         }
3532         return;
3533       }
3534
3535       if(AOP_TYPE(left) == AOP_LIT) {
3536         //symbol *lbl = newiTempLabel(NULL);
3537
3538         lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3539
3540         DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3541
3542         if(size==1) {
3543           if(sign) {
3544             if(lit & 0x80) {
3545               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3546             } else {
3547               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3548             }
3549             if(ifx) {
3550               if(IC_TRUE(ifx) != NULL)
3551                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3552               else
3553                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3554             }
3555           }
3556           emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3557           emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3558           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3559           rIfx.condition ^= 1;
3560           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3561         } else {
3562           size--;
3563           //lit++;
3564           i = (lit >> (size*8)) & 0xff;
3565
3566           if(sign) {
3567             if(i & 0x80) {
3568               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3569             } else {
3570               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3571             }
3572             if(ifx) {
3573               if(IC_TRUE(ifx) != NULL)
3574                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3575               else
3576                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3577             }
3578           }
3579
3580           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3581           emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3582           while(size--) {
3583             i = (lit >> (size*8)) & 0xff;
3584             emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3585             emitSKPNC;
3586             emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3587           }
3588   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3589           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,0,1);  //IC_TRUE(ifx) == NULL);
3590
3591         }
3592 /*
3593         if(sign)
3594           emitpLabel(lbl->key);
3595 */
3596         if(ifx) ifx->generated = 1;
3597         return;
3598       }
3599
3600
3601       // CLRC;
3602       DEBUGpic14_emitcode(";sign","%d",sign);
3603
3604       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3605       pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3606
3607       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3608       emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3609
3610       size--;
3611       while (size--) {
3612
3613         emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
3614         emitSKPC;
3615         emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3616         emitpcode(POC_SUBFW,   popGet(AOP(left),offset,FALSE,FALSE));
3617
3618 /*
3619         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3620         emitSKPC;
3621         pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3622         pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3623 */
3624         offset++;
3625       }
3626     }
3627   }
3628
3629   //release:
3630   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3631     pic14_outBitC(result);
3632   } else {
3633     /* if the result is used in the next
3634        ifx conditional branch then generate
3635        code a little differently */
3636     if (ifx )
3637       genIfxJump (ifx,"c");
3638     else
3639       pic14_outBitC(result);
3640     /* leave the result in acc */
3641   }
3642
3643 }
3644
3645 /*-----------------------------------------------------------------*/
3646 /* genCmpGt :- greater than comparison                             */
3647 /*-----------------------------------------------------------------*/
3648 static void genCmpGt (iCode *ic, iCode *ifx)
3649 {
3650     operand *left, *right, *result;
3651     sym_link *letype , *retype;
3652     int sign ;
3653
3654     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3655     left = IC_LEFT(ic);
3656     right= IC_RIGHT(ic);
3657     result = IC_RESULT(ic);
3658
3659     letype = getSpec(operandType(left));
3660     retype =getSpec(operandType(right));
3661     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3662     /* assign the amsops */
3663     aopOp (left,ic,FALSE);
3664     aopOp (right,ic,FALSE);
3665     aopOp (result,ic,TRUE);
3666
3667     genCmp(right, left, result, ifx, sign);
3668
3669     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3670     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3671     freeAsmop(result,NULL,ic,TRUE); 
3672 }
3673
3674 /*-----------------------------------------------------------------*/
3675 /* genCmpLt - less than comparisons                                */
3676 /*-----------------------------------------------------------------*/
3677 static void genCmpLt (iCode *ic, iCode *ifx)
3678 {
3679     operand *left, *right, *result;
3680     sym_link *letype , *retype;
3681     int sign ;
3682
3683     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3684     left = IC_LEFT(ic);
3685     right= IC_RIGHT(ic);
3686     result = IC_RESULT(ic);
3687
3688     letype = getSpec(operandType(left));
3689     retype =getSpec(operandType(right));
3690     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3691
3692     /* assign the amsops */
3693     aopOp (left,ic,FALSE);
3694     aopOp (right,ic,FALSE);
3695     aopOp (result,ic,TRUE);
3696
3697     genCmp(left, right, result, ifx, sign);
3698
3699     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3700     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3701     freeAsmop(result,NULL,ic,TRUE); 
3702 }
3703
3704 /*-----------------------------------------------------------------*/
3705 /* genc16bit2lit - compare a 16 bit value to a literal             */
3706 /*-----------------------------------------------------------------*/
3707 static void genc16bit2lit(operand *op, int lit, int offset)
3708 {
3709   int i;
3710
3711   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
3712   if( (lit&0xff) == 0) 
3713     i=1;
3714   else
3715     i=0;
3716
3717   switch( BYTEofLONG(lit,i)) { 
3718   case 0:
3719     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3720     break;
3721   case 1:
3722     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3723     break;
3724   case 0xff:
3725     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3726     break;
3727   default:
3728     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3729     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3730   }
3731
3732   i ^= 1;
3733
3734   switch( BYTEofLONG(lit,i)) { 
3735   case 0:
3736     emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3737     break;
3738   case 1:
3739     emitSKPNZ;
3740     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3741     break;
3742   case 0xff:
3743     emitSKPNZ;
3744     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3745     break;
3746   default:
3747     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3748     emitSKPNZ;
3749     emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3750
3751   }
3752
3753 }
3754
3755 /*-----------------------------------------------------------------*/
3756 /* gencjneshort - compare and jump if not equal                    */
3757 /*-----------------------------------------------------------------*/
3758 static void gencjne(operand *left, operand *right, iCode *ifx)
3759 {
3760   int size = max(AOP_SIZE(left),AOP_SIZE(right));
3761   int offset = 0;
3762   resolvedIfx rIfx;
3763   symbol *lbl;
3764   symbol *tlbl;
3765
3766   unsigned long lit = 0L;
3767   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3768   DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3769                        AopType(AOP_TYPE(left)),
3770                        aopGet(AOP(left),0,TRUE,FALSE),
3771                        AopType(AOP_TYPE(right)),
3772                        aopGet(AOP(right),0,FALSE,FALSE),
3773                        size);
3774
3775   resolveIfx(&rIfx,ifx);
3776   lbl =  newiTempLabel(NULL);
3777
3778
3779   /* if the left side is a literal or 
3780      if the right is in a pointer register and left 
3781      is not */
3782   if ((AOP_TYPE(left) == AOP_LIT) || 
3783       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3784     operand *t = right;
3785     right = left;
3786     left = t;
3787   }
3788   if(AOP_TYPE(right) == AOP_LIT)
3789     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3790
3791   /* if the right side is a literal then anything goes */
3792   if (AOP_TYPE(right) == AOP_LIT &&
3793       AOP_TYPE(left) != AOP_DIR ) {
3794     switch(size) {
3795     case 2:
3796       genc16bit2lit(left, lit, 0);
3797       emitSKPNZ;
3798       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3799       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3800       break;
3801     default:
3802       while (size--) {
3803         if(lit & 0xff) {
3804           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3805           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3806           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3807           pic14_emitcode("xorlw","0x%x",lit & 0xff);
3808         } else {
3809           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3810           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3811         }
3812
3813         emitSKPNZ;
3814         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3815         emitpcode(POC_GOTO,popGetLabel(lbl->key));
3816         offset++;
3817         lit >>= 8;
3818       }
3819       break;
3820     }
3821   }
3822
3823   /* if the right side is in a register or in direct space or
3824      if the left is a pointer register & right is not */    
3825   else if (AOP_TYPE(right) == AOP_REG ||
3826            AOP_TYPE(right) == AOP_DIR || 
3827            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3828            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3829     switch(size) {
3830     case 2:
3831       genc16bit2lit(left, lit, 0);
3832       emitSKPNZ;
3833       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3834       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3835       break;
3836     default:
3837       while (size--) {
3838         int emit_skip=1;
3839         if((AOP_TYPE(left) == AOP_DIR) && 
3840            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3841
3842           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3843           emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3844
3845         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3846             
3847           switch (lit & 0xff) {
3848           case 0:
3849             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3850             break;
3851           case 1:
3852             emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3853             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3854             emit_skip=0;
3855             break;
3856           case 0xff:
3857             emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3858             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3859             emit_skip=0;
3860             break;
3861           default:
3862             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3863             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3864           }
3865           lit >>= 8;
3866
3867         } else {
3868           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3869           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3870         }
3871         if(emit_skip) {
3872           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3873           if(rIfx.condition)
3874             emitSKPNZ;
3875           else
3876             emitSKPZ;
3877           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3878           if(ifx)
3879             ifx->generated=1;
3880         }
3881         emit_skip++;
3882         offset++;
3883       }
3884       break;
3885     }
3886   } else if(AOP_TYPE(right) == AOP_REG &&
3887             AOP_TYPE(left) != AOP_DIR){
3888
3889     while(size--) {
3890       emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3891       emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3892       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3893       if(rIfx.condition)
3894         emitSKPNZ;
3895       else
3896         emitSKPZ;
3897       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3898       offset++;
3899     }
3900       
3901   }else{
3902     /* right is a pointer reg need both a & b */
3903     while(size--) {
3904       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3905       if(strcmp(l,"b"))
3906         pic14_emitcode("mov","b,%s",l);
3907       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3908       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
3909       offset++;
3910     }
3911   }
3912   emitpLabel(lbl->key);
3913
3914   if(ifx)
3915     ifx->generated = 1;
3916 }
3917
3918 #if 0
3919 /*-----------------------------------------------------------------*/
3920 /* gencjne - compare and jump if not equal                         */
3921 /*-----------------------------------------------------------------*/
3922 static void gencjne(operand *left, operand *right, iCode *ifx)
3923 {
3924     symbol *tlbl  = newiTempLabel(NULL);
3925
3926     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3927     gencjneshort(left, right, lbl);
3928
3929     pic14_emitcode("mov","a,%s",one);
3930     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3931     pic14_emitcode("","%05d_DS_:",lbl->key+100);
3932     pic14_emitcode("clr","a");
3933     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3934
3935     emitpLabel(lbl->key);
3936     emitpLabel(tlbl->key);
3937
3938 }
3939 #endif
3940
3941 /*-----------------------------------------------------------------*/
3942 /* genCmpEq - generates code for equal to                          */
3943 /*-----------------------------------------------------------------*/
3944 static void genCmpEq (iCode *ic, iCode *ifx)
3945 {
3946     operand *left, *right, *result;
3947     unsigned long lit = 0L;
3948     int size,offset=0;
3949
3950     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3951
3952     if(ifx)
3953       DEBUGpic14_emitcode ("; ifx is non-null","");
3954     else
3955       DEBUGpic14_emitcode ("; ifx is null","");
3956
3957     aopOp((left=IC_LEFT(ic)),ic,FALSE);
3958     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3959     aopOp((result=IC_RESULT(ic)),ic,TRUE);
3960
3961 /*
3962     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3963                          AopType(AOP_TYPE(IC_RESULT(ic))),
3964                          AopType(AOP_TYPE(IC_LEFT(ic))),
3965                          AopType(AOP_TYPE(IC_RIGHT(ic))));
3966 */
3967     size = max(AOP_SIZE(left),AOP_SIZE(right));
3968     DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
3969                          AopType(AOP_TYPE(result)),
3970                          aopGet(AOP(result),0,TRUE,FALSE),
3971                          AopType(AOP_TYPE(left)),
3972                          aopGet(AOP(left),0,TRUE,FALSE),
3973                          AopType(AOP_TYPE(right)),
3974                          aopGet(AOP(right),0,FALSE,FALSE),
3975                          size);
3976
3977
3978     /* if literal, literal on the right or 
3979     if the right is in a pointer register and left 
3980     is not */
3981     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
3982         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3983         operand *t = IC_RIGHT(ic);
3984         IC_RIGHT(ic) = IC_LEFT(ic);
3985         IC_LEFT(ic) = t;
3986     }
3987
3988     if(ifx && !AOP_SIZE(result)){
3989         symbol *tlbl;
3990         /* if they are both bit variables */
3991         if (AOP_TYPE(left) == AOP_CRY &&
3992             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3993             if(AOP_TYPE(right) == AOP_LIT){
3994                 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3995                 if(lit == 0L){
3996                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3997                     pic14_emitcode("cpl","c");
3998                 } else if(lit == 1L) {
3999                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4000                 } else {
4001                     pic14_emitcode("clr","c");
4002                 }
4003                 /* AOP_TYPE(right) == AOP_CRY */
4004             } else {
4005                 symbol *lbl = newiTempLabel(NULL);
4006                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4007                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4008                 pic14_emitcode("cpl","c");
4009                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4010             }
4011             /* if true label then we jump if condition
4012             supplied is true */
4013             tlbl = newiTempLabel(NULL);
4014             if ( IC_TRUE(ifx) ) {
4015                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4016                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4017             } else {
4018                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4019                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4020             }
4021             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4022         } else {
4023
4024           /* They're not both bit variables. Is the right a literal? */
4025           if(AOP_TYPE(right) == AOP_LIT) {
4026             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4027             
4028
4029             switch(size) {
4030
4031             case 1:
4032               switch(lit & 0xff) {
4033               case 1:
4034                 if ( IC_TRUE(ifx) ) {
4035                   emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4036                   emitSKPNZ;
4037                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4038                 } else {
4039                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4040                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4041                 }
4042                 break;
4043               case 0xff:
4044                 if ( IC_TRUE(ifx) ) {
4045                   emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4046                   emitSKPNZ;
4047                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4048                 } else {
4049                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4050                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4051                 }
4052                 break;
4053               default:
4054                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4055                 if(lit)
4056                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4057                 genSkip(ifx,'z');
4058               }
4059
4060
4061               /* end of size == 1 */
4062               break;
4063               
4064             case 2:
4065               genc16bit2lit(left,lit,offset);
4066               genSkip(ifx,'z');
4067               break;
4068               /* end of size == 2 */
4069
4070             default:
4071               /* size is 4 */
4072               if(lit==0) {
4073                 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4074                 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4075                 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4076                 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4077
4078               } else {
4079
4080                 /* search for patterns that can be optimized */
4081
4082                 genc16bit2lit(left,lit,0);
4083                 lit >>= 16;
4084                 if(lit) {
4085                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4086                   //genSkip(ifx,'z');
4087                   genc16bit2lit(left,lit,2);
4088                 } else {
4089                   emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4090                   emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4091
4092                 }
4093                 
4094               }
4095
4096               genSkip(ifx,'z');
4097             }
4098           
4099             ifx->generated = 1;
4100             goto release ;
4101             
4102
4103           } else if(AOP_TYPE(right) == AOP_CRY ) {
4104             /* we know the left is not a bit, but that the right is */
4105             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4106             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4107                       popGet(AOP(right),offset,FALSE,FALSE));
4108             emitpcode(POC_XORLW,popGetLit(1));
4109
4110             pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4111             if ( IC_TRUE(ifx) )
4112               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4113                        AOP(right)->aopu.aop_dir,
4114                        AOP(right)->aopu.aop_dir);
4115             else
4116               pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4117                        AOP(right)->aopu.aop_dir,
4118                        AOP(right)->aopu.aop_dir);
4119
4120             pic14_emitcode("xorlw","1");
4121
4122             /* if the two are equal, then W will be 0 and the Z bit is set
4123              * we could test Z now, or go ahead and check the high order bytes if
4124              * the variable we're comparing is larger than a byte. */
4125
4126             while(--size)
4127               emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4128             //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4129
4130             if ( IC_TRUE(ifx) ) {
4131               emitSKPNZ;
4132               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4133               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4134             } else {
4135               emitSKPZ;
4136               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4137               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4138             }
4139
4140           } else {
4141             /* They're both variables that are larger than bits */
4142             int s = size;
4143
4144             tlbl = newiTempLabel(NULL);
4145
4146             while(size--) {
4147               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4148               emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4149
4150               pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4151               pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4152
4153               if ( IC_TRUE(ifx) ) {
4154                 if(size) {
4155                   emitSKPZ;
4156                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4157                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4158                 } else {
4159                   emitSKPNZ;
4160                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4161                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4162                 }
4163               } else {
4164                 emitSKPZ;
4165                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4166                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4167               }
4168               offset++;
4169             }
4170             if(s>1 && IC_TRUE(ifx)) {
4171               emitpLabel(tlbl->key);
4172               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4173             }
4174           }
4175         }
4176         /* mark the icode as generated */
4177         ifx->generated = 1;
4178         goto release ;
4179     }
4180
4181     /* if they are both bit variables */
4182     if (AOP_TYPE(left) == AOP_CRY &&
4183         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4184         if(AOP_TYPE(right) == AOP_LIT){
4185             unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4186             if(lit == 0L){
4187                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4188                 pic14_emitcode("cpl","c");
4189             } else if(lit == 1L) {
4190                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4191             } else {
4192                 pic14_emitcode("clr","c");
4193             }
4194             /* AOP_TYPE(right) == AOP_CRY */
4195         } else {
4196             symbol *lbl = newiTempLabel(NULL);
4197             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4198             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4199             pic14_emitcode("cpl","c");
4200             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4201         }
4202         /* c = 1 if egal */
4203         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4204             pic14_outBitC(result);
4205             goto release ;
4206         }
4207         if (ifx) {
4208             genIfxJump (ifx,"c");
4209             goto release ;
4210         }
4211         /* if the result is used in an arithmetic operation
4212         then put the result in place */
4213         pic14_outBitC(result);
4214     } else {
4215       
4216       gencjne(left,right,ifx);
4217 /*
4218       if(ifx) 
4219         gencjne(left,right,newiTempLabel(NULL));
4220       else {
4221         if(IC_TRUE(ifx)->key)
4222           gencjne(left,right,IC_TRUE(ifx)->key);
4223         else
4224           gencjne(left,right,IC_FALSE(ifx)->key);
4225         ifx->generated = 1;
4226         goto release ;
4227       }
4228       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4229         aopPut(AOP(result),"a",0);
4230         goto release ;
4231       }
4232
4233       if (ifx) {
4234         genIfxJump (ifx,"a");
4235         goto release ;
4236       }
4237 */
4238       /* if the result is used in an arithmetic operation
4239          then put the result in place */
4240       if (AOP_TYPE(result) != AOP_CRY) 
4241         pic14_outAcc(result);
4242       /* leave the result in acc */
4243     }
4244
4245 release:
4246     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4247     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4248     freeAsmop(result,NULL,ic,TRUE);
4249 }
4250
4251 /*-----------------------------------------------------------------*/
4252 /* ifxForOp - returns the icode containing the ifx for operand     */
4253 /*-----------------------------------------------------------------*/
4254 static iCode *ifxForOp ( operand *op, iCode *ic )
4255 {
4256     /* if true symbol then needs to be assigned */
4257     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4258     if (IS_TRUE_SYMOP(op))
4259         return NULL ;
4260
4261     /* if this has register type condition and
4262     the next instruction is ifx with the same operand
4263     and live to of the operand is upto the ifx only then */
4264     if (ic->next &&
4265         ic->next->op == IFX &&
4266         IC_COND(ic->next)->key == op->key &&
4267         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4268         return ic->next;
4269
4270     if (ic->next &&
4271         ic->next->op == IFX &&
4272         IC_COND(ic->next)->key == op->key) {
4273       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4274       return ic->next;
4275     }
4276
4277     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4278     if (ic->next &&
4279         ic->next->op == IFX)
4280       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4281
4282     if (ic->next &&
4283         ic->next->op == IFX &&
4284         IC_COND(ic->next)->key == op->key) {
4285       DEBUGpic14_emitcode ("; "," key is okay");
4286       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4287                            OP_SYMBOL(op)->liveTo,
4288                            ic->next->seq);
4289     }
4290
4291
4292     return NULL;
4293 }
4294 /*-----------------------------------------------------------------*/
4295 /* genAndOp - for && operation                                     */
4296 /*-----------------------------------------------------------------*/
4297 static void genAndOp (iCode *ic)
4298 {
4299     operand *left,*right, *result;
4300     symbol *tlbl;
4301
4302     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4303     /* note here that && operations that are in an
4304     if statement are taken away by backPatchLabels
4305     only those used in arthmetic operations remain */
4306     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4307     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4308     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4309
4310     /* if both are bit variables */
4311     if (AOP_TYPE(left) == AOP_CRY &&
4312         AOP_TYPE(right) == AOP_CRY ) {
4313         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4314         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4315         pic14_outBitC(result);
4316     } else {
4317         tlbl = newiTempLabel(NULL);
4318         pic14_toBoolean(left);    
4319         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4320         pic14_toBoolean(right);
4321         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4322         pic14_outBitAcc(result);
4323     }
4324
4325     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4326     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4327     freeAsmop(result,NULL,ic,TRUE);
4328 }
4329
4330
4331 /*-----------------------------------------------------------------*/
4332 /* genOrOp - for || operation                                      */
4333 /*-----------------------------------------------------------------*/
4334 /*
4335   tsd pic port -
4336   modified this code, but it doesn't appear to ever get called
4337 */
4338
4339 static void genOrOp (iCode *ic)
4340 {
4341     operand *left,*right, *result;
4342     symbol *tlbl;
4343
4344     /* note here that || operations that are in an
4345     if statement are taken away by backPatchLabels
4346     only those used in arthmetic operations remain */
4347     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4348     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4349     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4350     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4351
4352     /* if both are bit variables */
4353     if (AOP_TYPE(left) == AOP_CRY &&
4354         AOP_TYPE(right) == AOP_CRY ) {
4355       pic14_emitcode("clrc","");
4356       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4357                AOP(left)->aopu.aop_dir,
4358                AOP(left)->aopu.aop_dir);
4359       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4360                AOP(right)->aopu.aop_dir,
4361                AOP(right)->aopu.aop_dir);
4362       pic14_emitcode("setc","");
4363
4364     } else {
4365         tlbl = newiTempLabel(NULL);
4366         pic14_toBoolean(left);
4367         emitSKPZ;
4368         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4369         pic14_toBoolean(right);
4370         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4371
4372         pic14_outBitAcc(result);
4373     }
4374
4375     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4376     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4377     freeAsmop(result,NULL,ic,TRUE);            
4378 }
4379
4380 /*-----------------------------------------------------------------*/
4381 /* isLiteralBit - test if lit == 2^n                               */
4382 /*-----------------------------------------------------------------*/
4383 static int isLiteralBit(unsigned long lit)
4384 {
4385     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4386     0x100L,0x200L,0x400L,0x800L,
4387     0x1000L,0x2000L,0x4000L,0x8000L,
4388     0x10000L,0x20000L,0x40000L,0x80000L,
4389     0x100000L,0x200000L,0x400000L,0x800000L,
4390     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4391     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4392     int idx;
4393     
4394     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4395     for(idx = 0; idx < 32; idx++)
4396         if(lit == pw[idx])
4397             return idx+1;
4398     return 0;
4399 }
4400
4401 /*-----------------------------------------------------------------*/
4402 /* continueIfTrue -                                                */
4403 /*-----------------------------------------------------------------*/
4404 static void continueIfTrue (iCode *ic)
4405 {
4406     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4407     if(IC_TRUE(ic))
4408         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4409     ic->generated = 1;
4410 }
4411
4412 /*-----------------------------------------------------------------*/
4413 /* jmpIfTrue -                                                     */
4414 /*-----------------------------------------------------------------*/
4415 static void jumpIfTrue (iCode *ic)
4416 {
4417     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4418     if(!IC_TRUE(ic))
4419         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4420     ic->generated = 1;
4421 }
4422
4423 /*-----------------------------------------------------------------*/
4424 /* jmpTrueOrFalse -                                                */
4425 /*-----------------------------------------------------------------*/
4426 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4427 {
4428     // ugly but optimized by peephole
4429     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4430     if(IC_TRUE(ic)){
4431         symbol *nlbl = newiTempLabel(NULL);
4432         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
4433         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4434         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4435         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4436     }
4437     else{
4438         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4439         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4440     }
4441     ic->generated = 1;
4442 }
4443
4444 /*-----------------------------------------------------------------*/
4445 /* genAnd  - code for and                                          */
4446 /*-----------------------------------------------------------------*/
4447 static void genAnd (iCode *ic, iCode *ifx)
4448 {
4449     operand *left, *right, *result;
4450     int size, offset=0;  
4451     unsigned long lit = 0L;
4452     int bytelit = 0;
4453     //    char buffer[10];
4454
4455     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4456     aopOp((left = IC_LEFT(ic)),ic,FALSE);
4457     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4458     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4459
4460 #ifdef DEBUG_TYPE
4461     pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4462              AOP_TYPE(result),
4463              AOP_TYPE(left), AOP_TYPE(right));
4464     pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4465              AOP_SIZE(result),
4466              AOP_SIZE(left), AOP_SIZE(right));
4467 #endif
4468
4469     /* if left is a literal & right is not then exchange them */
4470     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4471         AOP_NEEDSACC(left)) {
4472         operand *tmp = right ;
4473         right = left;
4474         left = tmp;
4475     }
4476
4477     /* if result = right then exchange them */
4478     if(pic14_sameRegs(AOP(result),AOP(right))){
4479         operand *tmp = right ;
4480         right = left;
4481         left = tmp;
4482     }
4483
4484     /* if right is bit then exchange them */
4485     if (AOP_TYPE(right) == AOP_CRY &&
4486         AOP_TYPE(left) != AOP_CRY){
4487         operand *tmp = right ;
4488         right = left;
4489         left = tmp;
4490     }
4491     if(AOP_TYPE(right) == AOP_LIT)
4492         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4493
4494     size = AOP_SIZE(result);
4495
4496     // if(bit & yy)
4497     // result = bit & yy;
4498     if (AOP_TYPE(left) == AOP_CRY){
4499         // c = bit & literal;
4500         if(AOP_TYPE(right) == AOP_LIT){
4501             if(lit & 1) {
4502                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4503                     // no change
4504                     goto release;
4505                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4506             } else {
4507                 // bit(result) = 0;
4508                 if(size && (AOP_TYPE(result) == AOP_CRY)){
4509                     pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4510                     goto release;
4511                 }
4512                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4513                     jumpIfTrue(ifx);
4514                     goto release;
4515                 }
4516                 pic14_emitcode("clr","c");
4517             }
4518         } else {
4519             if (AOP_TYPE(right) == AOP_CRY){
4520                 // c = bit & bit;
4521                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4522                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4523             } else {
4524                 // c = bit & val;
4525                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4526                 // c = lsb
4527                 pic14_emitcode("rrc","a");
4528                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4529             }
4530         }
4531         // bit = c
4532         // val = c
4533         if(size)
4534             pic14_outBitC(result);
4535         // if(bit & ...)
4536         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4537             genIfxJump(ifx, "c");           
4538         goto release ;
4539     }
4540
4541     // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
4542     // bit = val & 0xZZ     - size = 1, ifx = FALSE -
4543     if((AOP_TYPE(right) == AOP_LIT) &&
4544        (AOP_TYPE(result) == AOP_CRY) &&
4545        (AOP_TYPE(left) != AOP_CRY)){
4546         int posbit = isLiteralBit(lit);
4547         /* left &  2^n */
4548         if(posbit){
4549           posbit--;
4550           //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4551             // bit = left & 2^n
4552           if(size)
4553             pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4554             // if(left &  2^n)
4555           else{
4556             if(ifx){
4557               if(IC_TRUE(ifx)) {
4558                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4559                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4560               } else {
4561                 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4562                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4563               }
4564               ifx->generated = 1;
4565             }
4566             goto release;
4567           }
4568         } else {
4569             symbol *tlbl = newiTempLabel(NULL);
4570             int sizel = AOP_SIZE(left);
4571             if(size)
4572                 pic14_emitcode("setb","c");
4573             while(sizel--){
4574                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4575                     MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4576                     // byte ==  2^n ?
4577                     if((posbit = isLiteralBit(bytelit)) != 0)
4578                         pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4579                     else{
4580                         if(bytelit != 0x0FFL)
4581                             pic14_emitcode("anl","a,%s",
4582                                      aopGet(AOP(right),offset,FALSE,TRUE));
4583                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4584                     }
4585                 }
4586                 offset++;
4587             }
4588             // bit = left & literal
4589             if(size){
4590                 pic14_emitcode("clr","c");
4591                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4592             }
4593             // if(left & literal)
4594             else{
4595                 if(ifx)
4596                     jmpTrueOrFalse(ifx, tlbl);
4597                 goto release ;
4598             }
4599         }
4600         pic14_outBitC(result);
4601         goto release ;
4602     }
4603
4604     /* if left is same as result */
4605     if(pic14_sameRegs(AOP(result),AOP(left))){
4606       int know_W = -1;
4607       for(;size--; offset++,lit>>=8) {
4608         if(AOP_TYPE(right) == AOP_LIT){
4609           switch(lit & 0xff) {
4610           case 0x00:
4611             /*  and'ing with 0 has clears the result */
4612             pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4613             emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4614             break;
4615           case 0xff:
4616             /* and'ing with 0xff is a nop when the result and left are the same */
4617             break;
4618
4619           default:
4620             {
4621               int p = my_powof2( (~lit) & 0xff );
4622               if(p>=0) {
4623                 /* only one bit is set in the literal, so use a bcf instruction */
4624                 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4625                 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4626                 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4627
4628               } else {
4629                 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4630                 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4631                 if(know_W != (lit&0xff))
4632                   emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4633                 know_W = lit &0xff;
4634                 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4635               }
4636             }    
4637           }
4638         } else {
4639           if (AOP_TYPE(left) == AOP_ACC) {
4640             emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4641           } else {                  
4642             emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4643             emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4644
4645           }
4646         }
4647       }
4648
4649     } else {
4650         // left & result in different registers
4651         if(AOP_TYPE(result) == AOP_CRY){
4652             // result = bit
4653             // if(size), result in bit
4654             // if(!size && ifx), conditional oper: if(left & right)
4655             symbol *tlbl = newiTempLabel(NULL);
4656             int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4657             if(size)
4658                 pic14_emitcode("setb","c");
4659             while(sizer--){
4660                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4661                 pic14_emitcode("anl","a,%s",
4662                          aopGet(AOP(left),offset,FALSE,FALSE));
4663                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4664                 offset++;
4665             }
4666             if(size){
4667                 CLRC;
4668                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4669                 pic14_outBitC(result);
4670             } else if(ifx)
4671                 jmpTrueOrFalse(ifx, tlbl);
4672         } else {
4673           for(;(size--);offset++) {
4674             // normal case
4675             // result = left & right
4676             if(AOP_TYPE(right) == AOP_LIT){
4677               int t = (lit >> (offset*8)) & 0x0FFL;
4678               switch(t) { 
4679               case 0x00:
4680                 pic14_emitcode("clrf","%s",
4681                          aopGet(AOP(result),offset,FALSE,FALSE));
4682                 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4683                 break;
4684               case 0xff:
4685                 pic14_emitcode("movf","%s,w",
4686                          aopGet(AOP(left),offset,FALSE,FALSE));
4687                 pic14_emitcode("movwf","%s",
4688                          aopGet(AOP(result),offset,FALSE,FALSE));
4689                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4690                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4691                 break;
4692               default:
4693                 pic14_emitcode("movlw","0x%x",t);
4694                 pic14_emitcode("andwf","%s,w",
4695                          aopGet(AOP(left),offset,FALSE,FALSE));
4696                 pic14_emitcode("movwf","%s",
4697                          aopGet(AOP(result),offset,FALSE,FALSE));
4698               
4699                 emitpcode(POC_MOVLW, popGetLit(t));
4700                 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4701                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4702               }
4703               continue;
4704             }
4705
4706             if (AOP_TYPE(left) == AOP_ACC) {
4707               pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4708               emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4709             } else {
4710               pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4711               pic14_emitcode("andwf","%s,w",
4712                        aopGet(AOP(left),offset,FALSE,FALSE));
4713               emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4714               emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4715             }
4716             pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4717             emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4718           }
4719         }
4720     }
4721
4722 release :
4723     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4724     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4725     freeAsmop(result,NULL,ic,TRUE);     
4726 }
4727
4728 /*-----------------------------------------------------------------*/
4729 /* genOr  - code for or                                            */
4730 /*-----------------------------------------------------------------*/
4731 static void genOr (iCode *ic, iCode *ifx)
4732 {
4733     operand *left, *right, *result;
4734     int size, offset=0;
4735     unsigned long lit = 0L;
4736
4737     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4738
4739     aopOp((left = IC_LEFT(ic)),ic,FALSE);
4740     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4741     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4742
4743
4744     /* if left is a literal & right is not then exchange them */
4745     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4746         AOP_NEEDSACC(left)) {
4747         operand *tmp = right ;
4748         right = left;
4749         left = tmp;
4750     }
4751
4752     /* if result = right then exchange them */
4753     if(pic14_sameRegs(AOP(result),AOP(right))){
4754         operand *tmp = right ;
4755         right = left;
4756         left = tmp;
4757     }
4758
4759     /* if right is bit then exchange them */
4760     if (AOP_TYPE(right) == AOP_CRY &&
4761         AOP_TYPE(left) != AOP_CRY){
4762         operand *tmp = right ;
4763         right = left;
4764         left = tmp;
4765     }
4766
4767     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4768                          AopType(AOP_TYPE(result)),
4769                          AopType(AOP_TYPE(left)),
4770                          AopType(AOP_TYPE(right)));
4771
4772     if(AOP_TYPE(right) == AOP_LIT)
4773         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4774
4775     size = AOP_SIZE(result);
4776
4777     // if(bit | yy)
4778     // xx = bit | yy;
4779     if (AOP_TYPE(left) == AOP_CRY){
4780         if(AOP_TYPE(right) == AOP_LIT){
4781             // c = bit & literal;
4782             if(lit){
4783                 // lit != 0 => result = 1
4784                 if(AOP_TYPE(result) == AOP_CRY){
4785                   if(size)
4786                     emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4787                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4788                   //     AOP(result)->aopu.aop_dir,
4789                   //     AOP(result)->aopu.aop_dir);
4790                     else if(ifx)
4791                         continueIfTrue(ifx);
4792                     goto release;
4793                 }
4794             } else {
4795                 // lit == 0 => result = left
4796                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4797                     goto release;
4798                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4799             }
4800         } else {
4801             if (AOP_TYPE(right) == AOP_CRY){
4802               if(pic14_sameRegs(AOP(result),AOP(left))){
4803                 // c = bit | bit;
4804                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4805                 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4806                 emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4807
4808                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4809                          AOP(result)->aopu.aop_dir,
4810                          AOP(result)->aopu.aop_dir);
4811                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4812                          AOP(right)->aopu.aop_dir,
4813                          AOP(right)->aopu.aop_dir);
4814                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4815                          AOP(result)->aopu.aop_dir,
4816                          AOP(result)->aopu.aop_dir);
4817               } else {
4818                 if( AOP_TYPE(result) == AOP_ACC) {
4819                   emitpcode(POC_MOVLW, popGetLit(0));
4820                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4821                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4822                   emitpcode(POC_MOVLW, popGetLit(1));
4823
4824                 } else {
4825
4826                   emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4827                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4828                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4829                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4830
4831                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4832                                  AOP(result)->aopu.aop_dir,
4833                                  AOP(result)->aopu.aop_dir);
4834                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4835                                  AOP(right)->aopu.aop_dir,
4836                                  AOP(right)->aopu.aop_dir);
4837                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4838                                  AOP(left)->aopu.aop_dir,
4839                                  AOP(left)->aopu.aop_dir);
4840                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4841                                  AOP(result)->aopu.aop_dir,
4842                                  AOP(result)->aopu.aop_dir);
4843                 }
4844               }
4845             } else {
4846                 // c = bit | val;
4847                 symbol *tlbl = newiTempLabel(NULL);
4848                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4849
4850
4851                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4852                 if( AOP_TYPE(right) == AOP_ACC) {
4853                   emitpcode(POC_IORLW, popGetLit(0));
4854                   emitSKPNZ;
4855                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4856                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4857                 }
4858
4859
4860
4861                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4862                     pic14_emitcode(";XXX setb","c");
4863                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4864                          AOP(left)->aopu.aop_dir,tlbl->key+100);
4865                 pic14_toBoolean(right);
4866                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4867                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4868                     jmpTrueOrFalse(ifx, tlbl);
4869                     goto release;
4870                 } else {
4871                     CLRC;
4872                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4873                 }
4874             }
4875         }
4876         // bit = c
4877         // val = c
4878         if(size)
4879             pic14_outBitC(result);
4880         // if(bit | ...)
4881         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4882             genIfxJump(ifx, "c");           
4883         goto release ;
4884     }
4885
4886     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
4887     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
4888     if((AOP_TYPE(right) == AOP_LIT) &&
4889        (AOP_TYPE(result) == AOP_CRY) &&
4890        (AOP_TYPE(left) != AOP_CRY)){
4891         if(lit){
4892           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4893             // result = 1
4894             if(size)
4895                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4896             else 
4897                 continueIfTrue(ifx);
4898             goto release;
4899         } else {
4900           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4901             // lit = 0, result = boolean(left)
4902             if(size)
4903                 pic14_emitcode(";XXX setb","c");
4904             pic14_toBoolean(right);
4905             if(size){
4906                 symbol *tlbl = newiTempLabel(NULL);
4907                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4908                 CLRC;
4909                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4910             } else {
4911                 genIfxJump (ifx,"a");
4912                 goto release;
4913             }
4914         }
4915         pic14_outBitC(result);
4916         goto release ;
4917     }
4918
4919     /* if left is same as result */
4920     if(pic14_sameRegs(AOP(result),AOP(left))){
4921       int know_W = -1;
4922       for(;size--; offset++,lit>>=8) {
4923         if(AOP_TYPE(right) == AOP_LIT){
4924           if((lit & 0xff) == 0)
4925             /*  or'ing with 0 has no effect */
4926             continue;
4927           else {
4928             int p = my_powof2(lit & 0xff);
4929             if(p>=0) {
4930               /* only one bit is set in the literal, so use a bsf instruction */
4931               emitpcode(POC_BSF,
4932                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4933             } else {
4934               if(know_W != (lit & 0xff))
4935                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4936               know_W = lit & 0xff;
4937               emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4938             }
4939                     
4940           }
4941         } else {
4942           if (AOP_TYPE(left) == AOP_ACC) {
4943             emitpcode(POC_IORFW,  popGet(AOP(right),offset,FALSE,FALSE));
4944             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4945           } else {                  
4946             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
4947             emitpcode(POC_IORWF,  popGet(AOP(left),offset,FALSE,FALSE));
4948
4949             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4950             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4951
4952           }
4953         }
4954       }
4955     } else {
4956         // left & result in different registers
4957         if(AOP_TYPE(result) == AOP_CRY){
4958             // result = bit
4959             // if(size), result in bit
4960             // if(!size && ifx), conditional oper: if(left | right)
4961             symbol *tlbl = newiTempLabel(NULL);
4962             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4963             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4964
4965
4966             if(size)
4967                 pic14_emitcode(";XXX setb","c");
4968             while(sizer--){
4969                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4970                 pic14_emitcode(";XXX orl","a,%s",
4971                          aopGet(AOP(left),offset,FALSE,FALSE));
4972                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4973                 offset++;
4974             }
4975             if(size){
4976                 CLRC;
4977                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4978                 pic14_outBitC(result);
4979             } else if(ifx)
4980                 jmpTrueOrFalse(ifx, tlbl);
4981         } else for(;(size--);offset++){
4982           // normal case
4983           // result = left & right
4984           if(AOP_TYPE(right) == AOP_LIT){
4985             int t = (lit >> (offset*8)) & 0x0FFL;
4986             switch(t) { 
4987             case 0x00:
4988               emitpcode(POC_MOVFW,  popGet(AOP(left),offset,FALSE,FALSE));
4989               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
4990
4991               pic14_emitcode("movf","%s,w",
4992                        aopGet(AOP(left),offset,FALSE,FALSE));
4993               pic14_emitcode("movwf","%s",
4994                        aopGet(AOP(result),offset,FALSE,FALSE));
4995               break;
4996             default:
4997               emitpcode(POC_MOVLW,  popGetLit(t));
4998               emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
4999               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5000
5001               pic14_emitcode("movlw","0x%x",t);
5002               pic14_emitcode("iorwf","%s,w",
5003                        aopGet(AOP(left),offset,FALSE,FALSE));
5004               pic14_emitcode("movwf","%s",
5005                        aopGet(AOP(result),offset,FALSE,FALSE));
5006               
5007             }
5008             continue;
5009           }
5010
5011           // faster than result <- left, anl result,right
5012           // and better if result is SFR
5013           if (AOP_TYPE(left) == AOP_ACC) {
5014             emitpcode(POC_IORWF,  popGet(AOP(right),offset,FALSE,FALSE));
5015             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5016           } else {
5017             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
5018             emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
5019
5020             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5021             pic14_emitcode("iorwf","%s,w",
5022                      aopGet(AOP(left),offset,FALSE,FALSE));
5023           }
5024           emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5025           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5026         }
5027     }
5028
5029 release :
5030     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032     freeAsmop(result,NULL,ic,TRUE);     
5033 }
5034
5035 /*-----------------------------------------------------------------*/
5036 /* genXor - code for xclusive or                                   */
5037 /*-----------------------------------------------------------------*/
5038 static void genXor (iCode *ic, iCode *ifx)
5039 {
5040     operand *left, *right, *result;
5041     int size, offset=0;
5042     unsigned long lit = 0L;
5043
5044     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5045
5046     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5047     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5048     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5049
5050     /* if left is a literal & right is not ||
5051        if left needs acc & right does not */
5052     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5053         (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5054         operand *tmp = right ;
5055         right = left;
5056         left = tmp;
5057     }
5058
5059     /* if result = right then exchange them */
5060     if(pic14_sameRegs(AOP(result),AOP(right))){
5061         operand *tmp = right ;
5062         right = left;
5063         left = tmp;
5064     }
5065
5066     /* if right is bit then exchange them */
5067     if (AOP_TYPE(right) == AOP_CRY &&
5068         AOP_TYPE(left) != AOP_CRY){
5069         operand *tmp = right ;
5070         right = left;
5071         left = tmp;
5072     }
5073     if(AOP_TYPE(right) == AOP_LIT)
5074         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5075
5076     size = AOP_SIZE(result);
5077
5078     // if(bit ^ yy)
5079     // xx = bit ^ yy;
5080     if (AOP_TYPE(left) == AOP_CRY){
5081         if(AOP_TYPE(right) == AOP_LIT){
5082             // c = bit & literal;
5083             if(lit>>1){
5084                 // lit>>1  != 0 => result = 1
5085                 if(AOP_TYPE(result) == AOP_CRY){
5086                     if(size)
5087                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5088                     else if(ifx)
5089                         continueIfTrue(ifx);
5090                     goto release;
5091                 }
5092                 pic14_emitcode("setb","c");
5093             } else{
5094                 // lit == (0 or 1)
5095                 if(lit == 0){
5096                     // lit == 0, result = left
5097                     if(size && pic14_sameRegs(AOP(result),AOP(left)))
5098                         goto release;
5099                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5100                 } else{
5101                     // lit == 1, result = not(left)
5102                     if(size && pic14_sameRegs(AOP(result),AOP(left))){
5103                         pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5104                         goto release;
5105                     } else {
5106                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5107                         pic14_emitcode("cpl","c");
5108                     }
5109                 }
5110             }
5111
5112         } else {
5113             // right != literal
5114             symbol *tlbl = newiTempLabel(NULL);
5115             if (AOP_TYPE(right) == AOP_CRY){
5116                 // c = bit ^ bit;
5117                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5118             }
5119             else{
5120                 int sizer = AOP_SIZE(right);
5121                 // c = bit ^ val
5122                 // if val>>1 != 0, result = 1
5123                 pic14_emitcode("setb","c");
5124                 while(sizer){
5125                     MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5126                     if(sizer == 1)
5127                         // test the msb of the lsb
5128                         pic14_emitcode("anl","a,#0xfe");
5129                     pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5130                     sizer--;
5131                 }
5132                 // val = (0,1)
5133                 pic14_emitcode("rrc","a");
5134             }
5135             pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5136             pic14_emitcode("cpl","c");
5137             pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5138         }
5139         // bit = c
5140         // val = c
5141         if(size)
5142             pic14_outBitC(result);
5143         // if(bit | ...)
5144         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5145             genIfxJump(ifx, "c");           
5146         goto release ;
5147     }
5148
5149     if(pic14_sameRegs(AOP(result),AOP(left))){
5150         /* if left is same as result */
5151         for(;size--; offset++) {
5152             if(AOP_TYPE(right) == AOP_LIT){
5153               int t  = (lit >> (offset*8)) & 0x0FFL;
5154                 if(t == 0x00L)
5155                     continue;
5156                 else
5157                     if (IS_AOP_PREG(left)) {
5158                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5159                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5160                         aopPut(AOP(result),"a",offset);
5161                     } else {
5162                       emitpcode(POC_MOVLW, popGetLit(t));
5163                       emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5164                       pic14_emitcode("xrl","%s,%s",
5165                                      aopGet(AOP(left),offset,FALSE,TRUE),
5166                                      aopGet(AOP(right),offset,FALSE,FALSE));
5167                     }
5168             } else {
5169                 if (AOP_TYPE(left) == AOP_ACC)
5170                     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5171                 else {
5172                     MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5173                     if (IS_AOP_PREG(left)) {
5174                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5175                         aopPut(AOP(result),"a",offset);
5176                     } else
5177                         pic14_emitcode("xrl","%s,a",
5178                                  aopGet(AOP(left),offset,FALSE,TRUE));
5179                 }
5180             }
5181         }
5182     } else {
5183         // left & result in different registers
5184         if(AOP_TYPE(result) == AOP_CRY){
5185             // result = bit
5186             // if(size), result in bit
5187             // if(!size && ifx), conditional oper: if(left ^ right)
5188             symbol *tlbl = newiTempLabel(NULL);
5189             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5190             if(size)
5191                 pic14_emitcode("setb","c");
5192             while(sizer--){
5193                 if((AOP_TYPE(right) == AOP_LIT) &&
5194                    (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5195                     MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5196                 } else {
5197                     MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5198                     pic14_emitcode("xrl","a,%s",
5199                              aopGet(AOP(left),offset,FALSE,FALSE));
5200                 }
5201                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5202                 offset++;
5203             }
5204             if(size){
5205                 CLRC;
5206                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5207                 pic14_outBitC(result);
5208             } else if(ifx)
5209                 jmpTrueOrFalse(ifx, tlbl);
5210         } else for(;(size--);offset++){
5211             // normal case
5212             // result = left & right
5213             if(AOP_TYPE(right) == AOP_LIT){
5214               int t = (lit >> (offset*8)) & 0x0FFL;
5215               switch(t) { 
5216               case 0x00:
5217                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5218                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5219                 pic14_emitcode("movf","%s,w",
5220                          aopGet(AOP(left),offset,FALSE,FALSE));
5221                 pic14_emitcode("movwf","%s",
5222                          aopGet(AOP(result),offset,FALSE,FALSE));
5223                 break;
5224               case 0xff:
5225                 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5226                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5227                 pic14_emitcode("comf","%s,w",
5228                          aopGet(AOP(left),offset,FALSE,FALSE));
5229                 pic14_emitcode("movwf","%s",
5230                          aopGet(AOP(result),offset,FALSE,FALSE));
5231                 break;
5232               default:
5233                 emitpcode(POC_MOVLW, popGetLit(t));
5234                 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5235                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5236                 pic14_emitcode("movlw","0x%x",t);
5237                 pic14_emitcode("xorwf","%s,w",
5238                          aopGet(AOP(left),offset,FALSE,FALSE));
5239                 pic14_emitcode("movwf","%s",
5240                          aopGet(AOP(result),offset,FALSE,FALSE));
5241
5242               }
5243               continue;
5244             }
5245
5246             // faster than result <- left, anl result,right
5247             // and better if result is SFR
5248             if (AOP_TYPE(left) == AOP_ACC) {
5249                 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5250                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5251             } else {
5252                 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5253                 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5254                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5255                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5256             }
5257             if ( AOP_TYPE(result) != AOP_ACC){
5258                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5259               pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5260             }
5261         }
5262     }
5263
5264 release :
5265     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5266     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5267     freeAsmop(result,NULL,ic,TRUE);     
5268 }
5269
5270 /*-----------------------------------------------------------------*/
5271 /* genInline - write the inline code out                           */
5272 /*-----------------------------------------------------------------*/
5273 static void genInline (iCode *ic)
5274 {
5275     char *buffer, *bp, *bp1;
5276     
5277     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5278
5279     _G.inLine += (!options.asmpeep);
5280
5281     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5282     strcpy(buffer,IC_INLINE(ic));
5283
5284     /* emit each line as a code */
5285     while (*bp) {
5286         if (*bp == '\n') {
5287             *bp++ = '\0';
5288             pic14_emitcode(bp1,"");
5289             bp1 = bp;
5290         } else {
5291             if (*bp == ':') {
5292                 bp++;
5293                 *bp = '\0';
5294                 bp++;
5295                 pic14_emitcode(bp1,"");
5296                 bp1 = bp;
5297             } else
5298                 bp++;
5299         }
5300     }
5301     if (bp1 != bp)
5302         pic14_emitcode(bp1,"");
5303     /*     pic14_emitcode("",buffer); */
5304     _G.inLine -= (!options.asmpeep);
5305 }
5306
5307 /*-----------------------------------------------------------------*/
5308 /* genRRC - rotate right with carry                                */
5309 /*-----------------------------------------------------------------*/
5310 static void genRRC (iCode *ic)
5311 {
5312     operand *left , *result ;
5313     int size, offset = 0;
5314     char *l;    
5315
5316     /* rotate right with carry */
5317     left = IC_LEFT(ic);
5318     result=IC_RESULT(ic);
5319     aopOp (left,ic,FALSE);
5320     aopOp (result,ic,FALSE);
5321
5322     /* move it to the result */
5323     size = AOP_SIZE(result);    
5324     offset = size - 1 ;
5325     CLRC;
5326     while (size--) {
5327         l = aopGet(AOP(left),offset,FALSE,FALSE);
5328         MOVA(l);
5329         pic14_emitcode("rrc","a");
5330         if (AOP_SIZE(result) > 1)
5331             aopPut(AOP(result),"a",offset--);
5332     }
5333     /* now we need to put the carry into the
5334     highest order byte of the result */
5335     if (AOP_SIZE(result) > 1) {
5336         l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5337         MOVA(l);
5338     }
5339     pic14_emitcode("mov","acc.7,c");
5340     aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5341     freeAsmop(left,NULL,ic,TRUE);
5342     freeAsmop(result,NULL,ic,TRUE);
5343 }
5344
5345 /*-----------------------------------------------------------------*/
5346 /* genRLC - generate code for rotate left with carry               */
5347 /*-----------------------------------------------------------------*/
5348 static void genRLC (iCode *ic)
5349 {    
5350     operand *left , *result ;
5351     int size, offset = 0;
5352     char *l;    
5353
5354     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5355     /* rotate right with carry */
5356     left = IC_LEFT(ic);
5357     result=IC_RESULT(ic);
5358     aopOp (left,ic,FALSE);
5359     aopOp (result,ic,FALSE);
5360
5361     /* move it to the result */
5362     size = AOP_SIZE(result);    
5363     offset = 0 ;
5364     if (size--) {
5365         l = aopGet(AOP(left),offset,FALSE,FALSE);
5366         MOVA(l);
5367         pic14_emitcode("add","a,acc");
5368         if (AOP_SIZE(result) > 1)
5369             aopPut(AOP(result),"a",offset++);
5370         while (size--) {
5371             l = aopGet(AOP(left),offset,FALSE,FALSE);
5372             MOVA(l);
5373             pic14_emitcode("rlc","a");
5374             if (AOP_SIZE(result) > 1)
5375                 aopPut(AOP(result),"a",offset++);
5376         }
5377     }
5378     /* now we need to put the carry into the
5379     highest order byte of the result */
5380     if (AOP_SIZE(result) > 1) {
5381         l = aopGet(AOP(result),0,FALSE,FALSE);
5382         MOVA(l);
5383     }
5384     pic14_emitcode("mov","acc.0,c");
5385     aopPut(AOP(result),"a",0);
5386     freeAsmop(left,NULL,ic,TRUE);
5387     freeAsmop(result,NULL,ic,TRUE);
5388 }
5389
5390 /*-----------------------------------------------------------------*/
5391 /* genGetHbit - generates code get highest order bit               */
5392 /*-----------------------------------------------------------------*/
5393 static void genGetHbit (iCode *ic)
5394 {
5395     operand *left, *result;
5396     left = IC_LEFT(ic);
5397     result=IC_RESULT(ic);
5398     aopOp (left,ic,FALSE);
5399     aopOp (result,ic,FALSE);
5400
5401     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5402     /* get the highest order byte into a */
5403     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5404     if(AOP_TYPE(result) == AOP_CRY){
5405         pic14_emitcode("rlc","a");
5406         pic14_outBitC(result);
5407     }
5408     else{
5409         pic14_emitcode("rl","a");
5410         pic14_emitcode("anl","a,#0x01");
5411         pic14_outAcc(result);
5412     }
5413
5414
5415     freeAsmop(left,NULL,ic,TRUE);
5416     freeAsmop(result,NULL,ic,TRUE);
5417 }
5418
5419 /*-----------------------------------------------------------------*/
5420 /* AccRol - rotate left accumulator by known count                 */
5421 /*-----------------------------------------------------------------*/
5422 static void AccRol (int shCount)
5423 {
5424     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5425     shCount &= 0x0007;              // shCount : 0..7
5426     switch(shCount){
5427         case 0 :
5428             break;
5429         case 1 :
5430             pic14_emitcode("rl","a");
5431             break;
5432         case 2 :
5433             pic14_emitcode("rl","a");
5434             pic14_emitcode("rl","a");
5435             break;
5436         case 3 :
5437             pic14_emitcode("swap","a");
5438             pic14_emitcode("rr","a");
5439             break;
5440         case 4 :
5441             pic14_emitcode("swap","a");
5442             break;
5443         case 5 :
5444             pic14_emitcode("swap","a");
5445             pic14_emitcode("rl","a");
5446             break;
5447         case 6 :
5448             pic14_emitcode("rr","a");
5449             pic14_emitcode("rr","a");
5450             break;
5451         case 7 :
5452             pic14_emitcode("rr","a");
5453             break;
5454     }
5455 }
5456
5457 /*-----------------------------------------------------------------*/
5458 /* AccLsh - left shift accumulator by known count                  */
5459 /*-----------------------------------------------------------------*/
5460 static void AccLsh (int shCount)
5461 {
5462     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5463     if(shCount != 0){
5464         if(shCount == 1)
5465             pic14_emitcode("add","a,acc");
5466         else 
5467             if(shCount == 2) {
5468             pic14_emitcode("add","a,acc");
5469             pic14_emitcode("add","a,acc");
5470         } else {
5471             /* rotate left accumulator */
5472             AccRol(shCount);
5473             /* and kill the lower order bits */
5474             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5475         }
5476     }
5477 }
5478
5479 /*-----------------------------------------------------------------*/
5480 /* AccRsh - right shift accumulator by known count                 */
5481 /*-----------------------------------------------------------------*/
5482 static void AccRsh (int shCount)
5483 {
5484     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5485     if(shCount != 0){
5486         if(shCount == 1){
5487             CLRC;
5488             pic14_emitcode("rrc","a");
5489         } else {
5490             /* rotate right accumulator */
5491             AccRol(8 - shCount);
5492             /* and kill the higher order bits */
5493             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5494         }
5495     }
5496 }
5497
5498 #if 0
5499 /*-----------------------------------------------------------------*/
5500 /* AccSRsh - signed right shift accumulator by known count                 */
5501 /*-----------------------------------------------------------------*/
5502 static void AccSRsh (int shCount)
5503 {
5504     symbol *tlbl ;
5505     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5506     if(shCount != 0){
5507         if(shCount == 1){
5508             pic14_emitcode("mov","c,acc.7");
5509             pic14_emitcode("rrc","a");
5510         } else if(shCount == 2){
5511             pic14_emitcode("mov","c,acc.7");
5512             pic14_emitcode("rrc","a");
5513             pic14_emitcode("mov","c,acc.7");
5514             pic14_emitcode("rrc","a");
5515         } else {
5516             tlbl = newiTempLabel(NULL);
5517             /* rotate right accumulator */
5518             AccRol(8 - shCount);
5519             /* and kill the higher order bits */
5520             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5521             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5522             pic14_emitcode("orl","a,#0x%02x",
5523                      (unsigned char)~SRMask[shCount]);
5524             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5525         }
5526     }
5527 }
5528 #endif
5529 /*-----------------------------------------------------------------*/
5530 /* shiftR1Left2Result - shift right one byte from left to result   */
5531 /*-----------------------------------------------------------------*/
5532 static void shiftR1Left2ResultSigned (operand *left, int offl,
5533                                 operand *result, int offr,
5534                                 int shCount)
5535 {
5536   int same;
5537
5538   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5539
5540   same = (left == result) || (AOP(left) == AOP(result));
5541
5542   switch(shCount) {
5543   case 1:
5544     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5545     if(same) 
5546       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5547     else {
5548       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5549       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5550     }
5551
5552     break;
5553
5554   default:
5555     break;
5556   }
5557 }
5558
5559 /*-----------------------------------------------------------------*/
5560 /* shiftR1Left2Result - shift right one byte from left to result   */
5561 /*-----------------------------------------------------------------*/
5562 static void shiftR1Left2Result (operand *left, int offl,
5563                                 operand *result, int offr,
5564                                 int shCount, int sign)
5565 {
5566   int same;
5567
5568   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5569
5570   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5571
5572   /* Copy the msb into the carry if signed. */
5573   if(sign) {
5574     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5575     return;
5576   }
5577
5578
5579
5580   switch(shCount) {
5581   case 1:
5582     emitCLRC;
5583     if(same) 
5584       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5585     else {
5586       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5587       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5588     }
5589     break;
5590   case 2:
5591     emitCLRC;
5592     if(same) {
5593       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5594     } else {
5595       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5596       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5597     }
5598     emitCLRC;
5599     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5600
5601     break;
5602   case 3:
5603     if(same) 
5604       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5605     else {
5606       emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5607       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5608     }
5609
5610     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5611     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5612     emitpcode(POC_ANDLW, popGetLit(0x1f));
5613     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5614     break;
5615       
5616   case 4:
5617     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5618     emitpcode(POC_ANDLW, popGetLit(0x0f));
5619     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5620     break;
5621
5622   case 5:
5623     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5624     emitpcode(POC_ANDLW, popGetLit(0x0f));
5625     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5626     emitCLRC;
5627     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5628
5629     break;
5630   case 6:
5631
5632     emitpcode(POC_RLFW,  popGet(AOP(left),offl,FALSE,FALSE));
5633     emitpcode(POC_ANDLW, popGetLit(0x80));
5634     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5635     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5636     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5637     break;
5638
5639   case 7:
5640
5641     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5642     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5643     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5644
5645     break;
5646
5647   default:
5648     break;
5649   }
5650
5651
5652 #if 0
5653     
5654   MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5655
5656   /* shift right accumulator */
5657   if(sign)
5658     AccSRsh(shCount);
5659   else
5660     AccRsh(shCount);
5661   aopPut(AOP(result),"a",offr);
5662 #endif
5663 }
5664
5665 /*-----------------------------------------------------------------*/
5666 /* shiftL1Left2Result - shift left one byte from left to result    */
5667 /*-----------------------------------------------------------------*/
5668 static void shiftL1Left2Result (operand *left, int offl,
5669                                 operand *result, int offr, int shCount)
5670 {
5671   int same;
5672
5673   //    char *l;
5674   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5675
5676   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5677   DEBUGpic14_emitcode ("; ***","same =  %d",same);
5678     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
5679     //    MOVA(l);
5680     /* shift left accumulator */
5681     //AccLsh(shCount); // don't comment out just yet...
5682   //    aopPut(AOP(result),"a",offr);
5683
5684   switch(shCount) {
5685   case 1:
5686     /* Shift left 1 bit position */
5687     emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5688     if(same) {
5689       emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5690     } else {
5691       emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5692       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5693     }
5694     break;
5695   case 2:
5696     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5697     emitpcode(POC_ANDLW,popGetLit(0x7e));
5698     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5699     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5700     break;
5701   case 3:
5702     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5703     emitpcode(POC_ANDLW,popGetLit(0x3e));
5704     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5705     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5706     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5707     break;
5708   case 4:
5709     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5710     emitpcode(POC_ANDLW, popGetLit(0xf0));
5711     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5712     break;
5713   case 5:
5714     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5715     emitpcode(POC_ANDLW, popGetLit(0xf0));
5716     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5717     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5718     break;
5719   case 6:
5720     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5721     emitpcode(POC_ANDLW, popGetLit(0x30));
5722     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5723     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5724     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5725     break;
5726   case 7:
5727     emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5728     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5729     emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
5730     break;
5731
5732   default:
5733     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5734   }
5735
5736 }
5737
5738 /*-----------------------------------------------------------------*/
5739 /* movLeft2Result - move byte from left to result                  */
5740 /*-----------------------------------------------------------------*/
5741 static void movLeft2Result (operand *left, int offl,
5742                             operand *result, int offr, int sign)
5743 {
5744     char *l;
5745     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5746     if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5747         l = aopGet(AOP(left),offl,FALSE,FALSE);
5748
5749         if (*l == '@' && (IS_AOP_PREG(result))) {
5750             pic14_emitcode("mov","a,%s",l);
5751             aopPut(AOP(result),"a",offr);
5752         } else {
5753           if(!sign) {
5754             emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5755             emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5756
5757             //aopPut(AOP(result),l,offr);
5758           }else{
5759                 /* MSB sign in acc.7 ! */
5760                 if(pic14_getDataSize(left) == offl+1){
5761                     pic14_emitcode("mov","a,%s",l);
5762                     aopPut(AOP(result),"a",offr);
5763                 }
5764             }
5765         }
5766     }
5767 }
5768
5769 /*-----------------------------------------------------------------*/
5770 /* AccAXRrl1 - right rotate c->a:x->c by 1                         */
5771 /*-----------------------------------------------------------------*/
5772 static void AccAXRrl1 (char *x)
5773 {
5774     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5775     pic14_emitcode("rrc","a");
5776     pic14_emitcode("xch","a,%s", x);
5777     pic14_emitcode("rrc","a");
5778     pic14_emitcode("xch","a,%s", x);
5779 }
5780
5781 /*-----------------------------------------------------------------*/
5782 /* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
5783 /*-----------------------------------------------------------------*/
5784 static void AccAXLrl1 (char *x)
5785 {
5786     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5787     pic14_emitcode("xch","a,%s",x);
5788     pic14_emitcode("rlc","a");
5789     pic14_emitcode("xch","a,%s",x);
5790     pic14_emitcode("rlc","a");
5791 }
5792 #if 0
5793 /*-----------------------------------------------------------------*/
5794 /* AccAXLsh1 - left shift a:x<-0 by 1                              */
5795 /*-----------------------------------------------------------------*/
5796 static void AccAXLsh1 (char *x)
5797 {
5798     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5799     pic14_emitcode("xch","a,%s",x);
5800     pic14_emitcode("add","a,acc");
5801     pic14_emitcode("xch","a,%s",x);
5802     pic14_emitcode("rlc","a");
5803 }
5804 #endif
5805 #if 0
5806 /*-----------------------------------------------------------------*/
5807 /* AccAXLsh - left shift a:x by known count (0..7)                 */
5808 /*-----------------------------------------------------------------*/
5809 static void AccAXLsh (char *x, int shCount)
5810 {
5811     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5812     switch(shCount){
5813         case 0 :
5814             break;
5815         case 1 :
5816             AccAXLsh1(x);
5817             break;
5818         case 2 :
5819             AccAXLsh1(x);
5820             AccAXLsh1(x);
5821             break;
5822         case 3 :
5823         case 4 :
5824         case 5 :                        // AAAAABBB:CCCCCDDD
5825             AccRol(shCount);            // BBBAAAAA:CCCCCDDD
5826             pic14_emitcode("anl","a,#0x%02x",
5827                      SLMask[shCount]);  // BBB00000:CCCCCDDD
5828             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBB00000
5829             AccRol(shCount);            // DDDCCCCC:BBB00000
5830             pic14_emitcode("xch","a,%s",x);   // BBB00000:DDDCCCCC
5831             pic14_emitcode("xrl","a,%s",x);   // (BBB^DDD)CCCCC:DDDCCCCC
5832             pic14_emitcode("xch","a,%s",x);   // DDDCCCCC:(BBB^DDD)CCCCC
5833             pic14_emitcode("anl","a,#0x%02x",
5834                      SLMask[shCount]);  // DDD00000:(BBB^DDD)CCCCC
5835             pic14_emitcode("xch","a,%s",x);   // (BBB^DDD)CCCCC:DDD00000
5836             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:DDD00000            
5837             break;
5838         case 6 :                        // AAAAAABB:CCCCCCDD
5839             pic14_emitcode("anl","a,#0x%02x",
5840                      SRMask[shCount]);  // 000000BB:CCCCCCDD
5841             pic14_emitcode("mov","c,acc.0");  // c = B
5842             pic14_emitcode("xch","a,%s",x);   // CCCCCCDD:000000BB
5843             AccAXRrl1(x);               // BCCCCCCD:D000000B
5844             AccAXRrl1(x);               // BBCCCCCC:DD000000
5845             break;
5846         case 7 :                        // a:x <<= 7
5847             pic14_emitcode("anl","a,#0x%02x",
5848                      SRMask[shCount]);  // 0000000B:CCCCCCCD
5849             pic14_emitcode("mov","c,acc.0");  // c = B
5850             pic14_emitcode("xch","a,%s",x);   // CCCCCCCD:0000000B
5851             AccAXRrl1(x);               // BCCCCCCC:D0000000
5852             break;
5853         default :
5854             break;
5855     }
5856 }
5857 #endif
5858 #if 0
5859 /*-----------------------------------------------------------------*/
5860 /* AccAXRsh - right shift a:x known count (0..7)                   */
5861 /*-----------------------------------------------------------------*/
5862 static void AccAXRsh (char *x, int shCount)
5863 {   
5864     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5865     switch(shCount){
5866         case 0 :
5867             break;
5868         case 1 :
5869             CLRC;
5870             AccAXRrl1(x);               // 0->a:x
5871             break;
5872         case 2 :
5873             CLRC;
5874             AccAXRrl1(x);               // 0->a:x
5875             CLRC;
5876             AccAXRrl1(x);               // 0->a:x
5877             break;
5878         case 3 :
5879         case 4 :
5880         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
5881             AccRol(8 - shCount);        // BBBAAAAA:DDDCCCCC
5882             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
5883             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
5884             pic14_emitcode("anl","a,#0x%02x",
5885                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
5886             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
5887             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
5888             pic14_emitcode("anl","a,#0x%02x",
5889                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
5890             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
5891             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
5892             pic14_emitcode("xch","a,%s",x);   // 000AAAAA:BBBCCCCC
5893             break;
5894         case 6 :                        // AABBBBBB:CCDDDDDD
5895             pic14_emitcode("mov","c,acc.7");
5896             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
5897             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
5898             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
5899             pic14_emitcode("anl","a,#0x%02x",
5900                      SRMask[shCount]);  // 000000AA:BBBBBBCC
5901             break;
5902         case 7 :                        // ABBBBBBB:CDDDDDDD
5903             pic14_emitcode("mov","c,acc.7");  // c = A
5904             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
5905             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
5906             pic14_emitcode("anl","a,#0x%02x",
5907                      SRMask[shCount]);  // 0000000A:BBBBBBBC
5908             break;
5909         default :
5910             break;
5911     }
5912 }
5913 #endif
5914 /*-----------------------------------------------------------------*/
5915 /* AccAXRshS - right shift signed a:x known count (0..7)           */
5916 /*-----------------------------------------------------------------*/
5917 static void AccAXRshS (char *x, int shCount)
5918 {   
5919     symbol *tlbl ;
5920     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5921     switch(shCount){
5922         case 0 :
5923             break;
5924         case 1 :
5925             pic14_emitcode("mov","c,acc.7");
5926             AccAXRrl1(x);               // s->a:x
5927             break;
5928         case 2 :
5929             pic14_emitcode("mov","c,acc.7");
5930             AccAXRrl1(x);               // s->a:x
5931             pic14_emitcode("mov","c,acc.7");
5932             AccAXRrl1(x);               // s->a:x
5933             break;
5934         case 3 :
5935         case 4 :
5936         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
5937             tlbl = newiTempLabel(NULL);
5938             AccRol(8 - shCount);        // BBBAAAAA:CCCCCDDD
5939             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
5940             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
5941             pic14_emitcode("anl","a,#0x%02x",
5942                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
5943             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
5944             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
5945             pic14_emitcode("anl","a,#0x%02x",
5946                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
5947             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
5948             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
5949             pic14_emitcode("xch","a,%s",x);   // 000SAAAA:BBBCCCCC
5950             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5951             pic14_emitcode("orl","a,#0x%02x",
5952                      (unsigned char)~SRMask[shCount]);  // 111AAAAA:BBBCCCCC
5953             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5954             break;                      // SSSSAAAA:BBBCCCCC
5955         case 6 :                        // AABBBBBB:CCDDDDDD
5956             tlbl = newiTempLabel(NULL);
5957             pic14_emitcode("mov","c,acc.7");
5958             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
5959             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
5960             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
5961             pic14_emitcode("anl","a,#0x%02x",
5962                      SRMask[shCount]);  // 000000AA:BBBBBBCC
5963             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5964             pic14_emitcode("orl","a,#0x%02x",
5965                      (unsigned char)~SRMask[shCount]);  // 111111AA:BBBBBBCC
5966             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5967             break;
5968         case 7 :                        // ABBBBBBB:CDDDDDDD
5969             tlbl = newiTempLabel(NULL);
5970             pic14_emitcode("mov","c,acc.7");  // c = A
5971             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
5972             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
5973             pic14_emitcode("anl","a,#0x%02x",
5974                      SRMask[shCount]);  // 0000000A:BBBBBBBC
5975             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5976             pic14_emitcode("orl","a,#0x%02x",
5977                      (unsigned char)~SRMask[shCount]);  // 1111111A:BBBBBBBC
5978             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5979             break;
5980         default :
5981             break;
5982     }
5983 }
5984
5985 /*-----------------------------------------------------------------*/
5986 /* shiftL2Left2Result - shift left two bytes from left to result   */
5987 /*-----------------------------------------------------------------*/
5988 static void shiftL2Left2Result (operand *left, int offl,
5989                                 operand *result, int offr, int shCount)
5990 {
5991
5992
5993   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5994
5995   if(pic14_sameRegs(AOP(result), AOP(left))) {
5996     switch(shCount) {
5997     case 0:
5998       break;
5999     case 1:
6000     case 2:
6001     case 3:
6002
6003       emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6004       emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6005       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6006
6007       while(--shCount) {
6008         emitCLRC;
6009         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6010         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6011       }
6012
6013       break;
6014     case 4:
6015     case 5:
6016       emitpcode(POC_MOVLW, popGetLit(0x0f));
6017       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6018       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6019       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6020       emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6021       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6022       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6023       if(shCount >=5) {
6024         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6025         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6026       }
6027       break;
6028     case 6:
6029       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6030       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6031       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6032       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6033       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6034       emitpcode(POC_ANDLW,popGetLit(0xc0));
6035       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6036       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6037       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6038       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6039       break;
6040     case 7:
6041       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6042       emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6043       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6044       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6045       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6046     }
6047
6048   } else {
6049     switch(shCount) {
6050     case 0:
6051       break;
6052     case 1:
6053     case 2:
6054     case 3:
6055       /* note, use a mov/add for the shift since the mov has a
6056          chance of getting optimized out */
6057       emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6058       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6059       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6060       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6061       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6062
6063       while(--shCount) {
6064         emitCLRC;
6065         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6066         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6067       }
6068       break;
6069
6070     case 4:
6071     case 5:
6072       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6073       emitpcode(POC_ANDLW, popGetLit(0xF0));
6074       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6075       emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6076       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6077       emitpcode(POC_ANDLW, popGetLit(0xF0));
6078       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6079       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6080
6081
6082       if(shCount == 5) {
6083         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6084         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6085       }
6086       break;
6087     case 6:
6088       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6089       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6090       emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6091       emitpcode(POC_MOVWF,  popGet(AOP(result),offr,FALSE,FALSE));
6092
6093       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6094       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6095       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6096       emitpcode(POC_ANDLW,popGetLit(0xc0));
6097       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6098       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6099       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6100       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6101       break;
6102     case 7:
6103       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6104       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6105       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6106       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6107       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6108     }
6109   }
6110
6111 }
6112 /*-----------------------------------------------------------------*/
6113 /* shiftR2Left2Result - shift right two bytes from left to result  */
6114 /*-----------------------------------------------------------------*/
6115 static void shiftR2Left2Result (operand *left, int offl,
6116                                 operand *result, int offr,
6117                                 int shCount, int sign)
6118 {
6119   int same=0;
6120
6121   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6122   same = pic14_sameRegs(AOP(result), AOP(left));
6123
6124   if(same && ((offl + MSB16) == offr)){
6125     same=1;
6126     /* don't crash result[offr] */
6127     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6128     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6129   } else {
6130     movLeft2Result(left,offl, result, offr, 0);
6131     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6132   }
6133   /* a:x >> shCount (x = lsb(result))*/
6134   if(sign)
6135     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6136   else {
6137     //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6138     
6139     switch(shCount) {
6140     case 0:
6141       break;
6142     case 1:
6143     case 2:
6144     case 3:
6145       emitCLRC;
6146       if(same) {
6147         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6148         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6149       } else {
6150
6151         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6152         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6153         emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6154         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6155       }
6156
6157       while(--shCount) {
6158         emitCLRC;
6159         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6160         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6161       }
6162       break;
6163     case 4:
6164     case 5:
6165       if(same) {
6166
6167         emitpcode(POC_MOVLW, popGetLit(0xf0));
6168         emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6169         emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6170
6171         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6172         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6173         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6174         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6175       } else {
6176         emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6177         emitpcode(POC_ANDLW, popGetLit(0x0f));
6178         emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6179
6180         emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6181         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6182         emitpcode(POC_ANDLW, popGetLit(0xf0));
6183         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6185       }
6186
6187       if(shCount >=5) {
6188         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6189         emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6190       }
6191
6192       break;
6193
6194     case 6:
6195       if(same) {
6196
6197         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6198         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6199
6200         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6201         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6202         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6203         emitpcode(POC_ANDLW,popGetLit(0x03));
6204         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6205         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6206         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6207         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6208       } else {
6209         emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6210         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6211         emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6212         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6213         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6214         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6215         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6216         emitpcode(POC_ANDLW,popGetLit(0x03));
6217         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6218       }
6219
6220       break;
6221     case 7:
6222       emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6223       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6224       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6225       emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6226       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6227     }
6228   }
6229 }
6230
6231 /*-----------------------------------------------------------------*/
6232 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6233 /*-----------------------------------------------------------------*/
6234 static void shiftLLeftOrResult (operand *left, int offl,
6235                                 operand *result, int offr, int shCount)
6236 {
6237     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6238     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6239     /* shift left accumulator */
6240     AccLsh(shCount);
6241     /* or with result */
6242     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6243     /* back to result */
6244     aopPut(AOP(result),"a",offr);
6245 }
6246
6247 /*-----------------------------------------------------------------*/
6248 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6249 /*-----------------------------------------------------------------*/
6250 static void shiftRLeftOrResult (operand *left, int offl,
6251                                 operand *result, int offr, int shCount)
6252 {
6253     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6254     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6255     /* shift right accumulator */
6256     AccRsh(shCount);
6257     /* or with result */
6258     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6259     /* back to result */
6260     aopPut(AOP(result),"a",offr);
6261 }
6262
6263 /*-----------------------------------------------------------------*/
6264 /* genlshOne - left shift a one byte quantity by known count       */
6265 /*-----------------------------------------------------------------*/
6266 static void genlshOne (operand *result, operand *left, int shCount)
6267 {       
6268     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6269     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6270 }
6271
6272 /*-----------------------------------------------------------------*/
6273 /* genlshTwo - left shift two bytes by known amount != 0           */
6274 /*-----------------------------------------------------------------*/
6275 static void genlshTwo (operand *result,operand *left, int shCount)
6276 {
6277     int size;
6278     
6279     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6280     size = pic14_getDataSize(result);
6281
6282     /* if shCount >= 8 */
6283     if (shCount >= 8) {
6284         shCount -= 8 ;
6285
6286         if (size > 1){
6287             if (shCount)
6288                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6289             else 
6290                 movLeft2Result(left, LSB, result, MSB16, 0);
6291         }
6292         emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6293     }
6294
6295     /*  1 <= shCount <= 7 */
6296     else {  
6297         if(size == 1)
6298             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6299         else 
6300             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6301     }
6302 }
6303
6304 /*-----------------------------------------------------------------*/
6305 /* shiftLLong - shift left one long from left to result            */
6306 /* offl = LSB or MSB16                                             */
6307 /*-----------------------------------------------------------------*/
6308 static void shiftLLong (operand *left, operand *result, int offr )
6309 {
6310     char *l;
6311     int size = AOP_SIZE(result);
6312
6313     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6314     if(size >= LSB+offr){
6315         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6316         MOVA(l);
6317         pic14_emitcode("add","a,acc");
6318         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6319             size >= MSB16+offr && offr != LSB )
6320             pic14_emitcode("xch","a,%s",
6321                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6322         else        
6323             aopPut(AOP(result),"a",LSB+offr);
6324     }
6325
6326     if(size >= MSB16+offr){
6327         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6328             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6329             MOVA(l);
6330         }
6331         pic14_emitcode("rlc","a");
6332         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6333             size >= MSB24+offr && offr != LSB)
6334             pic14_emitcode("xch","a,%s",
6335                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6336         else        
6337             aopPut(AOP(result),"a",MSB16+offr);
6338     }
6339
6340     if(size >= MSB24+offr){
6341         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6342             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6343             MOVA(l);
6344         }
6345         pic14_emitcode("rlc","a");
6346         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6347             size >= MSB32+offr && offr != LSB )
6348             pic14_emitcode("xch","a,%s",
6349                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6350         else        
6351             aopPut(AOP(result),"a",MSB24+offr);
6352     }
6353
6354     if(size > MSB32+offr){
6355         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6356             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6357             MOVA(l);    
6358         }
6359         pic14_emitcode("rlc","a");
6360         aopPut(AOP(result),"a",MSB32+offr);
6361     }
6362     if(offr != LSB)
6363         aopPut(AOP(result),zero,LSB);       
6364 }
6365
6366 /*-----------------------------------------------------------------*/
6367 /* genlshFour - shift four byte by a known amount != 0             */
6368 /*-----------------------------------------------------------------*/
6369 static void genlshFour (operand *result, operand *left, int shCount)
6370 {
6371     int size;
6372
6373     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6374     size = AOP_SIZE(result);
6375
6376     /* if shifting more that 3 bytes */
6377     if (shCount >= 24 ) {
6378         shCount -= 24;
6379         if (shCount)
6380             /* lowest order of left goes to the highest
6381             order of the destination */
6382             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6383         else
6384             movLeft2Result(left, LSB, result, MSB32, 0);
6385         aopPut(AOP(result),zero,LSB);
6386         aopPut(AOP(result),zero,MSB16);
6387         aopPut(AOP(result),zero,MSB32);
6388         return;
6389     }
6390
6391     /* more than two bytes */
6392     else if ( shCount >= 16 ) {
6393         /* lower order two bytes goes to higher order two bytes */
6394         shCount -= 16;
6395         /* if some more remaining */
6396         if (shCount)
6397             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6398         else {
6399             movLeft2Result(left, MSB16, result, MSB32, 0);
6400             movLeft2Result(left, LSB, result, MSB24, 0);
6401         }
6402         aopPut(AOP(result),zero,MSB16);
6403         aopPut(AOP(result),zero,LSB);
6404         return;
6405     }    
6406
6407     /* if more than 1 byte */
6408     else if ( shCount >= 8 ) {
6409         /* lower order three bytes goes to higher order  three bytes */
6410         shCount -= 8;
6411         if(size == 2){
6412             if(shCount)
6413                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6414             else
6415                 movLeft2Result(left, LSB, result, MSB16, 0);
6416         }
6417         else{   /* size = 4 */
6418             if(shCount == 0){
6419                 movLeft2Result(left, MSB24, result, MSB32, 0);
6420                 movLeft2Result(left, MSB16, result, MSB24, 0);
6421                 movLeft2Result(left, LSB, result, MSB16, 0);
6422                 aopPut(AOP(result),zero,LSB);
6423             }
6424             else if(shCount == 1)
6425                 shiftLLong(left, result, MSB16);
6426             else{
6427                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6428                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6429                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6430                 aopPut(AOP(result),zero,LSB);
6431             }
6432         }
6433     }
6434
6435     /* 1 <= shCount <= 7 */
6436     else if(shCount <= 2){
6437         shiftLLong(left, result, LSB);
6438         if(shCount == 2)
6439             shiftLLong(result, result, LSB);
6440     }
6441     /* 3 <= shCount <= 7, optimize */
6442     else{
6443         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6444         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6445         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6446     }
6447 }
6448
6449 /*-----------------------------------------------------------------*/
6450 /* genLeftShiftLiteral - left shifting by known count              */
6451 /*-----------------------------------------------------------------*/
6452 static void genLeftShiftLiteral (operand *left,
6453                                  operand *right,
6454                                  operand *result,
6455                                  iCode *ic)
6456 {    
6457     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6458     int size;
6459
6460     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6461     freeAsmop(right,NULL,ic,TRUE);
6462
6463     aopOp(left,ic,FALSE);
6464     aopOp(result,ic,FALSE);
6465
6466     size = getSize(operandType(result));
6467
6468 #if VIEW_SIZE
6469     pic14_emitcode("; shift left ","result %d, left %d",size,
6470              AOP_SIZE(left));
6471 #endif
6472
6473     /* I suppose that the left size >= result size */
6474     if(shCount == 0){
6475         while(size--){
6476             movLeft2Result(left, size, result, size, 0);
6477         }
6478     }
6479
6480     else if(shCount >= (size * 8))
6481         while(size--)
6482             aopPut(AOP(result),zero,size);
6483     else{
6484         switch (size) {
6485             case 1:
6486                 genlshOne (result,left,shCount);
6487                 break;
6488
6489             case 2:
6490             case 3:
6491                 genlshTwo (result,left,shCount);
6492                 break;
6493
6494             case 4:
6495                 genlshFour (result,left,shCount);
6496                 break;
6497         }
6498     }
6499     freeAsmop(left,NULL,ic,TRUE);
6500     freeAsmop(result,NULL,ic,TRUE);
6501 }
6502
6503 /*-----------------------------------------------------------------*/
6504 /* genLeftShift - generates code for left shifting                 */
6505 /*-----------------------------------------------------------------*/
6506 static void genLeftShift (iCode *ic)
6507 {
6508     operand *left,*right, *result;
6509     int size, offset;
6510     char *l;
6511     symbol *tlbl , *tlbl1;
6512
6513     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6514
6515     right = IC_RIGHT(ic);
6516     left  = IC_LEFT(ic);
6517     result = IC_RESULT(ic);
6518
6519     aopOp(right,ic,FALSE);
6520
6521     /* if the shift count is known then do it 
6522     as efficiently as possible */
6523     if (AOP_TYPE(right) == AOP_LIT) {
6524         genLeftShiftLiteral (left,right,result,ic);
6525         return ;
6526     }
6527
6528     /* shift count is unknown then we have to form 
6529     a loop get the loop count in B : Note: we take
6530     only the lower order byte since shifting
6531     more that 32 bits make no sense anyway, ( the
6532     largest size of an object can be only 32 bits ) */  
6533
6534     
6535     aopOp(left,ic,FALSE);
6536     aopOp(result,ic,FALSE);
6537
6538     /* now move the left to the result if they are not the
6539     same */
6540     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6541         AOP_SIZE(result) > 1) {
6542
6543         size = AOP_SIZE(result);
6544         offset=0;
6545         while (size--) {
6546             l = aopGet(AOP(left),offset,FALSE,TRUE);
6547             if (*l == '@' && (IS_AOP_PREG(result))) {
6548
6549                 pic14_emitcode("mov","a,%s",l);
6550                 aopPut(AOP(result),"a",offset);
6551             } else
6552                 aopPut(AOP(result),l,offset);
6553             offset++;
6554         }
6555     }
6556
6557     size = AOP_SIZE(result);
6558
6559     /* if it is only one byte then */
6560     if (size == 1) {
6561       if(optimized_for_speed) {
6562         emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6563         emitpcode(POC_ANDLW,  popGetLit(0xf0));
6564         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6565         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6566         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6567         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6568         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6569         emitpcode(POC_RLFW,   popGet(AOP(result),0,FALSE,FALSE));
6570         emitpcode(POC_ANDLW,  popGetLit(0xfe));
6571         emitpcode(POC_ADDFW,  popGet(AOP(result),0,FALSE,FALSE));
6572         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6573         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6574       } else {
6575
6576         tlbl = newiTempLabel(NULL);
6577         if (!pic14_sameRegs(AOP(left),AOP(result))) {
6578           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6579           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6580         }
6581
6582         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
6583         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
6584         emitpLabel(tlbl->key);
6585         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
6586         emitpcode(POC_ADDLW,  popGetLit(1));
6587         emitSKPC;
6588         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6589       }
6590       goto release ;
6591     }
6592     
6593
6594     tlbl = newiTempLabel(NULL);
6595     offset = 0 ;   
6596     tlbl1 = newiTempLabel(NULL);
6597
6598     reAdjustPreg(AOP(result));    
6599     
6600     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
6601     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6602     l = aopGet(AOP(result),offset,FALSE,FALSE);
6603     MOVA(l);
6604     pic14_emitcode("add","a,acc");         
6605     aopPut(AOP(result),"a",offset++);
6606     while (--size) {
6607         l = aopGet(AOP(result),offset,FALSE,FALSE);
6608         MOVA(l);
6609         pic14_emitcode("rlc","a");         
6610         aopPut(AOP(result),"a",offset++);
6611     }
6612     reAdjustPreg(AOP(result));
6613
6614     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6615     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6616 release:
6617     freeAsmop (right,NULL,ic,TRUE);
6618     freeAsmop(left,NULL,ic,TRUE);
6619     freeAsmop(result,NULL,ic,TRUE);
6620 }
6621
6622 /*-----------------------------------------------------------------*/
6623 /* genrshOne - right shift a one byte quantity by known count      */
6624 /*-----------------------------------------------------------------*/
6625 static void genrshOne (operand *result, operand *left,
6626                        int shCount, int sign)
6627 {
6628     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6629     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6630 }
6631
6632 /*-----------------------------------------------------------------*/
6633 /* genrshTwo - right shift two bytes by known amount != 0          */
6634 /*-----------------------------------------------------------------*/
6635 static void genrshTwo (operand *result,operand *left,
6636                        int shCount, int sign)
6637 {
6638     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6639     /* if shCount >= 8 */
6640     if (shCount >= 8) {
6641         shCount -= 8 ;
6642         if (shCount)
6643             shiftR1Left2Result(left, MSB16, result, LSB,
6644                                shCount, sign);
6645         else 
6646             movLeft2Result(left, MSB16, result, LSB, sign);
6647         if(sign)
6648           addSign(result, MSB16, sign);
6649         else
6650           emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6651
6652     }
6653
6654     /*  1 <= shCount <= 7 */
6655     else
6656         shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
6657 }
6658
6659 /*-----------------------------------------------------------------*/
6660 /* shiftRLong - shift right one long from left to result           */
6661 /* offl = LSB or MSB16                                             */
6662 /*-----------------------------------------------------------------*/
6663 static void shiftRLong (operand *left, int offl,
6664                         operand *result, int sign)
6665 {
6666     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6667     if(!sign)
6668         pic14_emitcode("clr","c");
6669     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6670     if(sign)
6671         pic14_emitcode("mov","c,acc.7");
6672     pic14_emitcode("rrc","a");
6673     aopPut(AOP(result),"a",MSB32-offl);
6674     if(offl == MSB16)
6675         /* add sign of "a" */
6676         addSign(result, MSB32, sign);
6677
6678     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6679     pic14_emitcode("rrc","a");
6680     aopPut(AOP(result),"a",MSB24-offl);
6681
6682     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6683     pic14_emitcode("rrc","a");
6684     aopPut(AOP(result),"a",MSB16-offl);
6685
6686     if(offl == LSB){
6687         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6688         pic14_emitcode("rrc","a");
6689         aopPut(AOP(result),"a",LSB);
6690     }
6691 }
6692
6693 /*-----------------------------------------------------------------*/
6694 /* genrshFour - shift four byte by a known amount != 0             */
6695 /*-----------------------------------------------------------------*/
6696 static void genrshFour (operand *result, operand *left,
6697                         int shCount, int sign)
6698 {
6699     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6700     /* if shifting more that 3 bytes */
6701     if(shCount >= 24 ) {
6702         shCount -= 24;
6703         if(shCount)
6704             shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6705         else
6706             movLeft2Result(left, MSB32, result, LSB, sign);
6707         addSign(result, MSB16, sign);
6708     }
6709     else if(shCount >= 16){
6710         shCount -= 16;
6711         if(shCount)
6712             shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6713         else{
6714             movLeft2Result(left, MSB24, result, LSB, 0);
6715             movLeft2Result(left, MSB32, result, MSB16, sign);
6716         }
6717         addSign(result, MSB24, sign);
6718     }
6719     else if(shCount >= 8){
6720         shCount -= 8;
6721         if(shCount == 1)
6722             shiftRLong(left, MSB16, result, sign);
6723         else if(shCount == 0){
6724             movLeft2Result(left, MSB16, result, LSB, 0);
6725             movLeft2Result(left, MSB24, result, MSB16, 0);
6726             movLeft2Result(left, MSB32, result, MSB24, sign);
6727             addSign(result, MSB32, sign);
6728         }
6729         else{
6730             shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6731             shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6732             /* the last shift is signed */
6733             shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6734             addSign(result, MSB32, sign);
6735         }
6736     }
6737     else{   /* 1 <= shCount <= 7 */
6738         if(shCount <= 2){
6739             shiftRLong(left, LSB, result, sign);
6740             if(shCount == 2)
6741                 shiftRLong(result, LSB, result, sign);
6742         }
6743         else{
6744             shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6745             shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6746             shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6747         }
6748     }
6749 }
6750
6751 /*-----------------------------------------------------------------*/
6752 /* genRightShiftLiteral - right shifting by known count            */
6753 /*-----------------------------------------------------------------*/
6754 static void genRightShiftLiteral (operand *left,
6755                                   operand *right,
6756                                   operand *result,
6757                                   iCode *ic,
6758                                   int sign)
6759 {    
6760     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6761     int size;
6762
6763     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6764     freeAsmop(right,NULL,ic,TRUE);
6765
6766     aopOp(left,ic,FALSE);
6767     aopOp(result,ic,FALSE);
6768
6769 #if VIEW_SIZE
6770     pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6771              AOP_SIZE(left));
6772 #endif
6773
6774     size = pic14_getDataSize(left);
6775     /* test the LEFT size !!! */
6776
6777     /* I suppose that the left size >= result size */
6778     if(shCount == 0){
6779         size = pic14_getDataSize(result);
6780         while(size--)
6781             movLeft2Result(left, size, result, size, 0);
6782     }
6783
6784     else if(shCount >= (size * 8)){
6785         if(sign)
6786             /* get sign in acc.7 */
6787             MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6788         addSign(result, LSB, sign);
6789     } else{
6790         switch (size) {
6791             case 1:
6792                 genrshOne (result,left,shCount,sign);
6793                 break;
6794
6795             case 2:
6796                 genrshTwo (result,left,shCount,sign);
6797                 break;
6798
6799             case 4:
6800                 genrshFour (result,left,shCount,sign);
6801                 break;
6802             default :
6803                 break;
6804         }
6805
6806         freeAsmop(left,NULL,ic,TRUE);
6807         freeAsmop(result,NULL,ic,TRUE);
6808     }
6809 }
6810
6811 /*-----------------------------------------------------------------*/
6812 /* genSignedRightShift - right shift of signed number              */
6813 /*-----------------------------------------------------------------*/
6814 static void genSignedRightShift (iCode *ic)
6815 {
6816     operand *right, *left, *result;
6817     int size, offset;
6818     char *l;
6819     symbol *tlbl, *tlbl1 ;
6820
6821     /* we do it the hard way put the shift count in b
6822     and loop thru preserving the sign */
6823     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6824
6825     right = IC_RIGHT(ic);
6826     left  = IC_LEFT(ic);
6827     result = IC_RESULT(ic);
6828
6829     aopOp(right,ic,FALSE);  
6830
6831
6832     if ( AOP_TYPE(right) == AOP_LIT) {
6833         genRightShiftLiteral (left,right,result,ic,1);
6834         return ;
6835     }
6836         /* shift count is unknown then we have to form 
6837        a loop get the loop count in B : Note: we take
6838        only the lower order byte since shifting
6839        more that 32 bits make no sense anyway, ( the
6840        largest size of an object can be only 32 bits ) */  
6841
6842     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6843     pic14_emitcode("inc","b");
6844     freeAsmop (right,NULL,ic,TRUE);
6845     aopOp(left,ic,FALSE);
6846     aopOp(result,ic,FALSE);
6847
6848     /* now move the left to the result if they are not the
6849     same */
6850     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6851         AOP_SIZE(result) > 1) {
6852
6853         size = AOP_SIZE(result);
6854         offset=0;
6855         while (size--) {
6856             l = aopGet(AOP(left),offset,FALSE,TRUE);
6857             if (*l == '@' && IS_AOP_PREG(result)) {
6858
6859                 pic14_emitcode("mov","a,%s",l);
6860                 aopPut(AOP(result),"a",offset);
6861             } else
6862                 aopPut(AOP(result),l,offset);
6863             offset++;
6864         }
6865     }
6866
6867     /* mov the highest order bit to OVR */    
6868     tlbl = newiTempLabel(NULL);
6869     tlbl1= newiTempLabel(NULL);
6870
6871     size = AOP_SIZE(result);
6872     offset = size - 1;
6873     pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6874     pic14_emitcode("rlc","a");
6875     pic14_emitcode("mov","ov,c");
6876     /* if it is only one byte then */
6877     if (size == 1) {
6878         l = aopGet(AOP(left),0,FALSE,FALSE);
6879         MOVA(l);
6880         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6881         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6882         pic14_emitcode("mov","c,ov");
6883         pic14_emitcode("rrc","a");
6884         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6885         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6886         aopPut(AOP(result),"a",0);
6887         goto release ;
6888     }
6889
6890     reAdjustPreg(AOP(result));
6891     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6892     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6893     pic14_emitcode("mov","c,ov");
6894     while (size--) {
6895         l = aopGet(AOP(result),offset,FALSE,FALSE);
6896         MOVA(l);
6897         pic14_emitcode("rrc","a");         
6898         aopPut(AOP(result),"a",offset--);
6899     }
6900     reAdjustPreg(AOP(result));
6901     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6902     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6903
6904 release:
6905     freeAsmop(left,NULL,ic,TRUE);
6906     freeAsmop(result,NULL,ic,TRUE);
6907 }
6908
6909 /*-----------------------------------------------------------------*/
6910 /* genRightShift - generate code for right shifting                */
6911 /*-----------------------------------------------------------------*/
6912 static void genRightShift (iCode *ic)
6913 {
6914     operand *right, *left, *result;
6915     sym_link *retype ;
6916     int size, offset;
6917     char *l;
6918     symbol *tlbl, *tlbl1 ;
6919
6920     /* if signed then we do it the hard way preserve the
6921     sign bit moving it inwards */
6922     retype = getSpec(operandType(IC_RESULT(ic)));
6923     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6924
6925     if (!SPEC_USIGN(retype)) {
6926         genSignedRightShift (ic);
6927         return ;
6928     }
6929
6930     /* signed & unsigned types are treated the same : i.e. the
6931     signed is NOT propagated inwards : quoting from the
6932     ANSI - standard : "for E1 >> E2, is equivalent to division
6933     by 2**E2 if unsigned or if it has a non-negative value,
6934     otherwise the result is implementation defined ", MY definition
6935     is that the sign does not get propagated */
6936
6937     right = IC_RIGHT(ic);
6938     left  = IC_LEFT(ic);
6939     result = IC_RESULT(ic);
6940
6941     aopOp(right,ic,FALSE);
6942
6943     /* if the shift count is known then do it 
6944     as efficiently as possible */
6945     if (AOP_TYPE(right) == AOP_LIT) {
6946         genRightShiftLiteral (left,right,result,ic, 0);
6947         return ;
6948     }
6949
6950     /* shift count is unknown then we have to form 
6951     a loop get the loop count in B : Note: we take
6952     only the lower order byte since shifting
6953     more that 32 bits make no sense anyway, ( the
6954     largest size of an object can be only 32 bits ) */  
6955
6956     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6957     pic14_emitcode("inc","b");
6958     aopOp(left,ic,FALSE);
6959     aopOp(result,ic,FALSE);
6960
6961     /* now move the left to the result if they are not the
6962     same */
6963     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6964         AOP_SIZE(result) > 1) {
6965
6966         size = AOP_SIZE(result);
6967         offset=0;
6968         while (size--) {
6969             l = aopGet(AOP(left),offset,FALSE,TRUE);
6970             if (*l == '@' && IS_AOP_PREG(result)) {
6971
6972                 pic14_emitcode("mov","a,%s",l);
6973                 aopPut(AOP(result),"a",offset);
6974             } else
6975                 aopPut(AOP(result),l,offset);
6976             offset++;
6977         }
6978     }
6979
6980     tlbl = newiTempLabel(NULL);
6981     tlbl1= newiTempLabel(NULL);
6982     size = AOP_SIZE(result);
6983     offset = size - 1;
6984
6985     /* if it is only one byte then */
6986     if (size == 1) {
6987 /*
6988         l = aopGet(AOP(left),0,FALSE,FALSE);
6989         MOVA(l);
6990         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6991         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6992         CLRC;
6993         pic14_emitcode("rrc","a");
6994         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6995         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6996         aopPut(AOP(result),"a",0);
6997 */
6998         tlbl = newiTempLabel(NULL);
6999         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7000           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
7001           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
7002         }
7003
7004         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
7005         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
7006         emitpLabel(tlbl->key);
7007         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
7008         emitpcode(POC_ADDLW,  popGetLit(1));
7009         emitSKPC;
7010         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7011
7012         goto release ;
7013     }
7014
7015     reAdjustPreg(AOP(result));
7016     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7017     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7018     CLRC;
7019     while (size--) {
7020         l = aopGet(AOP(result),offset,FALSE,FALSE);
7021         MOVA(l);
7022         pic14_emitcode("rrc","a");         
7023         aopPut(AOP(result),"a",offset--);
7024     }
7025     reAdjustPreg(AOP(result));
7026
7027     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7028     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7029
7030 release:
7031     freeAsmop(left,NULL,ic,TRUE);
7032     freeAsmop (right,NULL,ic,TRUE);
7033     freeAsmop(result,NULL,ic,TRUE);
7034 }
7035
7036 /*-----------------------------------------------------------------*/
7037 /* genUnpackBits - generates code for unpacking bits               */
7038 /*-----------------------------------------------------------------*/
7039 static void genUnpackBits (operand *result, char *rname, int ptype)
7040 {    
7041     int shCnt ;
7042     int rlen = 0 ;
7043     sym_link *etype;
7044     int offset = 0 ;
7045
7046     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7047     etype = getSpec(operandType(result));
7048
7049     /* read the first byte  */
7050     switch (ptype) {
7051
7052     case POINTER:
7053     case IPOINTER:
7054         pic14_emitcode("mov","a,@%s",rname);
7055         break;
7056         
7057     case PPOINTER:
7058         pic14_emitcode("movx","a,@%s",rname);
7059         break;
7060         
7061     case FPOINTER:
7062         pic14_emitcode("movx","a,@dptr");
7063         break;
7064
7065     case CPOINTER:
7066         pic14_emitcode("clr","a");
7067         pic14_emitcode("movc","a","@a+dptr");
7068         break;
7069
7070     case GPOINTER:
7071         pic14_emitcode("lcall","__gptrget");
7072         break;
7073     }
7074
7075     /* if we have bitdisplacement then it fits   */
7076     /* into this byte completely or if length is */
7077     /* less than a byte                          */
7078     if ((shCnt = SPEC_BSTR(etype)) || 
7079         (SPEC_BLEN(etype) <= 8))  {
7080
7081         /* shift right acc */
7082         AccRsh(shCnt);
7083
7084         pic14_emitcode("anl","a,#0x%02x",
7085                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7086         aopPut(AOP(result),"a",offset);
7087         return ;
7088     }
7089
7090     /* bit field did not fit in a byte  */
7091     rlen = SPEC_BLEN(etype) - 8;
7092     aopPut(AOP(result),"a",offset++);
7093
7094     while (1)  {
7095
7096         switch (ptype) {
7097         case POINTER:
7098         case IPOINTER:
7099             pic14_emitcode("inc","%s",rname);
7100             pic14_emitcode("mov","a,@%s",rname);
7101             break;
7102             
7103         case PPOINTER:
7104             pic14_emitcode("inc","%s",rname);
7105             pic14_emitcode("movx","a,@%s",rname);
7106             break;
7107
7108         case FPOINTER:
7109             pic14_emitcode("inc","dptr");
7110             pic14_emitcode("movx","a,@dptr");
7111             break;
7112             
7113         case CPOINTER:
7114             pic14_emitcode("clr","a");
7115             pic14_emitcode("inc","dptr");
7116             pic14_emitcode("movc","a","@a+dptr");
7117             break;
7118             
7119         case GPOINTER:
7120             pic14_emitcode("inc","dptr");
7121             pic14_emitcode("lcall","__gptrget");
7122             break;
7123         }
7124
7125         rlen -= 8;            
7126         /* if we are done */
7127         if ( rlen <= 0 )
7128             break ;
7129         
7130         aopPut(AOP(result),"a",offset++);
7131                               
7132     }
7133     
7134     if (rlen) {
7135         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7136         aopPut(AOP(result),"a",offset);        
7137     }
7138     
7139     return ;
7140 }
7141
7142
7143 /*-----------------------------------------------------------------*/
7144 /* genDataPointerGet - generates code when ptr offset is known     */
7145 /*-----------------------------------------------------------------*/
7146 static void genDataPointerGet (operand *left, 
7147                                operand *result, 
7148                                iCode *ic)
7149 {
7150   int size , offset = 0;
7151
7152
7153   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7154
7155
7156   /* optimization - most of the time, left and result are the same
7157    * address, but different types. for the pic code, we could omit
7158    * the following
7159    */
7160
7161   aopOp(result,ic,TRUE);
7162
7163   emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7164
7165   size = AOP_SIZE(result);
7166
7167   while (size--) {
7168     emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7169     offset++;
7170   }
7171
7172   freeAsmop(left,NULL,ic,TRUE);
7173   freeAsmop(result,NULL,ic,TRUE);
7174 }
7175
7176 /*-----------------------------------------------------------------*/
7177 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7178 /*-----------------------------------------------------------------*/
7179 static void genNearPointerGet (operand *left, 
7180                                operand *result, 
7181                                iCode *ic)
7182 {
7183     asmop *aop = NULL;
7184     regs *preg = NULL ;
7185     char *rname ;
7186     sym_link *rtype, *retype;
7187     sym_link *ltype = operandType(left);    
7188     char buffer[80];
7189
7190     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7191
7192     rtype = operandType(result);
7193     retype= getSpec(rtype);
7194     
7195     aopOp(left,ic,FALSE);
7196     
7197     /* if left is rematerialisable and
7198        result is not bit variable type and
7199        the left is pointer to data space i.e
7200        lower 128 bytes of space */
7201     if (AOP_TYPE(left) == AOP_IMMD &&
7202         !IS_BITVAR(retype)         &&
7203         DCL_TYPE(ltype) == POINTER) {
7204         genDataPointerGet (left,result,ic);
7205         return ;
7206     }
7207     
7208     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7209
7210         /* if the value is already in a pointer register
7211        then don't need anything more */
7212     if (!AOP_INPREG(AOP(left))) {
7213         /* otherwise get a free pointer register */
7214     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7215         aop = newAsmop(0);
7216         preg = getFreePtr(ic,&aop,FALSE);
7217         pic14_emitcode("mov","%s,%s",
7218                 preg->name,
7219                 aopGet(AOP(left),0,FALSE,TRUE));
7220         rname = preg->name ;
7221     } else
7222         rname = aopGet(AOP(left),0,FALSE,FALSE);
7223     
7224     freeAsmop(left,NULL,ic,TRUE);
7225     aopOp (result,ic,FALSE);
7226     
7227       /* if bitfield then unpack the bits */
7228     if (IS_BITVAR(retype)) 
7229         genUnpackBits (result,rname,POINTER);
7230     else {
7231         /* we have can just get the values */
7232         int size = AOP_SIZE(result);
7233         int offset = 0 ;        
7234         
7235     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7236         while (size--) {
7237             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7238
7239                 pic14_emitcode("mov","a,@%s",rname);
7240                 aopPut(AOP(result),"a",offset);
7241             } else {
7242                 sprintf(buffer,"@%s",rname);
7243                 aopPut(AOP(result),buffer,offset);
7244             }
7245             offset++ ;
7246             if (size)
7247                 pic14_emitcode("inc","%s",rname);
7248         }
7249     }
7250
7251     /* now some housekeeping stuff */
7252     if (aop) {
7253         /* we had to allocate for this iCode */
7254     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7255         freeAsmop(NULL,aop,ic,TRUE);
7256     } else { 
7257         /* we did not allocate which means left
7258            already in a pointer register, then
7259            if size > 0 && this could be used again
7260            we have to point it back to where it 
7261            belongs */
7262     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7263         if (AOP_SIZE(result) > 1 &&
7264             !OP_SYMBOL(left)->remat &&
7265             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7266               ic->depth )) {
7267             int size = AOP_SIZE(result) - 1;
7268             while (size--)
7269                 pic14_emitcode("dec","%s",rname);
7270         }
7271     }
7272
7273     /* done */
7274     freeAsmop(result,NULL,ic,TRUE);
7275      
7276 }
7277
7278 /*-----------------------------------------------------------------*/
7279 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7280 /*-----------------------------------------------------------------*/
7281 static void genPagedPointerGet (operand *left, 
7282                                operand *result, 
7283                                iCode *ic)
7284 {
7285     asmop *aop = NULL;
7286     regs *preg = NULL ;
7287     char *rname ;
7288     sym_link *rtype, *retype;    
7289
7290     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7291
7292     rtype = operandType(result);
7293     retype= getSpec(rtype);
7294     
7295     aopOp(left,ic,FALSE);
7296
7297   /* if the value is already in a pointer register
7298        then don't need anything more */
7299     if (!AOP_INPREG(AOP(left))) {
7300         /* otherwise get a free pointer register */
7301         aop = newAsmop(0);
7302         preg = getFreePtr(ic,&aop,FALSE);
7303         pic14_emitcode("mov","%s,%s",
7304                 preg->name,
7305                 aopGet(AOP(left),0,FALSE,TRUE));
7306         rname = preg->name ;
7307     } else
7308         rname = aopGet(AOP(left),0,FALSE,FALSE);
7309     
7310     freeAsmop(left,NULL,ic,TRUE);
7311     aopOp (result,ic,FALSE);
7312
7313     /* if bitfield then unpack the bits */
7314     if (IS_BITVAR(retype)) 
7315         genUnpackBits (result,rname,PPOINTER);
7316     else {
7317         /* we have can just get the values */
7318         int size = AOP_SIZE(result);
7319         int offset = 0 ;        
7320         
7321         while (size--) {
7322             
7323             pic14_emitcode("movx","a,@%s",rname);
7324             aopPut(AOP(result),"a",offset);
7325             
7326             offset++ ;
7327             
7328             if (size)
7329                 pic14_emitcode("inc","%s",rname);
7330         }
7331     }
7332
7333     /* now some housekeeping stuff */
7334     if (aop) {
7335         /* we had to allocate for this iCode */
7336         freeAsmop(NULL,aop,ic,TRUE);
7337     } else { 
7338         /* we did not allocate which means left
7339            already in a pointer register, then
7340            if size > 0 && this could be used again
7341            we have to point it back to where it 
7342            belongs */
7343         if (AOP_SIZE(result) > 1 &&
7344             !OP_SYMBOL(left)->remat &&
7345             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7346               ic->depth )) {
7347             int size = AOP_SIZE(result) - 1;
7348             while (size--)
7349                 pic14_emitcode("dec","%s",rname);
7350         }
7351     }
7352
7353     /* done */
7354     freeAsmop(result,NULL,ic,TRUE);
7355     
7356         
7357 }
7358
7359 /*-----------------------------------------------------------------*/
7360 /* genFarPointerGet - gget value from far space                    */
7361 /*-----------------------------------------------------------------*/
7362 static void genFarPointerGet (operand *left,
7363                               operand *result, iCode *ic)
7364 {
7365     int size, offset ;
7366     sym_link *retype = getSpec(operandType(result));
7367
7368     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7369
7370     aopOp(left,ic,FALSE);
7371
7372     /* if the operand is already in dptr 
7373     then we do nothing else we move the value to dptr */
7374     if (AOP_TYPE(left) != AOP_STR) {
7375         /* if this is remateriazable */
7376         if (AOP_TYPE(left) == AOP_IMMD)
7377             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7378         else { /* we need to get it byte by byte */
7379             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7380             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7381             if (options.model == MODEL_FLAT24)
7382             {
7383                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7384             }
7385         }
7386     }
7387     /* so dptr know contains the address */
7388     freeAsmop(left,NULL,ic,TRUE);
7389     aopOp(result,ic,FALSE);
7390
7391     /* if bit then unpack */
7392     if (IS_BITVAR(retype)) 
7393         genUnpackBits(result,"dptr",FPOINTER);
7394     else {
7395         size = AOP_SIZE(result);
7396         offset = 0 ;
7397
7398         while (size--) {
7399             pic14_emitcode("movx","a,@dptr");
7400             aopPut(AOP(result),"a",offset++);
7401             if (size)
7402                 pic14_emitcode("inc","dptr");
7403         }
7404     }
7405
7406     freeAsmop(result,NULL,ic,TRUE);
7407 }
7408
7409 /*-----------------------------------------------------------------*/
7410 /* pic14_emitcodePointerGet - gget value from code space                  */
7411 /*-----------------------------------------------------------------*/
7412 static void pic14_emitcodePointerGet (operand *left,
7413                                 operand *result, iCode *ic)
7414 {
7415     int size, offset ;
7416     sym_link *retype = getSpec(operandType(result));
7417
7418     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7419
7420     aopOp(left,ic,FALSE);
7421
7422     /* if the operand is already in dptr 
7423     then we do nothing else we move the value to dptr */
7424     if (AOP_TYPE(left) != AOP_STR) {
7425         /* if this is remateriazable */
7426         if (AOP_TYPE(left) == AOP_IMMD)
7427             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7428         else { /* we need to get it byte by byte */
7429             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7430             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7431             if (options.model == MODEL_FLAT24)
7432             {
7433                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7434             }
7435         }
7436     }
7437     /* so dptr know contains the address */
7438     freeAsmop(left,NULL,ic,TRUE);
7439     aopOp(result,ic,FALSE);
7440
7441     /* if bit then unpack */
7442     if (IS_BITVAR(retype)) 
7443         genUnpackBits(result,"dptr",CPOINTER);
7444     else {
7445         size = AOP_SIZE(result);
7446         offset = 0 ;
7447
7448         while (size--) {
7449             pic14_emitcode("clr","a");
7450             pic14_emitcode("movc","a,@a+dptr");
7451             aopPut(AOP(result),"a",offset++);
7452             if (size)
7453                 pic14_emitcode("inc","dptr");
7454         }
7455     }
7456
7457     freeAsmop(result,NULL,ic,TRUE);
7458 }
7459
7460 /*-----------------------------------------------------------------*/
7461 /* genGenPointerGet - gget value from generic pointer space        */
7462 /*-----------------------------------------------------------------*/
7463 static void genGenPointerGet (operand *left,
7464                               operand *result, iCode *ic)
7465 {
7466   int size, offset ;
7467   sym_link *retype = getSpec(operandType(result));
7468
7469   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7470   aopOp(left,ic,FALSE);
7471   aopOp(result,ic,FALSE);
7472
7473
7474   DEBUGpic14_emitcode ("; ","result %s, left %s",
7475                          AopType(AOP_TYPE(result)),
7476                          AopType(AOP_TYPE(left)));
7477
7478   /* if the operand is already in dptr 
7479      then we do nothing else we move the value to dptr */
7480   if (AOP_TYPE(left) != AOP_STR) {
7481     /* if this is remateriazable */
7482     if (AOP_TYPE(left) == AOP_IMMD) {
7483       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7484       pic14_emitcode("mov","b,#%d",pointerCode(retype));
7485     }
7486     else { /* we need to get it byte by byte */
7487
7488       size = AOP_SIZE(result);
7489       offset = 0 ;
7490
7491       while(size--) {
7492         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7493         emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7494         if(size)
7495           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7496       }
7497       goto release;
7498     }
7499   }
7500   /* so dptr know contains the address */
7501
7502   /* if bit then unpack */
7503   if (IS_BITVAR(retype)) 
7504     genUnpackBits(result,"dptr",GPOINTER);
7505
7506  release:
7507   freeAsmop(left,NULL,ic,TRUE);
7508   freeAsmop(result,NULL,ic,TRUE);
7509
7510 }
7511
7512 /*-----------------------------------------------------------------*/
7513 /* genPointerGet - generate code for pointer get                   */
7514 /*-----------------------------------------------------------------*/
7515 static void genPointerGet (iCode *ic)
7516 {
7517     operand *left, *result ;
7518     sym_link *type, *etype;
7519     int p_type;
7520
7521     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7522
7523     left = IC_LEFT(ic);
7524     result = IC_RESULT(ic) ;
7525
7526     /* depending on the type of pointer we need to
7527     move it to the correct pointer register */
7528     type = operandType(left);
7529     etype = getSpec(type);
7530     /* if left is of type of pointer then it is simple */
7531     if (IS_PTR(type) && !IS_FUNC(type->next)) 
7532         p_type = DCL_TYPE(type);
7533     else {
7534         /* we have to go by the storage class */
7535         p_type = PTR_TYPE(SPEC_OCLS(etype));
7536
7537 /*      if (SPEC_OCLS(etype)->codesp ) { */
7538 /*          p_type = CPOINTER ;  */
7539 /*      } */
7540 /*      else */
7541 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7542 /*              p_type = FPOINTER ; */
7543 /*          else */
7544 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7545 /*                  p_type = PPOINTER; */
7546 /*              else */
7547 /*                  if (SPEC_OCLS(etype) == idata ) */
7548 /*                      p_type = IPOINTER; */
7549 /*                  else */
7550 /*                      p_type = POINTER ; */
7551     }
7552
7553     /* now that we have the pointer type we assign
7554     the pointer values */
7555     switch (p_type) {
7556
7557     case POINTER:       
7558     case IPOINTER:
7559         genNearPointerGet (left,result,ic);
7560         break;
7561
7562     case PPOINTER:
7563         genPagedPointerGet(left,result,ic);
7564         break;
7565
7566     case FPOINTER:
7567         genFarPointerGet (left,result,ic);
7568         break;
7569
7570     case CPOINTER:
7571         pic14_emitcodePointerGet (left,result,ic);
7572         break;
7573
7574     case GPOINTER:
7575         genGenPointerGet (left,result,ic);
7576         break;
7577     }
7578
7579 }
7580
7581 /*-----------------------------------------------------------------*/
7582 /* genPackBits - generates code for packed bit storage             */
7583 /*-----------------------------------------------------------------*/
7584 static void genPackBits (sym_link    *etype ,
7585                          operand *right ,
7586                          char *rname, int p_type)
7587 {
7588     int shCount = 0 ;
7589     int offset = 0  ;
7590     int rLen = 0 ;
7591     int blen, bstr ;   
7592     char *l ;
7593
7594     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7595     blen = SPEC_BLEN(etype);
7596     bstr = SPEC_BSTR(etype);
7597
7598     l = aopGet(AOP(right),offset++,FALSE,FALSE);
7599     MOVA(l);   
7600
7601     /* if the bit lenth is less than or    */
7602     /* it exactly fits a byte then         */
7603     if (SPEC_BLEN(etype) <= 8 )  {
7604         shCount = SPEC_BSTR(etype) ;
7605
7606         /* shift left acc */
7607         AccLsh(shCount);
7608
7609         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7610
7611
7612             switch (p_type) {
7613                 case POINTER:
7614                     pic14_emitcode ("mov","b,a");
7615                     pic14_emitcode("mov","a,@%s",rname);
7616                     break;
7617
7618                 case FPOINTER:
7619                     pic14_emitcode ("mov","b,a");
7620                     pic14_emitcode("movx","a,@dptr");
7621                     break;
7622
7623                 case GPOINTER:
7624                     pic14_emitcode ("push","b");
7625                     pic14_emitcode ("push","acc");
7626                     pic14_emitcode ("lcall","__gptrget");
7627                     pic14_emitcode ("pop","b");
7628                     break;
7629             }
7630
7631             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7632                       ((unsigned char)(0xFF << (blen+bstr)) | 
7633                        (unsigned char)(0xFF >> (8-bstr)) ) );
7634             pic14_emitcode ("orl","a,b");
7635             if (p_type == GPOINTER)
7636                 pic14_emitcode("pop","b");
7637         }
7638     }
7639
7640     switch (p_type) {
7641         case POINTER:
7642             pic14_emitcode("mov","@%s,a",rname);
7643             break;
7644
7645         case FPOINTER:
7646             pic14_emitcode("movx","@dptr,a");
7647             break;
7648
7649         case GPOINTER:
7650             DEBUGpic14_emitcode(";lcall","__gptrput");
7651             break;
7652     }
7653
7654     /* if we r done */
7655     if ( SPEC_BLEN(etype) <= 8 )
7656         return ;
7657
7658     pic14_emitcode("inc","%s",rname);
7659     rLen = SPEC_BLEN(etype) ;     
7660
7661     /* now generate for lengths greater than one byte */
7662     while (1) {
7663
7664         l = aopGet(AOP(right),offset++,FALSE,TRUE);
7665
7666         rLen -= 8 ;
7667         if (rLen <= 0 )
7668             break ;
7669
7670         switch (p_type) {
7671             case POINTER:
7672                 if (*l == '@') {
7673                     MOVA(l);
7674                     pic14_emitcode("mov","@%s,a",rname);
7675                 } else
7676                     pic14_emitcode("mov","@%s,%s",rname,l);
7677                 break;
7678
7679             case FPOINTER:
7680                 MOVA(l);
7681                 pic14_emitcode("movx","@dptr,a");
7682                 break;
7683
7684             case GPOINTER:
7685                 MOVA(l);
7686                 DEBUGpic14_emitcode(";lcall","__gptrput");
7687                 break;  
7688         }   
7689         pic14_emitcode ("inc","%s",rname);
7690     }
7691
7692     MOVA(l);
7693
7694     /* last last was not complete */
7695     if (rLen)   {
7696         /* save the byte & read byte */
7697         switch (p_type) {
7698             case POINTER:
7699                 pic14_emitcode ("mov","b,a");
7700                 pic14_emitcode("mov","a,@%s",rname);
7701                 break;
7702
7703             case FPOINTER:
7704                 pic14_emitcode ("mov","b,a");
7705                 pic14_emitcode("movx","a,@dptr");
7706                 break;
7707
7708             case GPOINTER:
7709                 pic14_emitcode ("push","b");
7710                 pic14_emitcode ("push","acc");
7711                 pic14_emitcode ("lcall","__gptrget");
7712                 pic14_emitcode ("pop","b");
7713                 break;
7714         }
7715
7716         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7717         pic14_emitcode ("orl","a,b");
7718     }
7719
7720     if (p_type == GPOINTER)
7721         pic14_emitcode("pop","b");
7722
7723     switch (p_type) {
7724
7725     case POINTER:
7726         pic14_emitcode("mov","@%s,a",rname);
7727         break;
7728         
7729     case FPOINTER:
7730         pic14_emitcode("movx","@dptr,a");
7731         break;
7732         
7733     case GPOINTER:
7734         DEBUGpic14_emitcode(";lcall","__gptrput");
7735         break;                  
7736     }
7737 }
7738 /*-----------------------------------------------------------------*/
7739 /* genDataPointerSet - remat pointer to data space                 */
7740 /*-----------------------------------------------------------------*/
7741 static void genDataPointerSet(operand *right,
7742                               operand *result,
7743                               iCode *ic)
7744 {
7745     int size, offset = 0 ;
7746     char *l, buffer[256];
7747
7748     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7749     aopOp(right,ic,FALSE);
7750     
7751     l = aopGet(AOP(result),0,FALSE,TRUE);
7752     size = AOP_SIZE(right);
7753     // tsd, was l+1 - the underline `_' prefix was being stripped
7754     while (size--) {
7755         if (offset)
7756             sprintf(buffer,"(%s + %d)",l,offset);
7757         else
7758             sprintf(buffer,"%s",l);
7759
7760         if (AOP_TYPE(right) == AOP_LIT) {
7761           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7762           lit = lit >> (8*offset);
7763           if(lit&0xff) {
7764             pic14_emitcode("movlw","%d",lit);
7765             pic14_emitcode("movwf","%s",buffer);
7766
7767             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7768             emitpcode(POC_MOVWF, popRegFromString(buffer));
7769
7770           } else {
7771             pic14_emitcode("clrf","%s",buffer);
7772             emitpcode(POC_CLRF, popRegFromString(buffer));
7773           }
7774         }else {
7775           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7776           pic14_emitcode("movwf","%s",buffer);
7777
7778           emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7779           emitpcode(POC_MOVWF, popRegFromString(buffer));
7780
7781         }
7782
7783         offset++;
7784     }
7785
7786     freeAsmop(right,NULL,ic,TRUE);
7787     freeAsmop(result,NULL,ic,TRUE);
7788 }
7789
7790 /*-----------------------------------------------------------------*/
7791 /* genNearPointerSet - pic14_emitcode for near pointer put                */
7792 /*-----------------------------------------------------------------*/
7793 static void genNearPointerSet (operand *right,
7794                                operand *result, 
7795                                iCode *ic)
7796 {
7797     asmop *aop = NULL;
7798     char *l;
7799     sym_link *retype;
7800     sym_link *ptype = operandType(result);
7801
7802     
7803     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7804     retype= getSpec(operandType(right));
7805
7806     aopOp(result,ic,FALSE);
7807     
7808     /* if the result is rematerializable &
7809        in data space & not a bit variable */
7810     if (AOP_TYPE(result) == AOP_IMMD &&
7811         DCL_TYPE(ptype) == POINTER   &&
7812         !IS_BITVAR(retype)) {
7813         genDataPointerSet (right,result,ic);
7814         return;
7815     }
7816
7817     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7818
7819     /* if the value is already in a pointer register
7820     then don't need anything more */
7821     if (!AOP_INPREG(AOP(result))) {
7822         /* otherwise get a free pointer register */
7823         //aop = newAsmop(0);
7824         //preg = getFreePtr(ic,&aop,FALSE);
7825         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7826         //pic14_emitcode("mov","%s,%s",
7827         //         preg->name,
7828         //         aopGet(AOP(result),0,FALSE,TRUE));
7829         //rname = preg->name ;
7830         pic14_emitcode("movwf","fsr");
7831     }// else
7832     //   rname = aopGet(AOP(result),0,FALSE,FALSE);
7833
7834     freeAsmop(result,NULL,ic,TRUE);
7835     aopOp (right,ic,FALSE);
7836     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7837
7838     /* if bitfield then unpack the bits */
7839     if (IS_BITVAR(retype)) {
7840       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7841              "The programmer is obviously confused");
7842       //genPackBits (retype,right,rname,POINTER);
7843       exit(1);
7844     }
7845     else {
7846         /* we have can just get the values */
7847         int size = AOP_SIZE(right);
7848         int offset = 0 ;    
7849
7850     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7851         while (size--) {
7852             l = aopGet(AOP(right),offset,FALSE,TRUE);
7853             if (*l == '@' ) {
7854               //MOVA(l);
7855               //pic14_emitcode("mov","@%s,a",rname);
7856               pic14_emitcode("movf","indf,w ;1");
7857             } else {
7858
7859               if (AOP_TYPE(right) == AOP_LIT) {
7860                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7861                 if(lit) {
7862                   pic14_emitcode("movlw","%s",l);
7863                   pic14_emitcode("movwf","indf ;2");
7864                 } else 
7865                   pic14_emitcode("clrf","indf");
7866               }else {
7867                 pic14_emitcode("movf","%s,w",l);
7868                 pic14_emitcode("movwf","indf ;2");
7869               }
7870             //pic14_emitcode("mov","@%s,%s",rname,l);
7871             }
7872             if (size)
7873               pic14_emitcode("incf","fsr,f ;3");
7874             //pic14_emitcode("inc","%s",rname);
7875             offset++;
7876         }
7877     }
7878
7879     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7880     /* now some housekeeping stuff */
7881     if (aop) {
7882         /* we had to allocate for this iCode */
7883         freeAsmop(NULL,aop,ic,TRUE);
7884     } else { 
7885         /* we did not allocate which means left
7886         already in a pointer register, then
7887         if size > 0 && this could be used again
7888         we have to point it back to where it 
7889         belongs */
7890     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7891         if (AOP_SIZE(right) > 1 &&
7892             !OP_SYMBOL(result)->remat &&
7893             ( OP_SYMBOL(result)->liveTo > ic->seq ||
7894               ic->depth )) {
7895             int size = AOP_SIZE(right) - 1;
7896             while (size--)
7897               pic14_emitcode("decf","fsr,f");
7898               //pic14_emitcode("dec","%s",rname);
7899         }
7900     }
7901
7902     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7903     /* done */
7904     freeAsmop(right,NULL,ic,TRUE);
7905
7906
7907 }
7908
7909 /*-----------------------------------------------------------------*/
7910 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
7911 /*-----------------------------------------------------------------*/
7912 static void genPagedPointerSet (operand *right,
7913                                operand *result, 
7914                                iCode *ic)
7915 {
7916     asmop *aop = NULL;
7917     regs *preg = NULL ;
7918     char *rname , *l;
7919     sym_link *retype;
7920        
7921     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7922
7923     retype= getSpec(operandType(right));
7924     
7925     aopOp(result,ic,FALSE);
7926     
7927     /* if the value is already in a pointer register
7928        then don't need anything more */
7929     if (!AOP_INPREG(AOP(result))) {
7930         /* otherwise get a free pointer register */
7931         aop = newAsmop(0);
7932         preg = getFreePtr(ic,&aop,FALSE);
7933         pic14_emitcode("mov","%s,%s",
7934                 preg->name,
7935                 aopGet(AOP(result),0,FALSE,TRUE));
7936         rname = preg->name ;
7937     } else
7938         rname = aopGet(AOP(result),0,FALSE,FALSE);
7939     
7940     freeAsmop(result,NULL,ic,TRUE);
7941     aopOp (right,ic,FALSE);
7942
7943     /* if bitfield then unpack the bits */
7944     if (IS_BITVAR(retype)) 
7945         genPackBits (retype,right,rname,PPOINTER);
7946     else {
7947         /* we have can just get the values */
7948         int size = AOP_SIZE(right);
7949         int offset = 0 ;        
7950         
7951         while (size--) {
7952             l = aopGet(AOP(right),offset,FALSE,TRUE);
7953             
7954             MOVA(l);
7955             pic14_emitcode("movx","@%s,a",rname);
7956
7957             if (size)
7958                 pic14_emitcode("inc","%s",rname);
7959
7960             offset++;
7961         }
7962     }
7963     
7964     /* now some housekeeping stuff */
7965     if (aop) {
7966         /* we had to allocate for this iCode */
7967         freeAsmop(NULL,aop,ic,TRUE);
7968     } else { 
7969         /* we did not allocate which means left
7970            already in a pointer register, then
7971            if size > 0 && this could be used again
7972            we have to point it back to where it 
7973            belongs */
7974         if (AOP_SIZE(right) > 1 &&
7975             !OP_SYMBOL(result)->remat &&
7976             ( OP_SYMBOL(result)->liveTo > ic->seq ||
7977               ic->depth )) {
7978             int size = AOP_SIZE(right) - 1;
7979             while (size--)
7980                 pic14_emitcode("dec","%s",rname);
7981         }
7982     }
7983
7984     /* done */
7985     freeAsmop(right,NULL,ic,TRUE);
7986     
7987         
7988 }
7989
7990 /*-----------------------------------------------------------------*/
7991 /* genFarPointerSet - set value from far space                     */
7992 /*-----------------------------------------------------------------*/
7993 static void genFarPointerSet (operand *right,
7994                               operand *result, iCode *ic)
7995 {
7996     int size, offset ;
7997     sym_link *retype = getSpec(operandType(right));
7998
7999     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8000     aopOp(result,ic,FALSE);
8001
8002     /* if the operand is already in dptr 
8003     then we do nothing else we move the value to dptr */
8004     if (AOP_TYPE(result) != AOP_STR) {
8005         /* if this is remateriazable */
8006         if (AOP_TYPE(result) == AOP_IMMD)
8007             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8008         else { /* we need to get it byte by byte */
8009             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8010             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8011             if (options.model == MODEL_FLAT24)
8012             {
8013                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8014             }
8015         }
8016     }
8017     /* so dptr know contains the address */
8018     freeAsmop(result,NULL,ic,TRUE);
8019     aopOp(right,ic,FALSE);
8020
8021     /* if bit then unpack */
8022     if (IS_BITVAR(retype)) 
8023         genPackBits(retype,right,"dptr",FPOINTER);
8024     else {
8025         size = AOP_SIZE(right);
8026         offset = 0 ;
8027
8028         while (size--) {
8029             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8030             MOVA(l);
8031             pic14_emitcode("movx","@dptr,a");
8032             if (size)
8033                 pic14_emitcode("inc","dptr");
8034         }
8035     }
8036
8037     freeAsmop(right,NULL,ic,TRUE);
8038 }
8039
8040 /*-----------------------------------------------------------------*/
8041 /* genGenPointerSet - set value from generic pointer space         */
8042 /*-----------------------------------------------------------------*/
8043 static void genGenPointerSet (operand *right,
8044                               operand *result, iCode *ic)
8045 {
8046   int size, offset ;
8047   sym_link *retype = getSpec(operandType(right));
8048
8049   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8050
8051   aopOp(result,ic,FALSE);
8052   aopOp(right,ic,FALSE);
8053   size = AOP_SIZE(right);
8054
8055   DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8056                        AopType(AOP_TYPE(result)),
8057                        aopGet(AOP(result),0,TRUE,FALSE),
8058                        AopType(AOP_TYPE(right)),
8059                        aopGet(AOP(right),0,FALSE,FALSE),
8060                        size);
8061
8062   /* if the operand is already in dptr 
8063      then we do nothing else we move the value to dptr */
8064   if (AOP_TYPE(result) != AOP_STR) {
8065     /* if this is remateriazable */
8066     if (AOP_TYPE(result) == AOP_IMMD) {
8067       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8068       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8069     }
8070     else { /* we need to get it byte by byte */
8071       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8072       size = AOP_SIZE(right);
8073       offset = 0 ;
8074
8075       /* hack hack! see if this the FSR. If so don't load W */
8076       if(AOP_TYPE(right) != AOP_ACC) {
8077
8078         if(size==2)
8079           emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8080
8081         if(size==4) {
8082           emitpcode(POC_MOVLW,popGetLit(0xfd));
8083           emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8084         }
8085
8086         while(size--) {
8087           emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8088           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8089           
8090           if(size)
8091             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8092         }
8093
8094
8095         goto release;
8096       } 
8097
8098       if(aopIdx(AOP(result),0) != 4) {
8099
8100         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8101         goto release;
8102       }
8103
8104       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8105       goto release;
8106
8107     }
8108   }
8109   /* so dptr know contains the address */
8110
8111
8112   /* if bit then unpack */
8113   if (IS_BITVAR(retype)) 
8114     genPackBits(retype,right,"dptr",GPOINTER);
8115   else {
8116     size = AOP_SIZE(right);
8117     offset = 0 ;
8118
8119     while (--size) {
8120       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8121       if(size)
8122         pic14_emitcode("incf","fsr,f");
8123       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8124       pic14_emitcode("movwf","indf");
8125       //MOVA(l);
8126       //DEBUGpic14_emitcode(";lcall","__gptrput");
8127       //if (size)
8128       //    pic14_emitcode("inc","dptr");
8129     }
8130   }
8131
8132  release:
8133   freeAsmop(right,NULL,ic,TRUE);
8134   freeAsmop(result,NULL,ic,TRUE);
8135 }
8136
8137 /*-----------------------------------------------------------------*/
8138 /* genPointerSet - stores the value into a pointer location        */
8139 /*-----------------------------------------------------------------*/
8140 static void genPointerSet (iCode *ic)
8141 {    
8142     operand *right, *result ;
8143     sym_link *type, *etype;
8144     int p_type;
8145
8146     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8147
8148     right = IC_RIGHT(ic);
8149     result = IC_RESULT(ic) ;
8150
8151     /* depending on the type of pointer we need to
8152     move it to the correct pointer register */
8153     type = operandType(result);
8154     etype = getSpec(type);
8155     /* if left is of type of pointer then it is simple */
8156     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8157         p_type = DCL_TYPE(type);
8158     }
8159     else {
8160         /* we have to go by the storage class */
8161         p_type = PTR_TYPE(SPEC_OCLS(etype));
8162
8163 /*      if (SPEC_OCLS(etype)->codesp ) { */
8164 /*          p_type = CPOINTER ;  */
8165 /*      } */
8166 /*      else */
8167 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8168 /*              p_type = FPOINTER ; */
8169 /*          else */
8170 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8171 /*                  p_type = PPOINTER ; */
8172 /*              else */
8173 /*                  if (SPEC_OCLS(etype) == idata ) */
8174 /*                      p_type = IPOINTER ; */
8175 /*                  else */
8176 /*                      p_type = POINTER ; */
8177     }
8178
8179     /* now that we have the pointer type we assign
8180     the pointer values */
8181     switch (p_type) {
8182
8183     case POINTER:
8184     case IPOINTER:
8185         genNearPointerSet (right,result,ic);
8186         break;
8187
8188     case PPOINTER:
8189         genPagedPointerSet (right,result,ic);
8190         break;
8191
8192     case FPOINTER:
8193         genFarPointerSet (right,result,ic);
8194         break;
8195
8196     case GPOINTER:
8197         genGenPointerSet (right,result,ic);
8198         break;
8199     }
8200
8201 }
8202
8203 /*-----------------------------------------------------------------*/
8204 /* genIfx - generate code for Ifx statement                        */
8205 /*-----------------------------------------------------------------*/
8206 static void genIfx (iCode *ic, iCode *popIc)
8207 {
8208   operand *cond = IC_COND(ic);
8209   int isbit =0;
8210
8211   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8212
8213   aopOp(cond,ic,FALSE);
8214
8215   /* get the value into acc */
8216   if (AOP_TYPE(cond) != AOP_CRY)
8217     pic14_toBoolean(cond);
8218   else
8219     isbit = 1;
8220   /* the result is now in the accumulator */
8221   freeAsmop(cond,NULL,ic,TRUE);
8222
8223   /* if there was something to be popped then do it */
8224   if (popIc)
8225     genIpop(popIc);
8226
8227   /* if the condition is  a bit variable */
8228   if (isbit && IS_ITEMP(cond) && 
8229       SPIL_LOC(cond)) {
8230     genIfxJump(ic,SPIL_LOC(cond)->rname);
8231     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8232   }
8233   else {
8234     if (isbit && !IS_ITEMP(cond))
8235       genIfxJump(ic,OP_SYMBOL(cond)->rname);
8236     else
8237       genIfxJump(ic,"a");
8238   }
8239   ic->generated = 1;
8240
8241 }
8242
8243 /*-----------------------------------------------------------------*/
8244 /* genAddrOf - generates code for address of                       */
8245 /*-----------------------------------------------------------------*/
8246 static void genAddrOf (iCode *ic)
8247 {
8248   //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8249   operand *right, *result, *left;
8250   //int size, offset ;
8251
8252   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8253
8254
8255   //aopOp(IC_RESULT(ic),ic,FALSE);
8256
8257   aopOp((left=IC_LEFT(ic)),ic,FALSE);
8258   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8259   aopOp((result=IC_RESULT(ic)),ic,TRUE);
8260
8261   if(result)
8262     DEBUGpic14_emitcode ("; ","result %s",
8263                          AopType(AOP_TYPE(IC_RESULT(ic))));
8264
8265   if(left)
8266     DEBUGpic14_emitcode ("; ","left %s",
8267                          AopType(AOP_TYPE(IC_LEFT(ic))));
8268   if(right)
8269     DEBUGpic14_emitcode ("; ","right %s",
8270                          AopType(AOP_TYPE(IC_RIGHT(ic))));
8271   
8272   emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8273   emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8274
8275 #if 0
8276   /* object not on stack then we need the name */
8277   size = AOP_SIZE(IC_RESULT(ic));
8278   offset = 0;
8279
8280   while (size--) {
8281     char s[SDCC_NAME_MAX];
8282     if (offset) 
8283       sprintf(s,"#(%s >> %d)",
8284               sym->rname,
8285               offset*8);
8286     else
8287       sprintf(s,"#%s",sym->rname);
8288     aopPut(AOP(IC_RESULT(ic)),s,offset++);
8289   }
8290 #endif
8291
8292
8293   //  freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8294   freeAsmop(left,NULL,ic,FALSE);
8295   freeAsmop(result,NULL,ic,TRUE);
8296
8297 }
8298
8299 #if 0
8300 /*-----------------------------------------------------------------*/
8301 /* genFarFarAssign - assignment when both are in far space         */
8302 /*-----------------------------------------------------------------*/
8303 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8304 {
8305     int size = AOP_SIZE(right);
8306     int offset = 0;
8307     char *l ;
8308     /* first push the right side on to the stack */
8309     while (size--) {
8310         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8311         MOVA(l);
8312         pic14_emitcode ("push","acc");
8313     }
8314     
8315     freeAsmop(right,NULL,ic,FALSE);
8316     /* now assign DPTR to result */
8317     aopOp(result,ic,FALSE);
8318     size = AOP_SIZE(result);
8319     while (size--) {
8320         pic14_emitcode ("pop","acc");
8321         aopPut(AOP(result),"a",--offset);
8322     }
8323     freeAsmop(result,NULL,ic,FALSE);
8324         
8325 }
8326 #endif
8327
8328 /*-----------------------------------------------------------------*/
8329 /* genAssign - generate code for assignment                        */
8330 /*-----------------------------------------------------------------*/
8331 static void genAssign (iCode *ic)
8332 {
8333   operand *result, *right;
8334   int size, offset,know_W;
8335   unsigned long lit = 0L;
8336
8337   result = IC_RESULT(ic);
8338   right  = IC_RIGHT(ic) ;
8339
8340   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8341
8342   /* if they are the same */
8343   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8344     return ;
8345
8346   aopOp(right,ic,FALSE);
8347   aopOp(result,ic,TRUE);
8348
8349   DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8350                        AopType(AOP_TYPE(IC_RESULT(ic))),
8351                        AopType(AOP_TYPE(IC_RIGHT(ic))),
8352                        AOP_SIZE(result));
8353
8354   /* if they are the same registers */
8355   if (pic14_sameRegs(AOP(right),AOP(result)))
8356     goto release;
8357
8358   /* if the result is a bit */
8359   if (AOP_TYPE(result) == AOP_CRY) {
8360
8361     /* if the right size is a literal then
8362        we know what the value is */
8363     if (AOP_TYPE(right) == AOP_LIT) {
8364           
8365       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8366                   popGet(AOP(result),0,FALSE,FALSE));
8367
8368       if (((int) operandLitValue(right))) 
8369         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8370                        AOP(result)->aopu.aop_dir,
8371                        AOP(result)->aopu.aop_dir);
8372       else
8373         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8374                        AOP(result)->aopu.aop_dir,
8375                        AOP(result)->aopu.aop_dir);
8376       goto release;
8377     }
8378
8379     /* the right is also a bit variable */
8380     if (AOP_TYPE(right) == AOP_CRY) {
8381       emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8382       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8383       emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8384
8385       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8386                      AOP(result)->aopu.aop_dir,
8387                      AOP(result)->aopu.aop_dir);
8388       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8389                      AOP(right)->aopu.aop_dir,
8390                      AOP(right)->aopu.aop_dir);
8391       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8392                      AOP(result)->aopu.aop_dir,
8393                      AOP(result)->aopu.aop_dir);
8394       goto release ;
8395     }
8396
8397     /* we need to or */
8398     emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8399     pic14_toBoolean(right);
8400     emitSKPZ;
8401     emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8402     //aopPut(AOP(result),"a",0);
8403     goto release ;
8404   }
8405
8406   /* bit variables done */
8407   /* general case */
8408   size = AOP_SIZE(result);
8409   offset = 0 ;
8410   if(AOP_TYPE(right) == AOP_LIT)
8411     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8412
8413   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
8414     if(aopIdx(AOP(result),0) == 4) {
8415       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8416       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8417       goto release;
8418     } else
8419       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
8420   }
8421
8422   know_W=-1;
8423   while (size--) {
8424     if(AOP_TYPE(right) == AOP_LIT) {
8425       if(lit&0xff) {
8426         if(know_W != (lit&0xff))
8427           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8428         know_W = lit&0xff;
8429         emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8430       } else
8431         emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8432
8433       lit >>= 8;
8434
8435     } else if (AOP_TYPE(right) == AOP_CRY) {
8436       emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8437       if(offset == 0) {
8438         emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8439         emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8440       }
8441     } else {
8442       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8443       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8444     }
8445             
8446     offset++;
8447   }
8448
8449     
8450  release:
8451   freeAsmop (right,NULL,ic,FALSE);
8452   freeAsmop (result,NULL,ic,TRUE);
8453 }   
8454
8455 /*-----------------------------------------------------------------*/
8456 /* genJumpTab - genrates code for jump table                       */
8457 /*-----------------------------------------------------------------*/
8458 static void genJumpTab (iCode *ic)
8459 {
8460     symbol *jtab;
8461     char *l;
8462
8463     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8464
8465     aopOp(IC_JTCOND(ic),ic,FALSE);
8466     /* get the condition into accumulator */
8467     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8468     MOVA(l);
8469     /* multiply by three */
8470     pic14_emitcode("add","a,acc");
8471     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8472
8473     jtab = newiTempLabel(NULL);
8474     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8475     pic14_emitcode("jmp","@a+dptr");
8476     pic14_emitcode("","%05d_DS_:",jtab->key+100);
8477
8478     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8479     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8480     emitSKPNC;
8481     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8482     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8483     emitpLabel(jtab->key);
8484
8485     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8486
8487     /* now generate the jump labels */
8488     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8489          jtab = setNextItem(IC_JTLABELS(ic))) {
8490         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8491         emitpcode(POC_GOTO,popGetLabel(jtab->key));
8492         
8493     }
8494
8495 }
8496
8497 /*-----------------------------------------------------------------*/
8498 /* genMixedOperation - gen code for operators between mixed types  */
8499 /*-----------------------------------------------------------------*/
8500 /*
8501   TSD - Written for the PIC port - but this unfortunately is buggy.
8502   This routine is good in that it is able to efficiently promote 
8503   types to different (larger) sizes. Unfortunately, the temporary
8504   variables that are optimized out by this routine are sometimes
8505   used in other places. So until I know how to really parse the 
8506   iCode tree, I'm going to not be using this routine :(.
8507 */
8508 static int genMixedOperation (iCode *ic)
8509 {
8510 #if 0
8511   operand *result = IC_RESULT(ic);
8512   sym_link *ctype = operandType(IC_LEFT(ic));
8513   operand *right = IC_RIGHT(ic);
8514   int ret = 0;
8515   int big,small;
8516   int offset;
8517
8518   iCode *nextic;
8519   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8520
8521   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8522
8523   nextic = ic->next;
8524   if(!nextic)
8525     return 0;
8526
8527   nextright = IC_RIGHT(nextic);
8528   nextleft  = IC_LEFT(nextic);
8529   nextresult = IC_RESULT(nextic);
8530
8531   aopOp(right,ic,FALSE);
8532   aopOp(result,ic,FALSE);
8533   aopOp(nextright,  nextic, FALSE);
8534   aopOp(nextleft,   nextic, FALSE);
8535   aopOp(nextresult, nextic, FALSE);
8536
8537   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8538
8539     operand *t = right;
8540     right = nextright;
8541     nextright = t; 
8542
8543     pic14_emitcode(";remove right +","");
8544
8545   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8546 /*
8547     operand *t = right;
8548     right = nextleft;
8549     nextleft = t; 
8550 */
8551     pic14_emitcode(";remove left +","");
8552   } else
8553     return 0;
8554
8555   big = AOP_SIZE(nextleft);
8556   small = AOP_SIZE(nextright);
8557
8558   switch(nextic->op) {
8559
8560   case '+':
8561     pic14_emitcode(";optimize a +","");
8562     /* if unsigned or not an integral type */
8563     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8564       pic14_emitcode(";add a bit to something","");
8565     } else {
8566
8567       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8568
8569       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8570         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8571         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8572       } else
8573         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8574
8575       offset = 0;
8576       while(--big) {
8577
8578         offset++;
8579
8580         if(--small) {
8581           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8582             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8583             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8584           }
8585
8586           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8587           emitSKPNC;
8588           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8589                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8590                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8591           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8592           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8593
8594         } else {
8595           pic14_emitcode("rlf","known_zero,w");
8596
8597           /*
8598             if right is signed
8599               btfsc  right,7
8600                addlw ff
8601           */
8602           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8603             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8604             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8605           } else {
8606             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8607           }
8608         }
8609       }
8610       ret = 1;
8611     }
8612   }
8613   ret = 1;
8614
8615 release:
8616   freeAsmop(right,NULL,ic,TRUE);
8617   freeAsmop(result,NULL,ic,TRUE);
8618   freeAsmop(nextright,NULL,ic,TRUE);
8619   freeAsmop(nextleft,NULL,ic,TRUE);
8620   if(ret)
8621     nextic->generated = 1;
8622
8623   return ret;
8624 #else
8625   return 0;
8626 #endif
8627 }
8628 /*-----------------------------------------------------------------*/
8629 /* genCast - gen code for casting                                  */
8630 /*-----------------------------------------------------------------*/
8631 static void genCast (iCode *ic)
8632 {
8633     operand *result = IC_RESULT(ic);
8634     sym_link *ctype = operandType(IC_LEFT(ic));
8635     operand *right = IC_RIGHT(ic);
8636     int size, offset ;
8637
8638     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8639     /* if they are equivalent then do nothing */
8640     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8641         return ;
8642
8643     aopOp(right,ic,FALSE) ;
8644     aopOp(result,ic,FALSE);
8645
8646     /* if the result is a bit */
8647     if (AOP_TYPE(result) == AOP_CRY) {
8648         /* if the right size is a literal then
8649         we know what the value is */
8650         if (AOP_TYPE(right) == AOP_LIT) {
8651
8652           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8653                       popGet(AOP(result),0,FALSE,FALSE));
8654
8655             if (((int) operandLitValue(right))) 
8656               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8657                        AOP(result)->aopu.aop_dir,
8658                        AOP(result)->aopu.aop_dir);
8659             else
8660               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8661                        AOP(result)->aopu.aop_dir,
8662                        AOP(result)->aopu.aop_dir);
8663
8664             goto release;
8665         }
8666
8667         /* the right is also a bit variable */
8668         if (AOP_TYPE(right) == AOP_CRY) {
8669
8670           emitCLRC;
8671           emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8672
8673           pic14_emitcode("clrc","");
8674           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8675                    AOP(right)->aopu.aop_dir,
8676                    AOP(right)->aopu.aop_dir);
8677             aopPut(AOP(result),"c",0);
8678             goto release ;
8679         }
8680
8681         /* we need to or */
8682         pic14_toBoolean(right);
8683         aopPut(AOP(result),"a",0);
8684         goto release ;
8685     }
8686
8687     /* if they are the same size : or less */
8688     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8689
8690         /* if they are in the same place */
8691         if (pic14_sameRegs(AOP(right),AOP(result)))
8692             goto release;
8693
8694         /* if they in different places then copy */
8695         size = AOP_SIZE(result);
8696         offset = 0 ;
8697         while (size--) {
8698             aopPut(AOP(result),
8699                    aopGet(AOP(right),offset,FALSE,FALSE),
8700                    offset);
8701             offset++;
8702         }
8703         goto release;
8704     }
8705
8706
8707     /* if the result is of type pointer */
8708     if (IS_PTR(ctype)) {
8709
8710         int p_type;
8711         sym_link *type = operandType(right);
8712         sym_link *etype = getSpec(type);
8713
8714         /* pointer to generic pointer */
8715         if (IS_GENPTR(ctype)) {
8716             char *l = zero;
8717             
8718             if (IS_PTR(type)) 
8719                 p_type = DCL_TYPE(type);
8720             else {
8721                 /* we have to go by the storage class */
8722                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8723
8724 /*              if (SPEC_OCLS(etype)->codesp )  */
8725 /*                  p_type = CPOINTER ;  */
8726 /*              else */
8727 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8728 /*                      p_type = FPOINTER ; */
8729 /*                  else */
8730 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8731 /*                          p_type = PPOINTER; */
8732 /*                      else */
8733 /*                          if (SPEC_OCLS(etype) == idata ) */
8734 /*                              p_type = IPOINTER ; */
8735 /*                          else */
8736 /*                              p_type = POINTER ; */
8737             }
8738                 
8739             /* the first two bytes are known */
8740             size = GPTRSIZE - 1; 
8741             offset = 0 ;
8742             while (size--) {
8743                 aopPut(AOP(result),
8744                        aopGet(AOP(right),offset,FALSE,FALSE),
8745                        offset);
8746                 offset++;
8747             }
8748             /* the last byte depending on type */
8749             switch (p_type) {
8750             case IPOINTER:
8751             case POINTER:
8752                 l = zero;
8753                 break;
8754             case FPOINTER:
8755                 l = one;
8756                 break;
8757             case CPOINTER:
8758                 l = "#0x02";
8759                 break;                          
8760             case PPOINTER:
8761                 l = "#0x03";
8762                 break;
8763                 
8764             default:
8765                 /* this should never happen */
8766                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8767                        "got unknown pointer type");
8768                 exit(1);
8769             }
8770             aopPut(AOP(result),l, GPTRSIZE - 1);            
8771             goto release ;
8772         }
8773         
8774         /* just copy the pointers */
8775         size = AOP_SIZE(result);
8776         offset = 0 ;
8777         while (size--) {
8778             aopPut(AOP(result),
8779                    aopGet(AOP(right),offset,FALSE,FALSE),
8780                    offset);
8781             offset++;
8782         }
8783         goto release ;
8784     }
8785     
8786
8787     if (AOP_TYPE(right) == AOP_CRY) {
8788       int offset = 1;
8789       size = AOP_SIZE(right);
8790
8791       emitpcode(POC_CLRF,   popGet(AOP(result),0,FALSE,FALSE));
8792       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8793       emitpcode(POC_INCF,   popGet(AOP(result),0,FALSE,FALSE));
8794
8795       pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8796       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8797                AOP(right)->aopu.aop_dir,
8798                AOP(right)->aopu.aop_dir);
8799       pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8800       while (size--) {
8801         pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8802         emitpcode(POC_CLRF,   popGet(AOP(result),offset++,FALSE,FALSE));
8803       }
8804       goto release;
8805     }
8806
8807     /* so we now know that the size of destination is greater
8808     than the size of the source.
8809     Now, if the next iCode is an operator then we might be
8810     able to optimize the operation without performing a cast.
8811     */
8812     if(genMixedOperation(ic))
8813       goto release;
8814
8815     
8816     /* we move to result for the size of source */
8817     size = AOP_SIZE(right);
8818     offset = 0 ;
8819     while (size--) {
8820       pic14_emitcode(";","%d",__LINE__);
8821       /* aopPut(AOP(result),
8822              aopGet(AOP(right),offset,FALSE,FALSE),
8823              offset); */
8824       emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
8825       emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8826       offset++;
8827     }
8828
8829     /* now depending on the sign of the destination */
8830     size = AOP_SIZE(result) - AOP_SIZE(right);
8831     /* if unsigned or not an integral type */
8832     if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8833       while (size--) {
8834           emitpcode(POC_CLRF,   popGet(AOP(result),offset,FALSE,FALSE));
8835           pic14_emitcode("clrf","%s  ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8836           offset++;
8837       }
8838     } else {
8839       /* we need to extend the sign :{ */
8840
8841       emitpcodeNULLop(POC_CLRW);
8842
8843       if(offset)
8844         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8845       else
8846         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8847
8848       emitpcode(POC_MOVLW,   popGetLit(0xff));
8849
8850         pic14_emitcode("clrw","");
8851         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8852                  AOP(right)->aopu.aop_dir,
8853                  AOP(right)->aopu.aop_dir);
8854         pic14_emitcode("movlw","0xff");
8855         while (size--) {
8856           emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8857           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8858           offset++;
8859           // aopPut(AOP(result),"a",offset++);
8860         }
8861
8862     }
8863
8864     /* we are done hurray !!!! */
8865
8866 release:
8867     freeAsmop(right,NULL,ic,TRUE);
8868     freeAsmop(result,NULL,ic,TRUE);
8869
8870 }
8871
8872 /*-----------------------------------------------------------------*/
8873 /* genDjnz - generate decrement & jump if not zero instrucion      */
8874 /*-----------------------------------------------------------------*/
8875 static int genDjnz (iCode *ic, iCode *ifx)
8876 {
8877     symbol *lbl, *lbl1;
8878     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8879
8880     if (!ifx)
8881         return 0;
8882     
8883     /* if the if condition has a false label
8884        then we cannot save */
8885     if (IC_FALSE(ifx))
8886         return 0;
8887
8888     /* if the minus is not of the form 
8889        a = a - 1 */
8890     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8891         !IS_OP_LITERAL(IC_RIGHT(ic)))
8892         return 0;
8893
8894     if (operandLitValue(IC_RIGHT(ic)) != 1)
8895         return 0;
8896
8897     /* if the size of this greater than one then no
8898        saving */
8899     if (getSize(operandType(IC_RESULT(ic))) > 1)
8900         return 0;
8901
8902     /* otherwise we can save BIG */
8903     lbl = newiTempLabel(NULL);
8904     lbl1= newiTempLabel(NULL);
8905
8906     aopOp(IC_RESULT(ic),ic,FALSE);
8907     
8908     if (IS_AOP_PREG(IC_RESULT(ic))) {
8909         pic14_emitcode("dec","%s",
8910                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8911         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8912         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8913     } else {    
8914
8915
8916       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8917       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8918
8919       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8920       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8921
8922     }
8923 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8924 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8925 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8926 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8927
8928     
8929     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8930     ifx->generated = 1;
8931     return 1;
8932 }
8933
8934 /*-----------------------------------------------------------------*/
8935 /* genReceive - generate code for a receive iCode                  */
8936 /*-----------------------------------------------------------------*/
8937 static void genReceive (iCode *ic)
8938 {    
8939     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8940
8941     if (isOperandInFarSpace(IC_RESULT(ic)) && 
8942         ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8943           IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8944
8945         int size = getSize(operandType(IC_RESULT(ic)));
8946         int offset =  fReturnSizePic - size;
8947         while (size--) {
8948             pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8949                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
8950             offset++;
8951         }
8952         aopOp(IC_RESULT(ic),ic,FALSE);  
8953         size = AOP_SIZE(IC_RESULT(ic));
8954         offset = 0;
8955         while (size--) {
8956             pic14_emitcode ("pop","acc");
8957             aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8958         }
8959         
8960     } else {
8961         _G.accInUse++;
8962         aopOp(IC_RESULT(ic),ic,FALSE);  
8963         _G.accInUse--;
8964         assignResultValue(IC_RESULT(ic));       
8965     }
8966
8967     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8968 }
8969
8970 /*-----------------------------------------------------------------*/
8971 /* genpic14Code - generate code for pic14 based controllers        */
8972 /*-----------------------------------------------------------------*/
8973 /*
8974  * At this point, ralloc.c has gone through the iCode and attempted
8975  * to optimize in a way suitable for a PIC. Now we've got to generate
8976  * PIC instructions that correspond to the iCode.
8977  *
8978  * Once the instructions are generated, we'll pass through both the
8979  * peep hole optimizer and the pCode optimizer.
8980  *-----------------------------------------------------------------*/
8981
8982 void genpic14Code (iCode *lic)
8983 {
8984     iCode *ic;
8985     int cln = 0;
8986
8987     lineHead = lineCurr = NULL;
8988
8989     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8990     addpBlock(pb);
8991
8992     /* if debug information required */
8993 /*     if (options.debug && currFunc) { */
8994     if (currFunc) {
8995         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8996         _G.debugLine = 1;
8997         if (IS_STATIC(currFunc->etype)) {
8998             pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
8999             //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9000         } else {
9001             pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9002             //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9003         }
9004         _G.debugLine = 0;
9005     }
9006
9007
9008     for (ic = lic ; ic ; ic = ic->next ) {
9009
9010       DEBUGpic14_emitcode(";ic","");
9011         if ( cln != ic->lineno ) {
9012             if ( options.debug ) {
9013                 _G.debugLine = 1;
9014                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9015                          FileBaseName(ic->filename),ic->lineno,
9016                          ic->level,ic->block);
9017                 _G.debugLine = 0;
9018             }
9019             pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
9020             cln = ic->lineno ;
9021         }
9022         /* if the result is marked as
9023            spilt and rematerializable or code for
9024            this has already been generated then
9025            do nothing */
9026         if (resultRemat(ic) || ic->generated ) 
9027             continue ;
9028         
9029         /* depending on the operation */
9030         switch (ic->op) {
9031         case '!' :
9032             genNot(ic);
9033             break;
9034             
9035         case '~' :
9036             genCpl(ic);
9037             break;
9038             
9039         case UNARYMINUS:
9040             genUminus (ic);
9041             break;
9042             
9043         case IPUSH:
9044             genIpush (ic);
9045             break;
9046             
9047         case IPOP:
9048             /* IPOP happens only when trying to restore a 
9049                spilt live range, if there is an ifx statement
9050                following this pop then the if statement might
9051                be using some of the registers being popped which
9052                would destory the contents of the register so
9053                we need to check for this condition and handle it */
9054             if (ic->next            && 
9055                 ic->next->op == IFX &&
9056                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9057                 genIfx (ic->next,ic);
9058             else
9059                 genIpop (ic);
9060             break; 
9061             
9062         case CALL:
9063             genCall (ic);
9064             break;
9065             
9066         case PCALL:
9067             genPcall (ic);
9068             break;
9069             
9070         case FUNCTION:
9071             genFunction (ic);
9072             break;
9073             
9074         case ENDFUNCTION:
9075             genEndFunction (ic);
9076             break;
9077             
9078         case RETURN:
9079             genRet (ic);
9080             break;
9081             
9082         case LABEL:
9083             genLabel (ic);
9084             break;
9085             
9086         case GOTO:
9087             genGoto (ic);
9088             break;
9089             
9090         case '+' :
9091             genPlus (ic) ;
9092             break;
9093             
9094         case '-' :
9095             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9096                 genMinus (ic);
9097             break;
9098             
9099         case '*' :
9100             genMult (ic);
9101             break;
9102             
9103         case '/' :
9104             genDiv (ic) ;
9105             break;
9106             
9107         case '%' :
9108             genMod (ic);
9109             break;
9110             
9111         case '>' :
9112             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9113             break;
9114             
9115         case '<' :
9116             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9117             break;
9118             
9119         case LE_OP:
9120         case GE_OP:
9121         case NE_OP:
9122             
9123             /* note these two are xlated by algebraic equivalence
9124                during parsing SDCC.y */
9125             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9126                    "got '>=' or '<=' shouldn't have come here");
9127             break;      
9128             
9129         case EQ_OP:
9130             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9131             break;          
9132             
9133         case AND_OP:
9134             genAndOp (ic);
9135             break;
9136             
9137         case OR_OP:
9138             genOrOp (ic);
9139             break;
9140             
9141         case '^' :
9142             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9143             break;
9144             
9145         case '|' :
9146                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9147             break;
9148             
9149         case BITWISEAND:
9150             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9151             break;
9152             
9153         case INLINEASM:
9154             genInline (ic);
9155             break;
9156             
9157         case RRC:
9158             genRRC (ic);
9159             break;
9160             
9161         case RLC:
9162             genRLC (ic);
9163             break;
9164             
9165         case GETHBIT:
9166             genGetHbit (ic);
9167             break;
9168             
9169         case LEFT_OP:
9170             genLeftShift (ic);
9171             break;
9172             
9173         case RIGHT_OP:
9174             genRightShift (ic);
9175             break;
9176             
9177         case GET_VALUE_AT_ADDRESS:
9178             genPointerGet(ic);
9179             break;
9180             
9181         case '=' :
9182             if (POINTER_SET(ic))
9183                 genPointerSet(ic);
9184             else
9185                 genAssign(ic);
9186             break;
9187             
9188         case IFX:
9189             genIfx (ic,NULL);
9190             break;
9191             
9192         case ADDRESS_OF:
9193             genAddrOf (ic);
9194             break;
9195             
9196         case JUMPTABLE:
9197             genJumpTab (ic);
9198             break;
9199             
9200         case CAST:
9201             genCast (ic);
9202             break;
9203             
9204         case RECEIVE:
9205             genReceive(ic);
9206             break;
9207             
9208         case SEND:
9209             addSet(&_G.sendSet,ic);
9210             break;
9211
9212         default :
9213             ic = ic;
9214         }
9215     }
9216     
9217
9218     /* now we are ready to call the 
9219        peep hole optimizer */
9220     if (!options.nopeep) {
9221       printf("peep hole optimizing\n");
9222         peepHole (&lineHead);
9223     }
9224     /* now do the actual printing */
9225     printLine (lineHead,codeOutFile);
9226
9227     printf("printing pBlock\n\n");
9228     printpBlock(stdout,pb);
9229
9230     return;
9231 }