- Added ;#CSRC labels so that a 3rd party tool can parse the .asm output
[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     if(IC_TRUE(ifx)) 
396       DEBUGpic14_emitcode("; ***","ifx true is non-null");
397     if(IC_FALSE(ifx)) 
398       DEBUGpic14_emitcode("; ***","ifx false is non-null");
399   }
400
401   DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
402
403 }
404 /*-----------------------------------------------------------------*/
405 /* pointerCode - returns the code for a pointer type               */
406 /*-----------------------------------------------------------------*/
407 static int pointerCode (sym_link *etype)
408 {
409
410     return PTR_TYPE(SPEC_OCLS(etype));
411
412 }
413
414 /*-----------------------------------------------------------------*/
415 /* aopForSym - for a true symbol                                   */
416 /*-----------------------------------------------------------------*/
417 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
418 {
419     asmop *aop;
420     memmap *space= SPEC_OCLS(sym->etype);
421
422     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
423     /* if already has one */
424     if (sym->aop)
425         return sym->aop;
426
427     /* assign depending on the storage class */
428     /* if it is on the stack or indirectly addressable */
429     /* space we need to assign either r0 or r1 to it   */    
430     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
431         sym->aop = aop = newAsmop(0);
432         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
433         aop->size = getSize(sym->type);
434
435         /* now assign the address of the variable to 
436         the pointer register */
437         if (aop->type != AOP_STK) {
438
439             if (sym->onStack) {
440                     if ( _G.accInUse )
441                         pic14_emitcode("push","acc");
442
443                     pic14_emitcode("mov","a,_bp");
444                     pic14_emitcode("add","a,#0x%02x",
445                              ((sym->stack < 0) ?
446                               ((char)(sym->stack - _G.nRegsSaved )) :
447                               ((char)sym->stack)) & 0xff);
448                     pic14_emitcode("mov","%s,a",
449                              aop->aopu.aop_ptr->name);
450
451                     if ( _G.accInUse )
452                         pic14_emitcode("pop","acc");
453             } else
454                 pic14_emitcode("mov","%s,#%s",
455                          aop->aopu.aop_ptr->name,
456                          sym->rname);
457             aop->paged = space->paged;
458         } else
459             aop->aopu.aop_stk = sym->stack;
460         return aop;
461     }
462     
463     if (sym->onStack && options.stack10bit)
464     {
465         /* It's on the 10 bit stack, which is located in
466          * far data space.
467          */
468          
469       //DEBUGpic14_emitcode(";","%d",__LINE__);
470
471         if ( _G.accInUse )
472                 pic14_emitcode("push","acc");
473
474         pic14_emitcode("mov","a,_bp");
475         pic14_emitcode("add","a,#0x%02x",
476                  ((sym->stack < 0) ?
477                    ((char)(sym->stack - _G.nRegsSaved )) :
478                    ((char)sym->stack)) & 0xff);
479         
480         genSetDPTR(1);
481         pic14_emitcode ("mov","dpx1,#0x40");
482         pic14_emitcode ("mov","dph1,#0x00");
483         pic14_emitcode ("mov","dpl1, a");
484         genSetDPTR(0);
485         
486         if ( _G.accInUse )
487             pic14_emitcode("pop","acc");
488             
489         sym->aop = aop = newAsmop(AOP_DPTR2);
490         aop->size = getSize(sym->type); 
491         return aop;
492     }
493
494     //DEBUGpic14_emitcode(";","%d",__LINE__);
495     /* if in bit space */
496     if (IN_BITSPACE(space)) {
497         sym->aop = aop = newAsmop (AOP_CRY);
498         aop->aopu.aop_dir = sym->rname ;
499         aop->size = getSize(sym->type);
500         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
501         return aop;
502     }
503     /* if it is in direct space */
504     if (IN_DIRSPACE(space)) {
505         sym->aop = aop = newAsmop (AOP_DIR);
506         aop->aopu.aop_dir = sym->rname ;
507         aop->size = getSize(sym->type);
508         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
509         return aop;
510     }
511
512     /* special case for a function */
513     if (IS_FUNC(sym->type)) {   
514         sym->aop = aop = newAsmop(AOP_IMMD);    
515         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
516         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
517         strcpy(aop->aopu.aop_immd,sym->rname);
518         aop->size = FPTRSIZE; 
519         return aop;
520     }
521
522
523     /* only remaining is far space */
524     /* in which case DPTR gets the address */
525     sym->aop = aop = newAsmop(AOP_DPTR);
526     pic14_emitcode ("mov","dptr,#%s", sym->rname);
527     aop->size = getSize(sym->type);
528
529     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
530     /* if it is in code space */
531     if (IN_CODESPACE(space))
532         aop->code = 1;
533
534     return aop;     
535 }
536
537 /*-----------------------------------------------------------------*/
538 /* aopForRemat - rematerialzes an object                           */
539 /*-----------------------------------------------------------------*/
540 static asmop *aopForRemat (symbol *sym)
541 {
542     iCode *ic = sym->rematiCode;
543     asmop *aop = newAsmop(AOP_IMMD);
544     int val = 0;
545     DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
546     for (;;) {
547         if (ic->op == '+')
548             val += (int) operandLitValue(IC_RIGHT(ic));
549         else if (ic->op == '-')
550             val -= (int) operandLitValue(IC_RIGHT(ic));
551         else
552             break;
553         
554         ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
555     }
556
557     if (val)
558         sprintf(buffer,"(%s %c 0x%04x)",
559                 OP_SYMBOL(IC_LEFT(ic))->rname, 
560                 val >= 0 ? '+' : '-',
561                 abs(val) & 0xffff);
562     else
563         strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
564
565     //DEBUGpic14_emitcode(";","%s",buffer);
566     aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
567     strcpy(aop->aopu.aop_immd,buffer);    
568     return aop;        
569 }
570
571 int aopIdx (asmop *aop, int offset)
572 {
573   if(!aop)
574     return -1;
575
576   if(aop->type !=  AOP_REG)
577     return -2;
578         
579   return aop->aopu.aop_reg[offset]->rIdx;
580
581 }
582 /*-----------------------------------------------------------------*/
583 /* regsInCommon - two operands have some registers in common       */
584 /*-----------------------------------------------------------------*/
585 static bool regsInCommon (operand *op1, operand *op2)
586 {
587     symbol *sym1, *sym2;
588     int i;
589
590     /* if they have registers in common */
591     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
592         return FALSE ;
593
594     sym1 = OP_SYMBOL(op1);
595     sym2 = OP_SYMBOL(op2);
596
597     if (sym1->nRegs == 0 || sym2->nRegs == 0)
598         return FALSE ;
599
600     for (i = 0 ; i < sym1->nRegs ; i++) {
601         int j;
602         if (!sym1->regs[i])
603             continue ;
604
605         for (j = 0 ; j < sym2->nRegs ;j++ ) {
606             if (!sym2->regs[j])
607                 continue ;
608
609             if (sym2->regs[j] == sym1->regs[i])
610                 return TRUE ;
611         }
612     }
613
614     return FALSE ;
615 }
616
617 /*-----------------------------------------------------------------*/
618 /* operandsEqu - equivalent                                        */
619 /*-----------------------------------------------------------------*/
620 static bool operandsEqu ( operand *op1, operand *op2)
621 {
622     symbol *sym1, *sym2;
623
624     /* if they not symbols */
625     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
626         return FALSE;
627
628     sym1 = OP_SYMBOL(op1);
629     sym2 = OP_SYMBOL(op2);
630
631     /* if both are itemps & one is spilt
632        and the other is not then false */
633     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
634         sym1->isspilt != sym2->isspilt )
635         return FALSE ;
636
637     /* if they are the same */
638     if (sym1 == sym2)
639         return TRUE ;
640
641     if (strcmp(sym1->rname,sym2->rname) == 0)
642         return TRUE;
643
644
645     /* if left is a tmp & right is not */
646     if (IS_ITEMP(op1)  && 
647         !IS_ITEMP(op2) &&
648         sym1->isspilt  &&
649         (sym1->usl.spillLoc == sym2))
650         return TRUE;
651
652     if (IS_ITEMP(op2)  && 
653         !IS_ITEMP(op1) &&
654         sym2->isspilt  &&
655         sym1->level > 0 &&
656         (sym2->usl.spillLoc == sym1))
657         return TRUE ;
658
659     return FALSE ;
660 }
661
662 /*-----------------------------------------------------------------*/
663 /* pic14_sameRegs - two asmops have the same registers                   */
664 /*-----------------------------------------------------------------*/
665 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
666 {
667     int i;
668
669     if (aop1 == aop2)
670         return TRUE ;
671
672     if (aop1->type != AOP_REG ||
673         aop2->type != AOP_REG )
674         return FALSE ;
675
676     if (aop1->size != aop2->size )
677         return FALSE ;
678
679     for (i = 0 ; i < aop1->size ; i++ )
680         if (aop1->aopu.aop_reg[i] !=
681             aop2->aopu.aop_reg[i] )
682             return FALSE ;
683
684     return TRUE ;
685 }
686
687 /*-----------------------------------------------------------------*/
688 /* aopOp - allocates an asmop for an operand  :                    */
689 /*-----------------------------------------------------------------*/
690 void aopOp (operand *op, iCode *ic, bool result)
691 {
692     asmop *aop;
693     symbol *sym;
694     int i;
695
696     if (!op)
697         return ;
698
699     DEBUGpic14_emitcode(";","%d",__LINE__);
700     /* if this a literal */
701     if (IS_OP_LITERAL(op)) {
702         op->aop = aop = newAsmop(AOP_LIT);
703         aop->aopu.aop_lit = op->operand.valOperand;
704         aop->size = getSize(operandType(op));
705       DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
706         return;
707     }
708
709     /* if already has a asmop then continue */
710     if (op->aop)
711         return ;
712
713     /* if the underlying symbol has a aop */
714     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
715       DEBUGpic14_emitcode(";","%d",__LINE__);
716         op->aop = OP_SYMBOL(op)->aop;
717         return;
718     }
719
720     /* if this is a true symbol */
721     if (IS_TRUE_SYMOP(op)) {    
722       DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
723         op->aop = aopForSym(ic,OP_SYMBOL(op),result);
724         return ;
725     }
726
727     /* this is a temporary : this has
728     only four choices :
729     a) register
730     b) spillocation
731     c) rematerialize 
732     d) conditional   
733     e) can be a return use only */
734
735     sym = OP_SYMBOL(op);
736
737
738     /* if the type is a conditional */
739     if (sym->regType == REG_CND) {
740       DEBUGpic14_emitcode(";","%d",__LINE__);
741         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
742         aop->size = 0;
743         return;
744     }
745
746     /* if it is spilt then two situations
747     a) is rematerialize 
748     b) has a spill location */
749     if (sym->isspilt || sym->nRegs == 0) {
750
751       DEBUGpic14_emitcode(";","%d",__LINE__);
752         /* rematerialize it NOW */
753         if (sym->remat) {
754             sym->aop = op->aop = aop =
755                                       aopForRemat (sym);
756             aop->size = getSize(sym->type);
757             DEBUGpic14_emitcode(";","%d",__LINE__);
758             return;
759         }
760
761         if (sym->accuse) {
762             int i;
763             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
764             aop->size = getSize(sym->type);
765             for ( i = 0 ; i < 2 ; i++ )
766                 aop->aopu.aop_str[i] = accUse[i];
767             DEBUGpic14_emitcode(";","%d",__LINE__);
768             return;  
769         }
770
771         if (sym->ruonly ) {
772             unsigned i;
773             aop = op->aop = sym->aop = newAsmop(AOP_STR);
774             aop->size = getSize(sym->type);
775             for ( i = 0 ; i < fReturnSizePic ; i++ )
776               aop->aopu.aop_str[i] = fReturn[i];
777             DEBUGpic14_emitcode(";","%d",__LINE__);
778             return;
779         }
780
781         /* else spill location  */
782         DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
783         sym->aop = op->aop = aop = 
784                                   aopForSym(ic,sym->usl.spillLoc,result);
785         aop->size = getSize(sym->type);
786         return;
787     }
788
789     /* must be in a register */
790     sym->aop = op->aop = aop = newAsmop(AOP_REG);
791     aop->size = sym->nRegs;
792     for ( i = 0 ; i < sym->nRegs ;i++)
793         aop->aopu.aop_reg[i] = sym->regs[i];
794 }
795
796 /*-----------------------------------------------------------------*/
797 /* freeAsmop - free up the asmop given to an operand               */
798 /*----------------------------------------------------------------*/
799 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
800 {   
801     asmop *aop ;
802
803     if (!op)
804         aop = aaop;
805     else 
806         aop = op->aop;
807
808     if (!aop)
809         return ;
810
811     if (aop->freed)
812         goto dealloc; 
813
814     aop->freed = 1;
815
816     /* depending on the asmop type only three cases need work AOP_RO
817        , AOP_R1 && AOP_STK */
818     switch (aop->type) {
819         case AOP_R0 :
820             if (_G.r0Pushed ) {
821                 if (pop) {
822                     pic14_emitcode ("pop","ar0");     
823                     _G.r0Pushed--;
824                 }
825             }
826             bitVectUnSetBit(ic->rUsed,R0_IDX);
827             break;
828
829         case AOP_R1 :
830             if (_G.r1Pushed ) {
831                 if (pop) {
832                     pic14_emitcode ("pop","ar1");
833                     _G.r1Pushed--;
834                 }
835             }
836             bitVectUnSetBit(ic->rUsed,R1_IDX);          
837             break;
838
839         case AOP_STK :
840         {
841             int sz = aop->size;    
842             int stk = aop->aopu.aop_stk + aop->size;
843             bitVectUnSetBit(ic->rUsed,R0_IDX);
844             bitVectUnSetBit(ic->rUsed,R1_IDX);          
845
846             getFreePtr(ic,&aop,FALSE);
847             
848             if (options.stack10bit)
849             {
850                 /* I'm not sure what to do here yet... */
851                 /* #STUB */
852                 fprintf(stderr, 
853                         "*** Warning: probably generating bad code for "
854                         "10 bit stack mode.\n");
855             }
856             
857             if (stk) {
858                 pic14_emitcode ("mov","a,_bp");
859                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
860                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
861             } else {
862                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
863             }
864
865             while (sz--) {
866                 pic14_emitcode("pop","acc");
867                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
868                 if (!sz) break;
869                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
870             }
871             op->aop = aop;
872             freeAsmop(op,NULL,ic,TRUE);
873             if (_G.r0Pushed) {
874                 pic14_emitcode("pop","ar0");
875                 _G.r0Pushed--;
876             }
877
878             if (_G.r1Pushed) {
879                 pic14_emitcode("pop","ar1");
880                 _G.r1Pushed--;
881             }       
882         }
883     }
884
885 dealloc:
886     /* all other cases just dealloc */
887     if (op ) {
888         op->aop = NULL;
889         if (IS_SYMOP(op)) {
890             OP_SYMBOL(op)->aop = NULL;    
891             /* if the symbol has a spill */
892             if (SPIL_LOC(op))
893                 SPIL_LOC(op)->aop = NULL;
894         }
895     }
896 }
897
898 /*-----------------------------------------------------------------*/
899 /* aopGet - for fetching value of the aop                          */
900 /*-----------------------------------------------------------------*/
901 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
902 {
903     char *s = buffer ;
904     char *rs;
905
906     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
907     /* offset is greater than
908     size then zero */
909     if (offset > (aop->size - 1) &&
910         aop->type != AOP_LIT)
911         return zero;
912
913     /* depending on type */
914     switch (aop->type) {
915         
916     case AOP_R0:
917     case AOP_R1:
918         DEBUGpic14_emitcode(";","%d",__LINE__);
919         /* if we need to increment it */       
920         while (offset > aop->coff) {        
921             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
922             aop->coff++;
923         }
924         
925         while (offset < aop->coff) {
926             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
927             aop->coff--;
928         }
929         
930         aop->coff = offset ;
931         if (aop->paged) {
932             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
933             return (dname ? "acc" : "a");
934         }       
935         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
936         rs = Safe_calloc(1,strlen(s)+1);
937         strcpy(rs,s);   
938         return rs;
939         
940     case AOP_DPTR:
941     case AOP_DPTR2:
942         DEBUGpic14_emitcode(";","%d",__LINE__);
943     if (aop->type == AOP_DPTR2)
944     {
945         genSetDPTR(1);
946     }
947     
948         while (offset > aop->coff) {
949             pic14_emitcode ("inc","dptr");
950             aop->coff++;
951         }
952         
953         while (offset < aop->coff) {        
954             pic14_emitcode("lcall","__decdptr");
955             aop->coff--;
956         }
957         
958         aop->coff = offset;
959         if (aop->code) {
960             pic14_emitcode("clr","a");
961             pic14_emitcode("movc","a,@a+dptr");
962         }
963     else {
964             pic14_emitcode("movx","a,@dptr");
965     }
966             
967     if (aop->type == AOP_DPTR2)
968     {
969         genSetDPTR(0);
970     }
971             
972     return (dname ? "acc" : "a");
973         
974         
975     case AOP_IMMD:
976       DEBUGpic14_emitcode(";","%d",__LINE__);
977         if (bit16) 
978             sprintf (s,"%s",aop->aopu.aop_immd);
979         else
980             if (offset) 
981                 sprintf(s,"(%s >> %d)",
982                         aop->aopu.aop_immd,
983                         offset*8);
984             else
985                 sprintf(s,"%s",
986                         aop->aopu.aop_immd);
987         rs = Safe_calloc(1,strlen(s)+1);
988         strcpy(rs,s);   
989         return rs;
990         
991     case AOP_DIR:
992         if (offset)
993             sprintf(s,"(%s + %d)",
994                     aop->aopu.aop_dir,
995                     offset);
996         else
997             sprintf(s,"%s",aop->aopu.aop_dir);
998         rs = Safe_calloc(1,strlen(s)+1);
999         strcpy(rs,s);   
1000         return rs;
1001         
1002     case AOP_REG:
1003       DEBUGpic14_emitcode(";","%d",__LINE__);
1004         if (dname) 
1005             return aop->aopu.aop_reg[offset]->dname;
1006         else
1007             return aop->aopu.aop_reg[offset]->name;
1008         
1009     case AOP_CRY:
1010       pic14_emitcode(";","%d",__LINE__);
1011       //pic14_emitcode("clr","a");
1012       //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1013       //pic14_emitcode("rlc","a") ;
1014       //return (dname ? "acc" : "a");
1015       return aop->aopu.aop_dir;
1016         
1017     case AOP_ACC:
1018         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1019         //if (!offset && dname)
1020         //    return "acc";
1021         //return aop->aopu.aop_str[offset];
1022         return "AOP_accumulator_bug";
1023
1024     case AOP_LIT:
1025         DEBUGpic14_emitcode(";","%d",__LINE__);
1026         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1027         rs = Safe_calloc(1,strlen(s)+1);
1028         strcpy(rs,s);   
1029         return rs;
1030         
1031     case AOP_STR:
1032         DEBUGpic14_emitcode(";","%d",__LINE__);
1033         aop->coff = offset ;
1034         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1035             dname)
1036             return "acc";
1037         
1038         return aop->aopu.aop_str[offset];
1039         
1040     }
1041
1042     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1043            "aopget got unsupported aop->type");
1044     exit(0);
1045 }
1046
1047 /*-----------------------------------------------------------------*/
1048 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1049 /*-----------------------------------------------------------------*/
1050 pCodeOp *popGetLabel(unsigned int key)
1051 {
1052
1053   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1054
1055   if(key>max_key)
1056     max_key = key;
1057
1058   return newpCodeOpLabel(key+100+labelOffset);
1059 }
1060
1061 /*-----------------------------------------------------------------*/
1062 /* popCopyReg - copy a pcode operator                              */
1063 /*-----------------------------------------------------------------*/
1064 pCodeOp *popCopyReg(pCodeOpReg *pc)
1065 {
1066   pCodeOpReg *pcor;
1067
1068   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1069   pcor->pcop.type = pc->pcop.type;
1070   if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1071     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1072   pcor->r = pc->r;
1073   pcor->rIdx = pc->rIdx;
1074
1075
1076   return PCOP(pcor);
1077 }
1078
1079 /*-----------------------------------------------------------------*/
1080 /* popCopy - copy a pcode operator                                 */
1081 /*-----------------------------------------------------------------*/
1082 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1083 {
1084   pCodeOp *pcop;
1085
1086   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1087   pcop->type = PO_BIT;
1088   if(!(pcop->name = Safe_strdup(pc->name)))
1089     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1090   ((pCodeOpBit *)pcop)->bit = bitval;
1091
1092   ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1093
1094   return pcop;
1095 }
1096
1097 /*-----------------------------------------------------------------*/
1098 /* popGet - asm operator to pcode operator conversion              */
1099 /*-----------------------------------------------------------------*/
1100 pCodeOp *popGetLit(unsigned int lit)
1101 {
1102
1103   return newpCodeOpLit(lit);
1104 }
1105
1106
1107 /*-----------------------------------------------------------------*/
1108 /* popGet - asm operator to pcode operator conversion              */
1109 /*-----------------------------------------------------------------*/
1110 pCodeOp *popGetWithString(char *str)
1111 {
1112   pCodeOp *pcop;
1113
1114
1115   if(!str) {
1116     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1117     exit (1);
1118   }
1119
1120   pcop = newpCodeOp(str,PO_STR);
1121
1122   return pcop;
1123 }
1124
1125 pCodeOp *popRegFromString(char *str)
1126 {
1127
1128   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1129   pcop->type = PO_GPR_REGISTER;
1130
1131   PCOR(pcop)->rIdx = -1;
1132   PCOR(pcop)->r = NULL;
1133
1134   DEBUGpic14_emitcode(";","%d",__LINE__);
1135   pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1136
1137   return pcop;
1138 }
1139
1140 /*-----------------------------------------------------------------*/
1141 /* popGet - asm operator to pcode operator conversion              */
1142 /*-----------------------------------------------------------------*/
1143 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1144 {
1145     char *s = buffer ;
1146     char *rs;
1147
1148     pCodeOp *pcop;
1149
1150     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1151     /* offset is greater than
1152     size then zero */
1153
1154     if (offset > (aop->size - 1) &&
1155         aop->type != AOP_LIT)
1156       return NULL;  //zero;
1157
1158     /* depending on type */
1159     switch (aop->type) {
1160         
1161     case AOP_R0:
1162     case AOP_R1:
1163     case AOP_DPTR:
1164     case AOP_DPTR2:
1165     case AOP_ACC:
1166         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1167         //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1168         //pcop->type = PO_SFR_REGISTER;
1169
1170         //PCOR(pcop)->rIdx = -1;
1171         //PCOR(pcop)->r = NULL;
1172         // Really nasty hack to check for temporary registers
1173
1174         //pcop->name = Safe_strdup("BAD_REGISTER");
1175
1176         return NULL;
1177         
1178     case AOP_IMMD:
1179       DEBUGpic14_emitcode(";","%d",__LINE__);
1180         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1181         pcop->type = PO_IMMEDIATE;
1182         if (bit16) 
1183             sprintf (s,"%s",aop->aopu.aop_immd);
1184         else
1185             if (offset) 
1186                 sprintf(s,"(%s >> %d)",
1187                         aop->aopu.aop_immd,
1188                         offset*8);
1189             else
1190                 sprintf(s,"%s",
1191                         aop->aopu.aop_immd);
1192         pcop->name = Safe_calloc(1,strlen(s)+1);
1193         strcpy(pcop->name,s);   
1194         return pcop;
1195         
1196     case AOP_DIR:
1197         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1198         pcop->type = PO_DIR;
1199         if (offset)
1200             sprintf(s,"(%s + %d)",
1201                     aop->aopu.aop_dir,
1202                     offset);
1203         else
1204             sprintf(s,"%s",aop->aopu.aop_dir);
1205         pcop->name = Safe_calloc(1,strlen(s)+1);
1206         strcpy(pcop->name,s);   
1207         return pcop;
1208         
1209     case AOP_REG:
1210       {
1211         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1212
1213         DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1214         if(bit16)
1215           pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1216         else
1217           pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1218         //pcop->type = PO_GPR_REGISTER;
1219         PCOR(pcop)->rIdx = rIdx;
1220         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1221         pcop->type = PCOR(pcop)->r->pc_type;
1222
1223         if (dname)
1224           rs = aop->aopu.aop_reg[offset]->dname;
1225         else 
1226           rs = aop->aopu.aop_reg[offset]->name;
1227
1228         DEBUGpic14_emitcode(";","%d  %s",__LINE__,rs);
1229
1230         return pcop;
1231       }
1232
1233     case AOP_CRY:
1234       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1235       return pcop;
1236         
1237     case AOP_LIT:
1238       DEBUGpic14_emitcode(";","%d",__LINE__);
1239       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1240
1241     case AOP_STR:
1242       DEBUGpic14_emitcode(";","%d",__LINE__);
1243
1244       pcop = Safe_calloc(1,sizeof(pCodeOp) );
1245       pcop->type = PO_STR;
1246
1247       //aop->coff = offset ;
1248         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1249           sprintf(s,"%s","acc");
1250         else
1251           sprintf(s,"%s",aop->aopu.aop_str[offset]);
1252         pcop->name = Safe_calloc(1,strlen(s)+1);
1253         strcpy(pcop->name,s);   
1254         return pcop;
1255         
1256     }
1257
1258     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1259            "popGet got unsupported aop->type");
1260     exit(0);
1261 }
1262 /*-----------------------------------------------------------------*/
1263 /* aopPut - puts a string for a aop                                */
1264 /*-----------------------------------------------------------------*/
1265 void aopPut (asmop *aop, char *s, int offset)
1266 {
1267     char *d = buffer ;
1268     symbol *lbl ;
1269
1270     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1271
1272     if (aop->size && offset > ( aop->size - 1)) {
1273         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1274                "aopPut got offset > aop->size");
1275         exit(0);
1276     }
1277
1278     /* will assign value to value */
1279     /* depending on where it is ofcourse */
1280     switch (aop->type) {
1281     case AOP_DIR:
1282         if (offset)
1283             sprintf(d,"(%s + %d)",
1284                     aop->aopu.aop_dir,offset);
1285         else
1286             sprintf(d,"%s",aop->aopu.aop_dir);
1287         
1288         if (strcmp(d,s)) {
1289           DEBUGpic14_emitcode(";","%d",__LINE__);
1290           if(strcmp(s,"W"))
1291             pic14_emitcode("movf","%s,w",s);
1292           pic14_emitcode("movwf","%s",d);
1293
1294           if(strcmp(s,"W"))
1295             pic14_emitcode(";BUG! should have this:movf","%s,w   %d",s,__LINE__);
1296           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1297
1298
1299         }
1300         break;
1301         
1302     case AOP_REG:
1303         if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1304             strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1305           /*
1306             if (*s == '@'           ||
1307                 strcmp(s,"r0") == 0 ||
1308                 strcmp(s,"r1") == 0 ||
1309                 strcmp(s,"r2") == 0 ||
1310                 strcmp(s,"r3") == 0 ||
1311                 strcmp(s,"r4") == 0 ||
1312                 strcmp(s,"r5") == 0 ||
1313                 strcmp(s,"r6") == 0 || 
1314                 strcmp(s,"r7") == 0 )
1315                 pic14_emitcode("mov","%s,%s  ; %d",
1316                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1317             else
1318           */
1319
1320           if(strcmp(s,"W"))
1321             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1322
1323           pic14_emitcode("movwf","%s",
1324                    aop->aopu.aop_reg[offset]->name);
1325
1326           if(strcmp(s,"W")) {
1327             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1328             pcop->type = PO_GPR_REGISTER;
1329
1330             PCOR(pcop)->rIdx = -1;
1331             PCOR(pcop)->r = NULL;
1332
1333             DEBUGpic14_emitcode(";","%d",__LINE__);
1334             pcop->name = Safe_strdup(s);
1335             emitpcode(POC_MOVFW,pcop);
1336           }
1337           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1338
1339         }
1340         break;
1341         
1342     case AOP_DPTR:
1343     case AOP_DPTR2:
1344     
1345     if (aop->type == AOP_DPTR2)
1346     {
1347         genSetDPTR(1);
1348     }
1349     
1350         if (aop->code) {
1351             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1352                    "aopPut writting to code space");
1353             exit(0);
1354         }
1355         
1356         while (offset > aop->coff) {
1357             aop->coff++;
1358             pic14_emitcode ("inc","dptr");
1359         }
1360         
1361         while (offset < aop->coff) {
1362             aop->coff-- ;
1363             pic14_emitcode("lcall","__decdptr");
1364         }
1365         
1366         aop->coff = offset;
1367         
1368         /* if not in accumulater */
1369         MOVA(s);        
1370         
1371         pic14_emitcode ("movx","@dptr,a");
1372         
1373     if (aop->type == AOP_DPTR2)
1374     {
1375         genSetDPTR(0);
1376     }
1377         break;
1378         
1379     case AOP_R0:
1380     case AOP_R1:
1381         while (offset > aop->coff) {
1382             aop->coff++;
1383             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1384         }
1385         while (offset < aop->coff) {
1386             aop->coff-- ;
1387             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1388         }
1389         aop->coff = offset;
1390         
1391         if (aop->paged) {
1392             MOVA(s);           
1393             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1394             
1395         } else
1396             if (*s == '@') {
1397                 MOVA(s);
1398                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1399             } else
1400                 if (strcmp(s,"r0") == 0 ||
1401                     strcmp(s,"r1") == 0 ||
1402                     strcmp(s,"r2") == 0 ||
1403                     strcmp(s,"r3") == 0 ||
1404                     strcmp(s,"r4") == 0 ||
1405                     strcmp(s,"r5") == 0 ||
1406                     strcmp(s,"r6") == 0 || 
1407                     strcmp(s,"r7") == 0 ) {
1408                     char buffer[10];
1409                     sprintf(buffer,"a%s",s);
1410                     pic14_emitcode("mov","@%s,%s",
1411                              aop->aopu.aop_ptr->name,buffer);
1412                 } else
1413                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1414         
1415         break;
1416         
1417     case AOP_STK:
1418         if (strcmp(s,"a") == 0)
1419             pic14_emitcode("push","acc");
1420         else
1421             pic14_emitcode("push","%s",s);
1422         
1423         break;
1424         
1425     case AOP_CRY:
1426         /* if bit variable */
1427         if (!aop->aopu.aop_dir) {
1428             pic14_emitcode("clr","a");
1429             pic14_emitcode("rlc","a");
1430         } else {
1431             if (s == zero) 
1432                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1433             else
1434                 if (s == one)
1435                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1436                 else
1437                     if (!strcmp(s,"c"))
1438                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1439                     else {
1440                         lbl = newiTempLabel(NULL);
1441                         
1442                         if (strcmp(s,"a")) {
1443                             MOVA(s);
1444                         }
1445                         pic14_emitcode("clr","c");
1446                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1447                         pic14_emitcode("cpl","c");
1448                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1449                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1450                     }
1451         }
1452         break;
1453         
1454     case AOP_STR:
1455         aop->coff = offset;
1456         if (strcmp(aop->aopu.aop_str[offset],s))
1457             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1458         break;
1459         
1460     case AOP_ACC:
1461         aop->coff = offset;
1462         if (!offset && (strcmp(s,"acc") == 0))
1463             break;
1464         
1465         if (strcmp(aop->aopu.aop_str[offset],s))
1466             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1467         break;
1468
1469     default :
1470         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1471                "aopPut got unsupported aop->type");
1472         exit(0);    
1473     }    
1474
1475 }
1476
1477 /*-----------------------------------------------------------------*/
1478 /* reAdjustPreg - points a register back to where it should        */
1479 /*-----------------------------------------------------------------*/
1480 static void reAdjustPreg (asmop *aop)
1481 {
1482     int size ;
1483
1484     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1485     aop->coff = 0;
1486     if ((size = aop->size) <= 1)
1487         return ;
1488     size-- ;
1489     switch (aop->type) {
1490         case AOP_R0 :
1491         case AOP_R1 :
1492             while (size--)
1493                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1494             break;          
1495         case AOP_DPTR :
1496         case AOP_DPTR2:
1497             if (aop->type == AOP_DPTR2)
1498             {
1499                 genSetDPTR(1);
1500             } 
1501             while (size--)
1502             {
1503                 pic14_emitcode("lcall","__decdptr");
1504             }
1505                 
1506             if (aop->type == AOP_DPTR2)
1507             {
1508                 genSetDPTR(0);
1509             }                
1510             break;  
1511
1512     }   
1513
1514 }
1515
1516 /*-----------------------------------------------------------------*/
1517 /* genNotFloat - generates not for float operations              */
1518 /*-----------------------------------------------------------------*/
1519 static void genNotFloat (operand *op, operand *res)
1520 {
1521     int size, offset;
1522     char *l;
1523     symbol *tlbl ;
1524
1525     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1526     /* we will put 127 in the first byte of 
1527     the result */
1528     aopPut(AOP(res),"#127",0);
1529     size = AOP_SIZE(op) - 1;
1530     offset = 1;
1531
1532     l = aopGet(op->aop,offset++,FALSE,FALSE);
1533     MOVA(l);    
1534
1535     while(size--) {
1536         pic14_emitcode("orl","a,%s",
1537                  aopGet(op->aop,
1538                         offset++,FALSE,FALSE));
1539     }
1540     tlbl = newiTempLabel(NULL);
1541
1542     tlbl = newiTempLabel(NULL);
1543     aopPut(res->aop,one,1);
1544     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1545     aopPut(res->aop,zero,1);
1546     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1547
1548     size = res->aop->size - 2;
1549     offset = 2;    
1550     /* put zeros in the rest */
1551     while (size--) 
1552         aopPut(res->aop,zero,offset++);
1553 }
1554
1555 #if 0
1556 /*-----------------------------------------------------------------*/
1557 /* opIsGptr: returns non-zero if the passed operand is             */   
1558 /* a generic pointer type.                                         */
1559 /*-----------------------------------------------------------------*/ 
1560 static int opIsGptr(operand *op)
1561 {
1562     sym_link *type = operandType(op);
1563     
1564     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1565     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1566     {
1567         return 1;
1568     }
1569     return 0;        
1570 }
1571 #endif
1572
1573 /*-----------------------------------------------------------------*/
1574 /* pic14_getDataSize - get the operand data size                         */
1575 /*-----------------------------------------------------------------*/
1576 int pic14_getDataSize(operand *op)
1577 {
1578     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1579
1580
1581     return AOP_SIZE(op);
1582
1583     // tsd- in the pic port, the genptr size is 1, so this code here
1584     // fails. ( in the 8051 port, the size was 4).
1585 #if 0
1586     int size;
1587     size = AOP_SIZE(op);
1588     if (size == GPTRSIZE)
1589     {
1590         sym_link *type = operandType(op);
1591         if (IS_GENPTR(type))
1592         {
1593             /* generic pointer; arithmetic operations
1594              * should ignore the high byte (pointer type).
1595              */
1596             size--;
1597     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1598         }
1599     }
1600     return size;
1601 #endif
1602 }
1603
1604 /*-----------------------------------------------------------------*/
1605 /* pic14_outAcc - output Acc                                             */
1606 /*-----------------------------------------------------------------*/
1607 void pic14_outAcc(operand *result)
1608 {
1609
1610     DEBUGpic14_emitcode ("; ***","%s  %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1611
1612 #if 0
1613     size = pic14_getDataSize(result);
1614     if(size){
1615         aopPut(AOP(result),"a",0);
1616         size--;
1617         offset = 1;
1618         /* unsigned or positive */
1619         while(size--){
1620             aopPut(AOP(result),zero,offset++);
1621         }
1622     }
1623 #endif
1624 }
1625
1626 /*-----------------------------------------------------------------*/
1627 /* pic14_outBitC - output a bit C                                        */
1628 /*-----------------------------------------------------------------*/
1629 void pic14_outBitC(operand *result)
1630 {
1631
1632     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1633     /* if the result is bit */
1634     if (AOP_TYPE(result) == AOP_CRY) 
1635         aopPut(AOP(result),"c",0);
1636     else {
1637         pic14_emitcode("clr","a  ; %d", __LINE__);
1638         pic14_emitcode("rlc","a");
1639         pic14_outAcc(result);
1640     }
1641 }
1642
1643 /*-----------------------------------------------------------------*/
1644 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1645 /*-----------------------------------------------------------------*/
1646 void pic14_toBoolean(operand *oper)
1647 {
1648     int size = AOP_SIZE(oper) - 1;
1649     int offset = 1;
1650
1651     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1652
1653     if ( AOP_TYPE(oper) != AOP_ACC) {
1654       emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1655       pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1656     }
1657     while (size--) {
1658       pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1659       emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1660     }
1661 }
1662
1663
1664 /*-----------------------------------------------------------------*/
1665 /* genNot - generate code for ! operation                          */
1666 /*-----------------------------------------------------------------*/
1667 static void genNot (iCode *ic)
1668 {
1669     symbol *tlbl;
1670     sym_link *optype = operandType(IC_LEFT(ic));
1671
1672     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1673     /* assign asmOps to operand & result */
1674     aopOp (IC_LEFT(ic),ic,FALSE);
1675     aopOp (IC_RESULT(ic),ic,TRUE);
1676
1677     /* if in bit space then a special case */
1678     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1679       pic14_emitcode("movlw","1<<%s");
1680       //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1681       //pic14_emitcode("cpl","c"); 
1682       //pic14_outBitC(IC_RESULT(ic));
1683       goto release;
1684     }
1685
1686     /* if type float then do float */
1687     if (IS_FLOAT(optype)) {
1688         genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1689         goto release;
1690     }
1691
1692     pic14_toBoolean(IC_LEFT(ic));
1693
1694     tlbl = newiTempLabel(NULL);
1695     pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1696     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1697     pic14_outBitC(IC_RESULT(ic));
1698
1699 release:    
1700     /* release the aops */
1701     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1702     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1703 }
1704
1705
1706 /*-----------------------------------------------------------------*/
1707 /* genCpl - generate code for complement                           */
1708 /*-----------------------------------------------------------------*/
1709 static void genCpl (iCode *ic)
1710 {
1711     int offset = 0;
1712     int size ;
1713
1714
1715     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1716     /* assign asmOps to operand & result */
1717     aopOp (IC_LEFT(ic),ic,FALSE);
1718     aopOp (IC_RESULT(ic),ic,TRUE);
1719
1720     /* if both are in bit space then 
1721     a special case */
1722     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1723         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1724
1725         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1726         pic14_emitcode("cpl","c"); 
1727         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1728         goto release; 
1729     } 
1730
1731     size = AOP_SIZE(IC_RESULT(ic));
1732     while (size--) {
1733         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1734         MOVA(l);       
1735         pic14_emitcode("cpl","a");
1736         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1737     }
1738
1739
1740 release:
1741     /* release the aops */
1742     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1743     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1744 }
1745
1746 /*-----------------------------------------------------------------*/
1747 /* genUminusFloat - unary minus for floating points                */
1748 /*-----------------------------------------------------------------*/
1749 static void genUminusFloat(operand *op,operand *result)
1750 {
1751     int size ,offset =0 ;
1752     char *l;
1753
1754     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1755     /* for this we just need to flip the 
1756     first it then copy the rest in place */
1757     size = AOP_SIZE(op) - 1;
1758     l = aopGet(AOP(op),3,FALSE,FALSE);
1759
1760     MOVA(l);    
1761
1762     pic14_emitcode("cpl","acc.7");
1763     aopPut(AOP(result),"a",3);    
1764
1765     while(size--) {
1766         aopPut(AOP(result),
1767                aopGet(AOP(op),offset,FALSE,FALSE),
1768                offset);
1769         offset++;
1770     }          
1771 }
1772
1773 /*-----------------------------------------------------------------*/
1774 /* genUminus - unary minus code generation                         */
1775 /*-----------------------------------------------------------------*/
1776 static void genUminus (iCode *ic)
1777 {
1778     int offset ,size ;
1779     sym_link *optype, *rtype;
1780
1781
1782     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1783     /* assign asmops */
1784     aopOp(IC_LEFT(ic),ic,FALSE);
1785     aopOp(IC_RESULT(ic),ic,TRUE);
1786
1787     /* if both in bit space then special
1788     case */
1789     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1790         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1791
1792         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1793         pic14_emitcode("cpl","c"); 
1794         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1795         goto release; 
1796     } 
1797
1798     optype = operandType(IC_LEFT(ic));
1799     rtype = operandType(IC_RESULT(ic));
1800
1801     /* if float then do float stuff */
1802     if (IS_FLOAT(optype)) {
1803         genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1804         goto release;
1805     }
1806
1807     /* otherwise subtract from zero */
1808     size = AOP_SIZE(IC_LEFT(ic));
1809     offset = 0 ;
1810     CLRC ;
1811     while(size--) {
1812         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1813         if (!strcmp(l,"a")) {
1814             pic14_emitcode("cpl","a");
1815             pic14_emitcode("inc","a");
1816         } else {
1817             pic14_emitcode("clr","a");
1818             pic14_emitcode("subb","a,%s",l);
1819         }       
1820         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1821     }
1822
1823     /* if any remaining bytes in the result */
1824     /* we just need to propagate the sign   */
1825     if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1826         pic14_emitcode("rlc","a");
1827         pic14_emitcode("subb","a,acc");
1828         while (size--) 
1829             aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1830     }       
1831
1832 release:
1833     /* release the aops */
1834     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1835     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1836 }
1837
1838 /*-----------------------------------------------------------------*/
1839 /* saveRegisters - will look for a call and save the registers     */
1840 /*-----------------------------------------------------------------*/
1841 static void saveRegisters(iCode *lic) 
1842 {
1843     int i;
1844     iCode *ic;
1845     bitVect *rsave;
1846     sym_link *dtype;
1847
1848     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1849     /* look for call */
1850     for (ic = lic ; ic ; ic = ic->next) 
1851         if (ic->op == CALL || ic->op == PCALL)
1852             break;
1853
1854     if (!ic) {
1855         fprintf(stderr,"found parameter push with no function call\n");
1856         return ;
1857     }
1858
1859     /* if the registers have been saved already then
1860     do nothing */
1861     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1862         return ;
1863
1864     /* find the registers in use at this time 
1865     and push them away to safety */
1866     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1867                           ic->rUsed);
1868
1869     ic->regsSaved = 1;
1870     if (options.useXstack) {
1871         if (bitVectBitValue(rsave,R0_IDX))
1872             pic14_emitcode("mov","b,r0");
1873         pic14_emitcode("mov","r0,%s",spname);
1874         for (i = 0 ; i < pic14_nRegs ; i++) {
1875             if (bitVectBitValue(rsave,i)) {
1876                 if (i == R0_IDX)
1877                     pic14_emitcode("mov","a,b");
1878                 else
1879                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1880                 pic14_emitcode("movx","@r0,a");
1881                 pic14_emitcode("inc","r0");
1882             }
1883         }
1884         pic14_emitcode("mov","%s,r0",spname);
1885         if (bitVectBitValue(rsave,R0_IDX))
1886             pic14_emitcode("mov","r0,b");           
1887     } else
1888         for (i = 0 ; i < pic14_nRegs ; i++) {
1889             if (bitVectBitValue(rsave,i))
1890                 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1891         }
1892
1893     dtype = operandType(IC_LEFT(ic));
1894     if (dtype        && 
1895         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1896         IFFUNC_ISISR(currFunc->type) &&
1897         !ic->bankSaved) 
1898
1899         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1900
1901 }
1902 /*-----------------------------------------------------------------*/
1903 /* unsaveRegisters - pop the pushed registers                      */
1904 /*-----------------------------------------------------------------*/
1905 static void unsaveRegisters (iCode *ic)
1906 {
1907     int i;
1908     bitVect *rsave;
1909
1910     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1911     /* find the registers in use at this time 
1912     and push them away to safety */
1913     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1914                           ic->rUsed);
1915     
1916     if (options.useXstack) {
1917         pic14_emitcode("mov","r0,%s",spname);   
1918         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1919             if (bitVectBitValue(rsave,i)) {
1920                 pic14_emitcode("dec","r0");
1921                 pic14_emitcode("movx","a,@r0");
1922                 if (i == R0_IDX)
1923                     pic14_emitcode("mov","b,a");
1924                 else
1925                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1926             }       
1927
1928         }
1929         pic14_emitcode("mov","%s,r0",spname);
1930         if (bitVectBitValue(rsave,R0_IDX))
1931             pic14_emitcode("mov","r0,b");
1932     } else
1933         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1934             if (bitVectBitValue(rsave,i))
1935                 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1936         }
1937
1938 }  
1939
1940
1941 /*-----------------------------------------------------------------*/
1942 /* pushSide -                                                      */
1943 /*-----------------------------------------------------------------*/
1944 static void pushSide(operand * oper, int size)
1945 {
1946         int offset = 0;
1947     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1948         while (size--) {
1949                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1950                 if (AOP_TYPE(oper) != AOP_REG &&
1951                     AOP_TYPE(oper) != AOP_DIR &&
1952                     strcmp(l,"a") ) {
1953                         pic14_emitcode("mov","a,%s",l);
1954                         pic14_emitcode("push","acc");
1955                 } else
1956                         pic14_emitcode("push","%s",l);
1957         }
1958 }
1959
1960 /*-----------------------------------------------------------------*/
1961 /* assignResultValue -                                             */
1962 /*-----------------------------------------------------------------*/
1963 static void assignResultValue(operand * oper)
1964 {
1965         int offset = 0;
1966         int size = AOP_SIZE(oper);
1967
1968     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1969
1970     // The last byte in the assignment is in W
1971     aopPut(AOP(oper),"W",size-1);
1972
1973     if(size>1) {
1974       while (--size) {
1975         aopPut(AOP(oper),fReturn[offset],offset);
1976         offset++;
1977
1978       }
1979     }
1980 }
1981
1982
1983 /*-----------------------------------------------------------------*/
1984 /* genXpush - pushes onto the external stack                       */
1985 /*-----------------------------------------------------------------*/
1986 static void genXpush (iCode *ic)
1987 {
1988     asmop *aop = newAsmop(0);
1989     regs *r ;
1990     int size,offset = 0;
1991
1992     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1993     aopOp(IC_LEFT(ic),ic,FALSE);
1994     r = getFreePtr(ic,&aop,FALSE);
1995
1996     
1997     pic14_emitcode("mov","%s,_spx",r->name);
1998
1999     size = AOP_SIZE(IC_LEFT(ic));
2000     while(size--) {
2001
2002         char *l = aopGet(AOP(IC_LEFT(ic)),
2003                          offset++,FALSE,FALSE); 
2004         MOVA(l);            
2005         pic14_emitcode("movx","@%s,a",r->name); 
2006         pic14_emitcode("inc","%s",r->name);
2007
2008     }
2009
2010         
2011     pic14_emitcode("mov","_spx,%s",r->name);
2012
2013     freeAsmop(NULL,aop,ic,TRUE);
2014     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2015 }
2016
2017 /*-----------------------------------------------------------------*/
2018 /* genIpush - genrate code for pushing this gets a little complex  */
2019 /*-----------------------------------------------------------------*/
2020 static void genIpush (iCode *ic)
2021 {
2022     int size, offset = 0 ;
2023     char *l;
2024
2025
2026     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2027     /* if this is not a parm push : ie. it is spill push 
2028     and spill push is always done on the local stack */
2029     if (!ic->parmPush) {
2030
2031         /* and the item is spilt then do nothing */
2032         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2033             return ;
2034
2035         aopOp(IC_LEFT(ic),ic,FALSE);
2036         size = AOP_SIZE(IC_LEFT(ic));
2037         /* push it on the stack */
2038         while(size--) {
2039             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2040             if (*l == '#') {
2041                 MOVA(l);
2042                 l = "acc";
2043             }
2044             pic14_emitcode("push","%s",l);
2045         }
2046         return ;        
2047     }
2048
2049     /* this is a paramter push: in this case we call
2050     the routine to find the call and save those
2051     registers that need to be saved */   
2052     saveRegisters(ic);
2053
2054     /* if use external stack then call the external
2055     stack pushing routine */
2056     if (options.useXstack) {
2057         genXpush(ic);
2058         return ;
2059     }
2060
2061     /* then do the push */
2062     aopOp(IC_LEFT(ic),ic,FALSE);
2063
2064
2065         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2066     size = AOP_SIZE(IC_LEFT(ic));
2067
2068     while (size--) {
2069         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2070         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2071             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2072             strcmp(l,"a") ) {
2073             pic14_emitcode("mov","a,%s",l);
2074             pic14_emitcode("push","acc");
2075         } else
2076             pic14_emitcode("push","%s",l);
2077     }       
2078
2079     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2080 }
2081
2082 /*-----------------------------------------------------------------*/
2083 /* genIpop - recover the registers: can happen only for spilling   */
2084 /*-----------------------------------------------------------------*/
2085 static void genIpop (iCode *ic)
2086 {
2087     int size,offset ;
2088
2089
2090     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2091     /* if the temp was not pushed then */
2092     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2093         return ;
2094
2095     aopOp(IC_LEFT(ic),ic,FALSE);
2096     size = AOP_SIZE(IC_LEFT(ic));
2097     offset = (size-1);
2098     while (size--) 
2099         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2100                                    FALSE,TRUE));
2101
2102     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2103 }
2104
2105 /*-----------------------------------------------------------------*/
2106 /* unsaverbank - restores the resgister bank from stack            */
2107 /*-----------------------------------------------------------------*/
2108 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2109 {
2110     int i;
2111     asmop *aop ;
2112     regs *r = NULL;
2113
2114     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2115     if (popPsw) {
2116         if (options.useXstack) {
2117             aop = newAsmop(0);
2118             r = getFreePtr(ic,&aop,FALSE);
2119             
2120             
2121             pic14_emitcode("mov","%s,_spx",r->name);
2122             pic14_emitcode("movx","a,@%s",r->name);
2123             pic14_emitcode("mov","psw,a");
2124             pic14_emitcode("dec","%s",r->name);
2125             
2126         }else
2127             pic14_emitcode ("pop","psw");
2128     }
2129
2130     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2131         if (options.useXstack) {       
2132             pic14_emitcode("movx","a,@%s",r->name);
2133             //pic14_emitcode("mov","(%s+%d),a",
2134             //       regspic14[i].base,8*bank+regspic14[i].offset);
2135             pic14_emitcode("dec","%s",r->name);
2136
2137         } else 
2138           pic14_emitcode("pop",""); //"(%s+%d)",
2139         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2140     }
2141
2142     if (options.useXstack) {
2143
2144         pic14_emitcode("mov","_spx,%s",r->name);
2145         freeAsmop(NULL,aop,ic,TRUE);
2146
2147     } 
2148 }
2149
2150 /*-----------------------------------------------------------------*/
2151 /* saverbank - saves an entire register bank on the stack          */
2152 /*-----------------------------------------------------------------*/
2153 static void saverbank (int bank, iCode *ic, bool pushPsw)
2154 {
2155     int i;
2156     asmop *aop ;
2157     regs *r = NULL;
2158
2159     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2160     if (options.useXstack) {
2161
2162         aop = newAsmop(0);
2163         r = getFreePtr(ic,&aop,FALSE);  
2164         pic14_emitcode("mov","%s,_spx",r->name);
2165
2166     }
2167
2168     for (i = 0 ; i < pic14_nRegs ;i++) {
2169         if (options.useXstack) {
2170             pic14_emitcode("inc","%s",r->name);
2171             //pic14_emitcode("mov","a,(%s+%d)",
2172             //         regspic14[i].base,8*bank+regspic14[i].offset);
2173             pic14_emitcode("movx","@%s,a",r->name);           
2174         } else 
2175           pic14_emitcode("push","");// "(%s+%d)",
2176                      //regspic14[i].base,8*bank+regspic14[i].offset);
2177     }
2178     
2179     if (pushPsw) {
2180         if (options.useXstack) {
2181             pic14_emitcode("mov","a,psw");
2182             pic14_emitcode("movx","@%s,a",r->name);     
2183             pic14_emitcode("inc","%s",r->name);
2184             pic14_emitcode("mov","_spx,%s",r->name);       
2185             freeAsmop (NULL,aop,ic,TRUE);
2186             
2187         } else
2188             pic14_emitcode("push","psw");
2189         
2190         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2191     }
2192     ic->bankSaved = 1;
2193
2194 }
2195
2196 /*-----------------------------------------------------------------*/
2197 /* genCall - generates a call statement                            */
2198 /*-----------------------------------------------------------------*/
2199 static void genCall (iCode *ic)
2200 {
2201     sym_link *dtype;   
2202
2203     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2204
2205     /* if caller saves & we have not saved then */
2206     if (!ic->regsSaved)
2207         saveRegisters(ic);
2208
2209     /* if we are calling a function that is not using
2210     the same register bank then we need to save the
2211     destination registers on the stack */
2212     dtype = operandType(IC_LEFT(ic));
2213     if (dtype        && 
2214         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2215         IFFUNC_ISISR(currFunc->type) &&
2216         !ic->bankSaved) 
2217
2218         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2219
2220     /* if send set is not empty the assign */
2221     if (_G.sendSet) {
2222         iCode *sic ;
2223
2224         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2225              sic = setNextItem(_G.sendSet)) {
2226             int size, offset = 0;
2227
2228             aopOp(IC_LEFT(sic),sic,FALSE);
2229             size = AOP_SIZE(IC_LEFT(sic));
2230             while (size--) {
2231                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2232                                 FALSE,FALSE);
2233                 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2234
2235                 if (strcmp(l,fReturn[offset])) {
2236
2237                   if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2238                        ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2239                     emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2240                   //pic14_emitcode("movlw","%s",l);
2241                   else
2242                     emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2243                   //pic14_emitcode("movf","%s,w",l);
2244
2245                   // The last one is passed in W
2246                   if(size)
2247                     pic14_emitcode("movwf","%s",fReturn[offset]);
2248                 }
2249                 offset++;
2250             }
2251             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2252         }
2253         _G.sendSet = NULL;
2254     }
2255     /* make the call */
2256     emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2257                                         OP_SYMBOL(IC_LEFT(ic))->rname :
2258                                         OP_SYMBOL(IC_LEFT(ic))->name));
2259
2260     pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2261                            OP_SYMBOL(IC_LEFT(ic))->rname :
2262                            OP_SYMBOL(IC_LEFT(ic))->name));
2263
2264     /* if we need assign a result value */
2265     if ((IS_ITEMP(IC_RESULT(ic)) && 
2266          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2267           OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2268         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2269
2270         _G.accInUse++;
2271         aopOp(IC_RESULT(ic),ic,FALSE);
2272         _G.accInUse--;
2273
2274         assignResultValue(IC_RESULT(ic));
2275                 
2276         freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2277     }
2278
2279     /* adjust the stack for parameters if 
2280     required */
2281     if (ic->parmBytes) {
2282         int i;
2283         if (ic->parmBytes > 3) {
2284             pic14_emitcode("mov","a,%s",spname);
2285             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2286             pic14_emitcode("mov","%s,a",spname);
2287         } else 
2288             for ( i = 0 ; i <  ic->parmBytes ;i++)
2289                 pic14_emitcode("dec","%s",spname);
2290
2291     }
2292
2293     /* if register bank was saved then pop them */
2294     if (ic->bankSaved)
2295         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2296
2297     /* if we hade saved some registers then unsave them */
2298     if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2299         unsaveRegisters (ic);
2300
2301
2302 }
2303
2304 /*-----------------------------------------------------------------*/
2305 /* genPcall - generates a call by pointer statement                */
2306 /*-----------------------------------------------------------------*/
2307 static void genPcall (iCode *ic)
2308 {
2309     sym_link *dtype;
2310     symbol *rlbl = newiTempLabel(NULL);
2311
2312
2313     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2314     /* if caller saves & we have not saved then */
2315     if (!ic->regsSaved)
2316         saveRegisters(ic);
2317
2318     /* if we are calling a function that is not using
2319     the same register bank then we need to save the
2320     destination registers on the stack */
2321     dtype = operandType(IC_LEFT(ic));
2322     if (dtype        && 
2323         IFFUNC_ISISR(currFunc->type) &&
2324         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2325         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2326
2327
2328     /* push the return address on to the stack */
2329     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2330     pic14_emitcode("push","acc");    
2331     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2332     pic14_emitcode("push","acc");
2333     
2334     if (options.model == MODEL_FLAT24)
2335     {
2336         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2337         pic14_emitcode("push","acc");    
2338     }
2339
2340     /* now push the calling address */
2341     aopOp(IC_LEFT(ic),ic,FALSE);
2342
2343     pushSide(IC_LEFT(ic), FPTRSIZE);
2344
2345     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2346
2347     /* if send set is not empty the assign */
2348     if (_G.sendSet) {
2349         iCode *sic ;
2350
2351         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2352              sic = setNextItem(_G.sendSet)) {
2353             int size, offset = 0;
2354             aopOp(IC_LEFT(sic),sic,FALSE);
2355             size = AOP_SIZE(IC_LEFT(sic));
2356             while (size--) {
2357                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2358                                 FALSE,FALSE);
2359                 if (strcmp(l,fReturn[offset]))
2360                     pic14_emitcode("mov","%s,%s",
2361                              fReturn[offset],
2362                              l);
2363                 offset++;
2364             }
2365             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2366         }
2367         _G.sendSet = NULL;
2368     }
2369
2370     pic14_emitcode("ret","");
2371     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2372
2373
2374     /* if we need assign a result value */
2375     if ((IS_ITEMP(IC_RESULT(ic)) &&
2376          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2377           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2378         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2379
2380         _G.accInUse++;
2381         aopOp(IC_RESULT(ic),ic,FALSE);
2382         _G.accInUse--;
2383         
2384         assignResultValue(IC_RESULT(ic));
2385
2386         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2387     }
2388
2389     /* adjust the stack for parameters if 
2390     required */
2391     if (ic->parmBytes) {
2392         int i;
2393         if (ic->parmBytes > 3) {
2394             pic14_emitcode("mov","a,%s",spname);
2395             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2396             pic14_emitcode("mov","%s,a",spname);
2397         } else 
2398             for ( i = 0 ; i <  ic->parmBytes ;i++)
2399                 pic14_emitcode("dec","%s",spname);
2400
2401     }
2402
2403     /* if register bank was saved then unsave them */
2404     if (dtype        && 
2405         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2406         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2407
2408     /* if we hade saved some registers then
2409     unsave them */
2410     if (ic->regsSaved)
2411         unsaveRegisters (ic);
2412
2413 }
2414
2415 /*-----------------------------------------------------------------*/
2416 /* resultRemat - result  is rematerializable                       */
2417 /*-----------------------------------------------------------------*/
2418 static int resultRemat (iCode *ic)
2419 {
2420     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2421     if (SKIP_IC(ic) || ic->op == IFX)
2422         return 0;
2423
2424     if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2425         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2426         if (sym->remat && !POINTER_SET(ic)) 
2427             return 1;
2428     }
2429
2430     return 0;
2431 }
2432
2433 #if defined(__BORLANDC__) || defined(_MSC_VER)
2434 #define STRCASECMP stricmp
2435 #else
2436 #define STRCASECMP strcasecmp
2437 #endif
2438
2439 /*-----------------------------------------------------------------*/
2440 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2441 /*-----------------------------------------------------------------*/
2442 static bool inExcludeList(char *s)
2443 {
2444     int i =0;
2445     
2446     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2447     if (options.excludeRegs[i] &&
2448     STRCASECMP(options.excludeRegs[i],"none") == 0)
2449         return FALSE ;
2450
2451     for ( i = 0 ; options.excludeRegs[i]; i++) {
2452         if (options.excludeRegs[i] &&
2453         STRCASECMP(s,options.excludeRegs[i]) == 0)
2454             return TRUE;
2455     }
2456     return FALSE ;
2457 }
2458
2459 /*-----------------------------------------------------------------*/
2460 /* genFunction - generated code for function entry                 */
2461 /*-----------------------------------------------------------------*/
2462 static void genFunction (iCode *ic)
2463 {
2464     symbol *sym;
2465     sym_link *ftype;
2466
2467     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2468
2469     labelOffset += (max_key+4);
2470     max_key=0;
2471
2472     _G.nRegsSaved = 0;
2473     /* create the function header */
2474     pic14_emitcode(";","-----------------------------------------");
2475     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2476     pic14_emitcode(";","-----------------------------------------");
2477
2478     pic14_emitcode("","%s:",sym->rname);
2479     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2480
2481     ftype = operandType(IC_LEFT(ic));
2482
2483     /* if critical function then turn interrupts off */
2484     if (IFFUNC_ISCRITICAL(ftype))
2485         pic14_emitcode("clr","ea");
2486
2487     /* here we need to generate the equates for the
2488        register bank if required */
2489 #if 0
2490     if (FUNC_REGBANK(ftype) != rbank) {
2491         int i ;
2492
2493         rbank = FUNC_REGBANK(ftype);
2494         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2495             if (strcmp(regspic14[i].base,"0") == 0)
2496                 pic14_emitcode("","%s = 0x%02x",
2497                          regspic14[i].dname,
2498                          8*rbank+regspic14[i].offset);
2499             else
2500                 pic14_emitcode ("","%s = %s + 0x%02x",
2501                           regspic14[i].dname,
2502                           regspic14[i].base,
2503                           8*rbank+regspic14[i].offset);
2504         }
2505     }
2506 #endif
2507
2508     /* if this is an interrupt service routine then
2509     save acc, b, dpl, dph  */
2510     if (IFFUNC_ISISR(sym->type)) {
2511         
2512         if (!inExcludeList("acc"))          
2513             pic14_emitcode ("push","acc");      
2514         if (!inExcludeList("b"))
2515             pic14_emitcode ("push","b");
2516         if (!inExcludeList("dpl"))
2517             pic14_emitcode ("push","dpl");
2518         if (!inExcludeList("dph"))
2519             pic14_emitcode ("push","dph");
2520         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2521         {
2522             pic14_emitcode ("push", "dpx");
2523             /* Make sure we're using standard DPTR */
2524             pic14_emitcode ("push", "dps");
2525             pic14_emitcode ("mov", "dps, #0x00");
2526             if (options.stack10bit)
2527             {   
2528                 /* This ISR could conceivably use DPTR2. Better save it. */
2529                 pic14_emitcode ("push", "dpl1");
2530                 pic14_emitcode ("push", "dph1");
2531                 pic14_emitcode ("push", "dpx1");
2532             }
2533         }
2534         /* if this isr has no bank i.e. is going to
2535            run with bank 0 , then we need to save more
2536            registers :-) */
2537         if (!FUNC_REGBANK(sym->type)) {
2538
2539             /* if this function does not call any other
2540                function then we can be economical and
2541                save only those registers that are used */
2542             if (! IFFUNC_HASFCALL(sym->type)) {
2543                 int i;
2544
2545                 /* if any registers used */
2546                 if (sym->regsUsed) {
2547                     /* save the registers used */
2548                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2549                         if (bitVectBitValue(sym->regsUsed,i) ||
2550                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2551                             pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);                         
2552                     }
2553                 }
2554                 
2555             } else {
2556                 /* this function has  a function call cannot
2557                    determines register usage so we will have the
2558                    entire bank */
2559                 saverbank(0,ic,FALSE);
2560             }       
2561         }
2562     } else {
2563         /* if callee-save to be used for this function
2564            then save the registers being used in this function */
2565         if (IFFUNC_CALLEESAVES(sym->type)) {
2566             int i;
2567             
2568             /* if any registers used */
2569             if (sym->regsUsed) {
2570                 /* save the registers used */
2571                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2572                     if (bitVectBitValue(sym->regsUsed,i) ||
2573                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2574                         pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2575                         _G.nRegsSaved++;
2576                     }
2577                 }
2578             }
2579         }
2580     }
2581
2582     /* set the register bank to the desired value */
2583     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2584         pic14_emitcode("push","psw");
2585         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2586     }
2587
2588     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2589
2590         if (options.useXstack) {
2591             pic14_emitcode("mov","r0,%s",spname);
2592             pic14_emitcode("mov","a,_bp");
2593             pic14_emitcode("movx","@r0,a");
2594             pic14_emitcode("inc","%s",spname);
2595         }
2596         else
2597         {
2598             /* set up the stack */
2599             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2600         }
2601         pic14_emitcode ("mov","_bp,%s",spname);
2602     }
2603
2604     /* adjust the stack for the function */
2605     if (sym->stack) {
2606
2607         int i = sym->stack;
2608         if (i > 256 ) 
2609             werror(W_STACK_OVERFLOW,sym->name);
2610
2611         if (i > 3 && sym->recvSize < 4) {              
2612
2613             pic14_emitcode ("mov","a,sp");
2614             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2615             pic14_emitcode ("mov","sp,a");
2616            
2617         }
2618         else
2619             while(i--)
2620                 pic14_emitcode("inc","sp");
2621     }
2622
2623      if (sym->xstack) {
2624
2625         pic14_emitcode ("mov","a,_spx");
2626         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2627         pic14_emitcode ("mov","_spx,a");
2628     }    
2629
2630 }
2631
2632 /*-----------------------------------------------------------------*/
2633 /* genEndFunction - generates epilogue for functions               */
2634 /*-----------------------------------------------------------------*/
2635 static void genEndFunction (iCode *ic)
2636 {
2637     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2638
2639     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2640
2641     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2642     {
2643         pic14_emitcode ("mov","%s,_bp",spname);
2644     }
2645
2646     /* if use external stack but some variables were
2647     added to the local stack then decrement the
2648     local stack */
2649     if (options.useXstack && sym->stack) {      
2650         pic14_emitcode("mov","a,sp");
2651         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2652         pic14_emitcode("mov","sp,a");
2653     }
2654
2655
2656     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2657         if (options.useXstack) {
2658             pic14_emitcode("mov","r0,%s",spname);
2659             pic14_emitcode("movx","a,@r0");
2660             pic14_emitcode("mov","_bp,a");
2661             pic14_emitcode("dec","%s",spname);
2662         }
2663         else
2664         {
2665             pic14_emitcode ("pop","_bp");
2666         }
2667     }
2668
2669     /* restore the register bank  */    
2670     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2671         pic14_emitcode ("pop","psw");
2672
2673     if (IFFUNC_ISISR(sym->type)) {
2674
2675         /* now we need to restore the registers */
2676         /* if this isr has no bank i.e. is going to
2677            run with bank 0 , then we need to save more
2678            registers :-) */
2679         if (!FUNC_REGBANK(sym->type)) {
2680             
2681             /* if this function does not call any other
2682                function then we can be economical and
2683                save only those registers that are used */
2684             if (! IFFUNC_HASFCALL(sym->type)) {
2685                 int i;
2686                 
2687                 /* if any registers used */
2688                 if (sym->regsUsed) {
2689                     /* save the registers used */
2690                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2691                         if (bitVectBitValue(sym->regsUsed,i) ||
2692                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2693                             pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2694                     }
2695                 }
2696                 
2697             } else {
2698                 /* this function has  a function call cannot
2699                    determines register usage so we will have the
2700                    entire bank */
2701                 unsaverbank(0,ic,FALSE);
2702             }       
2703         }
2704
2705         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2706         {
2707             if (options.stack10bit)
2708             {
2709                 pic14_emitcode ("pop", "dpx1");
2710                 pic14_emitcode ("pop", "dph1");
2711                 pic14_emitcode ("pop", "dpl1");
2712             }   
2713             pic14_emitcode ("pop", "dps");
2714             pic14_emitcode ("pop", "dpx");
2715         }
2716         if (!inExcludeList("dph"))
2717             pic14_emitcode ("pop","dph");
2718         if (!inExcludeList("dpl"))
2719             pic14_emitcode ("pop","dpl");
2720         if (!inExcludeList("b"))
2721             pic14_emitcode ("pop","b");
2722         if (!inExcludeList("acc"))
2723             pic14_emitcode ("pop","acc");
2724
2725         if (IFFUNC_ISCRITICAL(sym->type))
2726             pic14_emitcode("setb","ea");
2727
2728         /* if debug then send end of function */
2729 /*      if (options.debug && currFunc) { */
2730         if (currFunc) {
2731             _G.debugLine = 1;
2732             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2733                      FileBaseName(ic->filename),currFunc->lastLine,
2734                      ic->level,ic->block); 
2735             if (IS_STATIC(currFunc->etype))         
2736                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2737             else
2738                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2739             _G.debugLine = 0;
2740         }
2741         
2742         pic14_emitcode ("reti","");
2743     }
2744     else {
2745         if (IFFUNC_ISCRITICAL(sym->type))
2746             pic14_emitcode("setb","ea");
2747         
2748         if (IFFUNC_CALLEESAVES(sym->type)) {
2749             int i;
2750             
2751             /* if any registers used */
2752             if (sym->regsUsed) {
2753                 /* save the registers used */
2754                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2755                     if (bitVectBitValue(sym->regsUsed,i) ||
2756                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2757                         pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2758                 }
2759             }
2760             
2761         }
2762
2763         /* if debug then send end of function */
2764         if (currFunc) {
2765             _G.debugLine = 1;
2766             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2767                      FileBaseName(ic->filename),currFunc->lastLine,
2768                      ic->level,ic->block); 
2769             if (IS_STATIC(currFunc->etype))         
2770                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2771             else
2772                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2773             _G.debugLine = 0;
2774         }
2775
2776         pic14_emitcode ("return","");
2777         emitpcodeNULLop(POC_RETURN);
2778
2779         /* Mark the end of a function */
2780         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2781     }
2782
2783 }
2784
2785 /*-----------------------------------------------------------------*/
2786 /* genRet - generate code for return statement                     */
2787 /*-----------------------------------------------------------------*/
2788 static void genRet (iCode *ic)
2789 {
2790     int size,offset = 0 , pushed = 0;
2791     
2792     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2793     /* if we have no return value then
2794        just generate the "ret" */
2795     if (!IC_LEFT(ic)) 
2796         goto jumpret;       
2797     
2798     /* we have something to return then
2799        move the return value into place */
2800     aopOp(IC_LEFT(ic),ic,FALSE);
2801     size = AOP_SIZE(IC_LEFT(ic));
2802     
2803     while (size--) {
2804             char *l ;
2805             if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2806                     /* #NOCHANGE */
2807                     l = aopGet(AOP(IC_LEFT(ic)),offset++,
2808                            FALSE,TRUE);
2809                     pic14_emitcode("push","%s",l);
2810                     pushed++;
2811             } else {
2812                     l = aopGet(AOP(IC_LEFT(ic)),offset,
2813                                FALSE,FALSE);
2814                     if (strcmp(fReturn[offset],l)) {
2815                       if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2816                           ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2817                         pic14_emitcode("movlw","%s",l);
2818                       else
2819                         pic14_emitcode("movf","%s,w",l);
2820                       if(size)
2821                         pic14_emitcode("movwf","%s",fReturn[offset]);
2822                       offset++;
2823                     }
2824             }
2825     }    
2826
2827     if (pushed) {
2828         while(pushed) {
2829             pushed--;
2830             if (strcmp(fReturn[pushed],"a"))
2831                 pic14_emitcode("pop",fReturn[pushed]);
2832             else
2833                 pic14_emitcode("pop","acc");
2834         }
2835     }
2836     freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2837     
2838  jumpret:
2839         /* generate a jump to the return label
2840            if the next is not the return statement */
2841     if (!(ic->next && ic->next->op == LABEL &&
2842           IC_LABEL(ic->next) == returnLabel)) {
2843         
2844         emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2845         pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2846     }
2847     
2848 }
2849
2850 /*-----------------------------------------------------------------*/
2851 /* genLabel - generates a label                                    */
2852 /*-----------------------------------------------------------------*/
2853 static void genLabel (iCode *ic)
2854 {
2855     /* special case never generate */
2856     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2857     if (IC_LABEL(ic) == entryLabel)
2858         return ;
2859
2860     emitpLabel(IC_LABEL(ic)->key);
2861     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2862 }
2863
2864 /*-----------------------------------------------------------------*/
2865 /* genGoto - generates a goto                                      */
2866 /*-----------------------------------------------------------------*/
2867 //tsd
2868 static void genGoto (iCode *ic)
2869 {
2870   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2871   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2872 }
2873
2874 /*-----------------------------------------------------------------*/
2875 /* findLabelBackwards: walks back through the iCode chain looking  */
2876 /* for the given label. Returns number of iCode instructions       */
2877 /* between that label and given ic.                                */
2878 /* Returns zero if label not found.                                */
2879 /*-----------------------------------------------------------------*/
2880 #if 0
2881 static int findLabelBackwards(iCode *ic, int key)
2882 {
2883     int count = 0;
2884     
2885     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2886     while (ic->prev)
2887     {
2888         ic = ic->prev;
2889         count++;
2890         
2891         if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2892         {
2893             /* printf("findLabelBackwards = %d\n", count); */
2894             return count;
2895         }
2896     }
2897     
2898     return 0;
2899 }
2900 #endif
2901
2902 /*-----------------------------------------------------------------*/
2903 /* genMultbits :- multiplication of bits                           */
2904 /*-----------------------------------------------------------------*/
2905 static void genMultbits (operand *left, 
2906                          operand *right, 
2907                          operand *result)
2908 {
2909     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2910
2911     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2912     pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2913     pic14_outBitC(result);
2914 }
2915
2916
2917 /*-----------------------------------------------------------------*/
2918 /* genMultOneByte : 8 bit multiplication & division                */
2919 /*-----------------------------------------------------------------*/
2920 static void genMultOneByte (operand *left,
2921                             operand *right,
2922                             operand *result)
2923 {
2924     sym_link *opetype = operandType(result);
2925     char *l ;
2926     symbol *lbl ;
2927     int size,offset;
2928
2929     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2930     /* (if two literals, the value is computed before) */
2931     /* if one literal, literal on the right */
2932     if (AOP_TYPE(left) == AOP_LIT){
2933         operand *t = right;
2934         right = left;
2935         left = t;
2936     }
2937
2938     size = AOP_SIZE(result);
2939     /* signed or unsigned */
2940     pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2941     l = aopGet(AOP(left),0,FALSE,FALSE);
2942     MOVA(l);       
2943     pic14_emitcode("mul","ab");
2944     /* if result size = 1, mul signed = mul unsigned */
2945     aopPut(AOP(result),"a",0);
2946     if (size > 1){
2947         if (SPEC_USIGN(opetype)){
2948             aopPut(AOP(result),"b",1);
2949             if (size > 2)
2950                 /* for filling the MSBs */
2951                 pic14_emitcode("clr","a");
2952         }
2953         else{
2954             pic14_emitcode("mov","a,b");
2955
2956             /* adjust the MSB if left or right neg */
2957
2958             /* if one literal */
2959             if (AOP_TYPE(right) == AOP_LIT){
2960                 /* AND literal negative */
2961                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2962                     /* adjust MSB (c==0 after mul) */
2963                     pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2964                 }
2965             }
2966             else{
2967                 lbl = newiTempLabel(NULL);
2968                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2969                 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2970                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2971                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2972                 lbl = newiTempLabel(NULL);      
2973                 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
2974                 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2975                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2976             }
2977
2978             lbl = newiTempLabel(NULL);
2979             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2980             pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2981             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2982             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2983             lbl = newiTempLabel(NULL);      
2984             pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
2985             pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2986             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2987
2988             aopPut(AOP(result),"a",1);
2989             if(size > 2){
2990                 /* get the sign */
2991                 pic14_emitcode("rlc","a");
2992                 pic14_emitcode("subb","a,acc");
2993             }
2994         }
2995         size -= 2;   
2996         offset = 2;
2997         if (size > 0)
2998             while (size--)
2999                 aopPut(AOP(result),"a",offset++);
3000     }
3001 }
3002
3003 /*-----------------------------------------------------------------*/
3004 /* genMult - generates code for multiplication                     */
3005 /*-----------------------------------------------------------------*/
3006 static void genMult (iCode *ic)
3007 {
3008     operand *left = IC_LEFT(ic);
3009     operand *right = IC_RIGHT(ic);
3010     operand *result= IC_RESULT(ic);   
3011
3012     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3013     /* assign the amsops */
3014     aopOp (left,ic,FALSE);
3015     aopOp (right,ic,FALSE);
3016     aopOp (result,ic,TRUE);
3017
3018     /* special cases first */
3019     /* both are bits */
3020     if (AOP_TYPE(left) == AOP_CRY &&
3021         AOP_TYPE(right)== AOP_CRY) {
3022         genMultbits(left,right,result);
3023         goto release ;
3024     }
3025
3026     /* if both are of size == 1 */
3027     if (AOP_SIZE(left) == 1 &&
3028         AOP_SIZE(right) == 1 ) {
3029         genMultOneByte(left,right,result);
3030         goto release ;
3031     }
3032
3033     /* should have been converted to function call */       
3034     assert(1) ;
3035
3036 release :
3037     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3038     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3039     freeAsmop(result,NULL,ic,TRUE); 
3040 }
3041
3042 /*-----------------------------------------------------------------*/
3043 /* genDivbits :- division of bits                                  */
3044 /*-----------------------------------------------------------------*/
3045 static void genDivbits (operand *left, 
3046                         operand *right, 
3047                         operand *result)
3048 {
3049
3050     char *l;
3051
3052     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3053     /* the result must be bit */    
3054     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3055     l = aopGet(AOP(left),0,FALSE,FALSE);
3056
3057     MOVA(l);    
3058
3059     pic14_emitcode("div","ab");
3060     pic14_emitcode("rrc","a");
3061     aopPut(AOP(result),"c",0);
3062 }
3063
3064 /*-----------------------------------------------------------------*/
3065 /* genDivOneByte : 8 bit division                                  */
3066 /*-----------------------------------------------------------------*/
3067 static void genDivOneByte (operand *left,
3068                            operand *right,
3069                            operand *result)
3070 {
3071     sym_link *opetype = operandType(result);
3072     char *l ;
3073     symbol *lbl ;
3074     int size,offset;
3075
3076     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3077     size = AOP_SIZE(result) - 1;
3078     offset = 1;
3079     /* signed or unsigned */
3080     if (SPEC_USIGN(opetype)) {
3081         /* unsigned is easy */
3082         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3083         l = aopGet(AOP(left),0,FALSE,FALSE);
3084         MOVA(l);        
3085         pic14_emitcode("div","ab");
3086         aopPut(AOP(result),"a",0);
3087         while (size--)
3088             aopPut(AOP(result),zero,offset++);
3089         return ;
3090     }
3091
3092     /* signed is a little bit more difficult */
3093
3094     /* save the signs of the operands */
3095     l = aopGet(AOP(left),0,FALSE,FALSE);    
3096     MOVA(l);    
3097     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3098     pic14_emitcode("push","acc"); /* save it on the stack */
3099
3100     /* now sign adjust for both left & right */
3101     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3102     MOVA(l);       
3103     lbl = newiTempLabel(NULL);
3104     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3105     pic14_emitcode("cpl","a");   
3106     pic14_emitcode("inc","a");
3107     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3108     pic14_emitcode("mov","b,a");
3109
3110     /* sign adjust left side */
3111     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3112     MOVA(l);
3113
3114     lbl = newiTempLabel(NULL);
3115     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3116     pic14_emitcode("cpl","a");
3117     pic14_emitcode("inc","a");
3118     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3119
3120     /* now the division */
3121     pic14_emitcode("div","ab");
3122     /* we are interested in the lower order
3123     only */
3124     pic14_emitcode("mov","b,a");
3125     lbl = newiTempLabel(NULL);
3126     pic14_emitcode("pop","acc");   
3127     /* if there was an over flow we don't 
3128     adjust the sign of the result */
3129     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3130     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3131     CLRC;
3132     pic14_emitcode("clr","a");
3133     pic14_emitcode("subb","a,b");
3134     pic14_emitcode("mov","b,a");
3135     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3136
3137     /* now we are done */
3138     aopPut(AOP(result),"b",0);
3139     if(size > 0){
3140         pic14_emitcode("mov","c,b.7");
3141         pic14_emitcode("subb","a,acc");   
3142     }
3143     while (size--)
3144         aopPut(AOP(result),"a",offset++);
3145
3146 }
3147
3148 /*-----------------------------------------------------------------*/
3149 /* genDiv - generates code for division                            */
3150 /*-----------------------------------------------------------------*/
3151 static void genDiv (iCode *ic)
3152 {
3153     operand *left = IC_LEFT(ic);
3154     operand *right = IC_RIGHT(ic);
3155     operand *result= IC_RESULT(ic);   
3156
3157     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3158     /* assign the amsops */
3159     aopOp (left,ic,FALSE);
3160     aopOp (right,ic,FALSE);
3161     aopOp (result,ic,TRUE);
3162
3163     /* special cases first */
3164     /* both are bits */
3165     if (AOP_TYPE(left) == AOP_CRY &&
3166         AOP_TYPE(right)== AOP_CRY) {
3167         genDivbits(left,right,result);
3168         goto release ;
3169     }
3170
3171     /* if both are of size == 1 */
3172     if (AOP_SIZE(left) == 1 &&
3173         AOP_SIZE(right) == 1 ) {
3174         genDivOneByte(left,right,result);
3175         goto release ;
3176     }
3177
3178     /* should have been converted to function call */
3179     assert(1);
3180 release :
3181     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3183     freeAsmop(result,NULL,ic,TRUE); 
3184 }
3185
3186 /*-----------------------------------------------------------------*/
3187 /* genModbits :- modulus of bits                                   */
3188 /*-----------------------------------------------------------------*/
3189 static void genModbits (operand *left, 
3190                         operand *right, 
3191                         operand *result)
3192 {
3193
3194     char *l;
3195
3196     /* the result must be bit */    
3197     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3198     l = aopGet(AOP(left),0,FALSE,FALSE);
3199
3200     MOVA(l);       
3201
3202     pic14_emitcode("div","ab");
3203     pic14_emitcode("mov","a,b");
3204     pic14_emitcode("rrc","a");
3205     aopPut(AOP(result),"c",0);
3206 }
3207
3208 /*-----------------------------------------------------------------*/
3209 /* genModOneByte : 8 bit modulus                                   */
3210 /*-----------------------------------------------------------------*/
3211 static void genModOneByte (operand *left,
3212                            operand *right,
3213                            operand *result)
3214 {
3215     sym_link *opetype = operandType(result);
3216     char *l ;
3217     symbol *lbl ;
3218
3219     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3220     /* signed or unsigned */
3221     if (SPEC_USIGN(opetype)) {
3222         /* unsigned is easy */
3223         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3224         l = aopGet(AOP(left),0,FALSE,FALSE);
3225         MOVA(l);    
3226         pic14_emitcode("div","ab");
3227         aopPut(AOP(result),"b",0);
3228         return ;
3229     }
3230
3231     /* signed is a little bit more difficult */
3232
3233     /* save the signs of the operands */
3234     l = aopGet(AOP(left),0,FALSE,FALSE);    
3235     MOVA(l);
3236
3237     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3238     pic14_emitcode("push","acc"); /* save it on the stack */
3239
3240     /* now sign adjust for both left & right */
3241     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3242     MOVA(l);
3243
3244     lbl = newiTempLabel(NULL);
3245     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3246     pic14_emitcode("cpl","a");   
3247     pic14_emitcode("inc","a");
3248     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3249     pic14_emitcode("mov","b,a"); 
3250
3251     /* sign adjust left side */
3252     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3253     MOVA(l);
3254
3255     lbl = newiTempLabel(NULL);
3256     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3257     pic14_emitcode("cpl","a");   
3258     pic14_emitcode("inc","a");
3259     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3260
3261     /* now the multiplication */
3262     pic14_emitcode("div","ab");
3263     /* we are interested in the lower order
3264     only */
3265     lbl = newiTempLabel(NULL);
3266     pic14_emitcode("pop","acc");   
3267     /* if there was an over flow we don't 
3268     adjust the sign of the result */
3269     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3270     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3271     CLRC ;
3272     pic14_emitcode("clr","a");
3273     pic14_emitcode("subb","a,b");
3274     pic14_emitcode("mov","b,a");
3275     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3276
3277     /* now we are done */
3278     aopPut(AOP(result),"b",0);
3279
3280 }
3281
3282 /*-----------------------------------------------------------------*/
3283 /* genMod - generates code for division                            */
3284 /*-----------------------------------------------------------------*/
3285 static void genMod (iCode *ic)
3286 {
3287     operand *left = IC_LEFT(ic);
3288     operand *right = IC_RIGHT(ic);
3289     operand *result= IC_RESULT(ic);  
3290
3291     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3292     /* assign the amsops */
3293     aopOp (left,ic,FALSE);
3294     aopOp (right,ic,FALSE);
3295     aopOp (result,ic,TRUE);
3296
3297     /* special cases first */
3298     /* both are bits */
3299     if (AOP_TYPE(left) == AOP_CRY &&
3300         AOP_TYPE(right)== AOP_CRY) {
3301         genModbits(left,right,result);
3302         goto release ;
3303     }
3304
3305     /* if both are of size == 1 */
3306     if (AOP_SIZE(left) == 1 &&
3307         AOP_SIZE(right) == 1 ) {
3308         genModOneByte(left,right,result);
3309         goto release ;
3310     }
3311
3312     /* should have been converted to function call */
3313     assert(1);
3314
3315 release :
3316     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3317     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3318     freeAsmop(result,NULL,ic,TRUE); 
3319 }
3320
3321 /*-----------------------------------------------------------------*/
3322 /* genIfxJump :- will create a jump depending on the ifx           */
3323 /*-----------------------------------------------------------------*/
3324 /*
3325   note: May need to add parameter to indicate when a variable is in bit space.
3326 */
3327 static void genIfxJump (iCode *ic, char *jval)
3328 {
3329
3330     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3331     /* if true label then we jump if condition
3332     supplied is true */
3333     if ( IC_TRUE(ic) ) {
3334
3335         if(strcmp(jval,"a") == 0)
3336           emitSKPZ;
3337         else if (strcmp(jval,"c") == 0)
3338           emitSKPC;
3339         else {
3340           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3341           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3342         }
3343
3344         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3345         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3346
3347     }
3348     else {
3349         /* false label is present */
3350         if(strcmp(jval,"a") == 0)
3351           emitSKPNZ;
3352         else if (strcmp(jval,"c") == 0)
3353           emitSKPNC;
3354         else {
3355           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3356           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3357         }
3358
3359         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3360         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3361
3362     }
3363
3364
3365     /* mark the icode as generated */
3366     ic->generated = 1;
3367 }
3368
3369 /*-----------------------------------------------------------------*/
3370 /* genSkip                                                         */
3371 /*-----------------------------------------------------------------*/
3372 static void genSkip(iCode *ifx,int status_bit)
3373 {
3374   if(!ifx)
3375     return;
3376
3377   if ( IC_TRUE(ifx) ) {
3378     switch(status_bit) {
3379     case 'z':
3380       emitSKPNZ;
3381       break;
3382
3383     case 'c':
3384       emitSKPNC;
3385       break;
3386
3387     case 'd':
3388       emitSKPDC;
3389       break;
3390
3391     }
3392
3393     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3394     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3395
3396   } else {
3397
3398     switch(status_bit) {
3399
3400     case 'z':
3401       emitSKPZ;
3402       break;
3403
3404     case 'c':
3405       emitSKPC;
3406       break;
3407
3408     case 'd':
3409       emitSKPDC;
3410       break;
3411     }
3412     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3413     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3414
3415   }
3416
3417 }
3418
3419 /*-----------------------------------------------------------------*/
3420 /* genSkipc                                                        */
3421 /*-----------------------------------------------------------------*/
3422 static void genSkipc(resolvedIfx *rifx)
3423 {
3424   if(!rifx)
3425     return;
3426
3427   if(rifx->condition)
3428     emitSKPC;
3429   else
3430     emitSKPNC;
3431
3432   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3433   rifx->generated = 1;
3434 }
3435
3436 /*-----------------------------------------------------------------*/
3437 /* genSkipz                                                        */
3438 /*-----------------------------------------------------------------*/
3439 static void genSkipz(iCode *ifx, int condition)
3440 {
3441   if(!ifx)
3442     return;
3443
3444   if(condition)
3445     emitSKPNZ;
3446   else
3447     emitSKPZ;
3448
3449   if ( IC_TRUE(ifx) )
3450     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3451   else
3452     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3453
3454   if ( IC_TRUE(ifx) )
3455     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3456   else
3457     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3458
3459 }
3460 /*-----------------------------------------------------------------*/
3461 /* genCmp :- greater or less than comparison                       */
3462 /*-----------------------------------------------------------------*/
3463 static void genCmp (operand *left,operand *right,
3464                     operand *result, iCode *ifx, int sign)
3465 {
3466   int size, offset = 0 ;
3467   unsigned long lit = 0L,i = 0;
3468   resolvedIfx rIfx;
3469
3470   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3471   if(ifx) {
3472   DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3473   DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3474   }
3475
3476   resolveIfx(&rIfx,ifx);
3477
3478   /* if left & right are bit variables */
3479   if (AOP_TYPE(left) == AOP_CRY &&
3480       AOP_TYPE(right) == AOP_CRY ) {
3481     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3482     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3483   } else {
3484     /* subtract right from left if at the
3485        end the carry flag is set then we know that
3486        left is greater than right */
3487     size = max(AOP_SIZE(left),AOP_SIZE(right));
3488
3489     /* if unsigned char cmp with lit, do cjne left,#right,zz */
3490     if((size == 1) && !sign &&
3491        (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3492       symbol *lbl  = newiTempLabel(NULL);
3493       pic14_emitcode("cjne","%s,%s,%05d_DS_",
3494                aopGet(AOP(left),offset,FALSE,FALSE),
3495                aopGet(AOP(right),offset,FALSE,FALSE),
3496                lbl->key+100);
3497       pic14_emitcode("","%05d_DS_:",lbl->key+100);
3498     } else {
3499
3500       if(AOP_TYPE(right) == AOP_LIT) {
3501         symbol *lbl = newiTempLabel(NULL);
3502
3503         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3504
3505         DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3506
3507         size--;
3508         i = (lit >> (size*8)) & 0xff;
3509         if(sign) {
3510           if(i & 0x80) {
3511             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3512           } else {
3513             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3514           }
3515           emitpcode(POC_GOTO,popGetLabel(lbl->key));
3516         }
3517
3518         emitpcode(POC_MOVLW, popGetLit(i));
3519         emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3520         while(size--) {
3521           i = (lit >> (size*8)) & 0xff;
3522           emitpcode(POC_MOVLW, popGetLit(i));
3523           emitSKPNC;
3524           emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3525         }
3526
3527         if(ifx) {
3528           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3529           //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3530           genSkipc(&rIfx);
3531           //if(sign)
3532             emitpLabel(lbl->key);
3533
3534           ifx->generated = 1;
3535         }
3536         return;
3537       }
3538
3539       if(AOP_TYPE(left) == AOP_LIT) {
3540         //symbol *lbl = newiTempLabel(NULL);
3541
3542         lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3543
3544         DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3545
3546         if(size==1) {
3547           if(sign) {
3548             if(lit & 0x80) {
3549               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3550             } else {
3551               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3552             }
3553             if(ifx) {
3554               if(IC_TRUE(ifx) != NULL)
3555                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3556               else
3557                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3558             }
3559           }
3560           emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3561           emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3562           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3563           rIfx.condition ^= 1;
3564           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3565         } else {
3566           size--;
3567           //lit++;
3568           i = (lit >> (size*8)) & 0xff;
3569
3570           if(sign) {
3571             if(i & 0x80) {
3572               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3573             } else {
3574               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3575             }
3576             if(ifx) {
3577               if(IC_TRUE(ifx) != NULL)
3578                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3579               else
3580                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3581             }
3582           }
3583
3584           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3585           emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3586           while(size--) {
3587             i = (lit >> (size*8)) & 0xff;
3588             emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3589             emitSKPNC;
3590             emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3591           }
3592   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3593           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,0,1);  //IC_TRUE(ifx) == NULL);
3594
3595         }
3596 /*
3597         if(sign)
3598           emitpLabel(lbl->key);
3599 */
3600         if(ifx) ifx->generated = 1;
3601         return;
3602       }
3603
3604
3605       // CLRC;
3606       DEBUGpic14_emitcode(";sign","%d",sign);
3607
3608       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3609       pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3610
3611       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3612       emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3613
3614       size--;
3615       while (size--) {
3616
3617         emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
3618         emitSKPC;
3619         emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3620         emitpcode(POC_SUBFW,   popGet(AOP(left),offset,FALSE,FALSE));
3621
3622 /*
3623         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3624         emitSKPC;
3625         pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3626         pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3627 */
3628         offset++;
3629       }
3630     }
3631   }
3632
3633   //release:
3634   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3635     pic14_outBitC(result);
3636   } else {
3637     /* if the result is used in the next
3638        ifx conditional branch then generate
3639        code a little differently */
3640     if (ifx )
3641       genIfxJump (ifx,"c");
3642     else
3643       pic14_outBitC(result);
3644     /* leave the result in acc */
3645   }
3646
3647 }
3648
3649 /*-----------------------------------------------------------------*/
3650 /* genCmpGt :- greater than comparison                             */
3651 /*-----------------------------------------------------------------*/
3652 static void genCmpGt (iCode *ic, iCode *ifx)
3653 {
3654     operand *left, *right, *result;
3655     sym_link *letype , *retype;
3656     int sign ;
3657
3658     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3659     left = IC_LEFT(ic);
3660     right= IC_RIGHT(ic);
3661     result = IC_RESULT(ic);
3662
3663     letype = getSpec(operandType(left));
3664     retype =getSpec(operandType(right));
3665     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3666     /* assign the amsops */
3667     aopOp (left,ic,FALSE);
3668     aopOp (right,ic,FALSE);
3669     aopOp (result,ic,TRUE);
3670
3671     genCmp(right, left, result, ifx, sign);
3672
3673     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3674     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3675     freeAsmop(result,NULL,ic,TRUE); 
3676 }
3677
3678 /*-----------------------------------------------------------------*/
3679 /* genCmpLt - less than comparisons                                */
3680 /*-----------------------------------------------------------------*/
3681 static void genCmpLt (iCode *ic, iCode *ifx)
3682 {
3683     operand *left, *right, *result;
3684     sym_link *letype , *retype;
3685     int sign ;
3686
3687     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3688     left = IC_LEFT(ic);
3689     right= IC_RIGHT(ic);
3690     result = IC_RESULT(ic);
3691
3692     letype = getSpec(operandType(left));
3693     retype =getSpec(operandType(right));
3694     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3695
3696     /* assign the amsops */
3697     aopOp (left,ic,FALSE);
3698     aopOp (right,ic,FALSE);
3699     aopOp (result,ic,TRUE);
3700
3701     genCmp(left, right, result, ifx, sign);
3702
3703     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3704     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3705     freeAsmop(result,NULL,ic,TRUE); 
3706 }
3707
3708 /*-----------------------------------------------------------------*/
3709 /* genc16bit2lit - compare a 16 bit value to a literal             */
3710 /*-----------------------------------------------------------------*/
3711 static void genc16bit2lit(operand *op, int lit, int offset)
3712 {
3713   int i;
3714
3715   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
3716   if( (lit&0xff) == 0) 
3717     i=1;
3718   else
3719     i=0;
3720
3721   switch( BYTEofLONG(lit,i)) { 
3722   case 0:
3723     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3724     break;
3725   case 1:
3726     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3727     break;
3728   case 0xff:
3729     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3730     break;
3731   default:
3732     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3733     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3734   }
3735
3736   i ^= 1;
3737
3738   switch( BYTEofLONG(lit,i)) { 
3739   case 0:
3740     emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3741     break;
3742   case 1:
3743     emitSKPNZ;
3744     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3745     break;
3746   case 0xff:
3747     emitSKPNZ;
3748     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3749     break;
3750   default:
3751     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3752     emitSKPNZ;
3753     emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3754
3755   }
3756
3757 }
3758
3759 /*-----------------------------------------------------------------*/
3760 /* gencjneshort - compare and jump if not equal                    */
3761 /*-----------------------------------------------------------------*/
3762 static void gencjne(operand *left, operand *right, iCode *ifx)
3763 {
3764   int size = max(AOP_SIZE(left),AOP_SIZE(right));
3765   int offset = 0;
3766   resolvedIfx rIfx;
3767   symbol *lbl;
3768
3769   unsigned long lit = 0L;
3770   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3771   DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3772                        AopType(AOP_TYPE(left)),
3773                        aopGet(AOP(left),0,TRUE,FALSE),
3774                        AopType(AOP_TYPE(right)),
3775                        aopGet(AOP(right),0,FALSE,FALSE),
3776                        size);
3777
3778   resolveIfx(&rIfx,ifx);
3779   lbl =  newiTempLabel(NULL);
3780
3781
3782   /* if the left side is a literal or 
3783      if the right is in a pointer register and left 
3784      is not */
3785   if ((AOP_TYPE(left) == AOP_LIT) || 
3786       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3787     operand *t = right;
3788     right = left;
3789     left = t;
3790   }
3791   if(AOP_TYPE(right) == AOP_LIT)
3792     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3793
3794   /* if the right side is a literal then anything goes */
3795   if (AOP_TYPE(right) == AOP_LIT &&
3796       AOP_TYPE(left) != AOP_DIR ) {
3797     switch(size) {
3798     case 2:
3799       genc16bit2lit(left, lit, 0);
3800       emitSKPNZ;
3801       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3802       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3803       break;
3804     default:
3805       while (size--) {
3806         if(lit & 0xff) {
3807           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3808           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3809           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3810           pic14_emitcode("xorlw","0x%x",lit & 0xff);
3811         } else {
3812           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3813           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3814         }
3815
3816         emitSKPNZ;
3817         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3818         emitpcode(POC_GOTO,popGetLabel(lbl->key));
3819         offset++;
3820         lit >>= 8;
3821       }
3822       break;
3823     }
3824   }
3825
3826   /* if the right side is in a register or in direct space or
3827      if the left is a pointer register & right is not */    
3828   else if (AOP_TYPE(right) == AOP_REG ||
3829            AOP_TYPE(right) == AOP_DIR || 
3830            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3831            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3832     switch(size) {
3833     case 2:
3834       genc16bit2lit(left, lit, 0);
3835       emitSKPNZ;
3836       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3837       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3838       break;
3839     default:
3840       while (size--) {
3841         int emit_skip=1;
3842         if((AOP_TYPE(left) == AOP_DIR) && 
3843            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3844
3845           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3846           emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3847
3848         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3849             
3850           switch (lit & 0xff) {
3851           case 0:
3852             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3853             break;
3854           case 1:
3855             emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3856             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3857             emit_skip=0;
3858             break;
3859           case 0xff:
3860             emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3861             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3862             emit_skip=0;
3863             break;
3864           default:
3865             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3866             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3867           }
3868           lit >>= 8;
3869
3870         } else {
3871           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3872           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3873         }
3874         if(emit_skip) {
3875           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3876           if(rIfx.condition)
3877             emitSKPNZ;
3878           else
3879             emitSKPZ;
3880           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3881           if(ifx)
3882             ifx->generated=1;
3883         }
3884         emit_skip++;
3885         offset++;
3886       }
3887       break;
3888     }
3889   } else if(AOP_TYPE(right) == AOP_REG &&
3890             AOP_TYPE(left) != AOP_DIR){
3891
3892     while(size--) {
3893       emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3894       emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3895       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3896       if(rIfx.condition)
3897         emitSKPNZ;
3898       else
3899         emitSKPZ;
3900       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3901       offset++;
3902     }
3903       
3904   }else{
3905     /* right is a pointer reg need both a & b */
3906     while(size--) {
3907       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3908       if(strcmp(l,"b"))
3909         pic14_emitcode("mov","b,%s",l);
3910       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3911       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
3912       offset++;
3913     }
3914   }
3915   emitpLabel(lbl->key);
3916
3917   if(ifx)
3918     ifx->generated = 1;
3919 }
3920
3921 #if 0
3922 /*-----------------------------------------------------------------*/
3923 /* gencjne - compare and jump if not equal                         */
3924 /*-----------------------------------------------------------------*/
3925 static void gencjne(operand *left, operand *right, iCode *ifx)
3926 {
3927     symbol *tlbl  = newiTempLabel(NULL);
3928
3929     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3930     gencjneshort(left, right, lbl);
3931
3932     pic14_emitcode("mov","a,%s",one);
3933     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3934     pic14_emitcode("","%05d_DS_:",lbl->key+100);
3935     pic14_emitcode("clr","a");
3936     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3937
3938     emitpLabel(lbl->key);
3939     emitpLabel(tlbl->key);
3940
3941 }
3942 #endif
3943
3944 /*-----------------------------------------------------------------*/
3945 /* genCmpEq - generates code for equal to                          */
3946 /*-----------------------------------------------------------------*/
3947 static void genCmpEq (iCode *ic, iCode *ifx)
3948 {
3949     operand *left, *right, *result;
3950     unsigned long lit = 0L;
3951     int size,offset=0;
3952
3953     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3954
3955     if(ifx)
3956       DEBUGpic14_emitcode ("; ifx is non-null","");
3957     else
3958       DEBUGpic14_emitcode ("; ifx is null","");
3959
3960     aopOp((left=IC_LEFT(ic)),ic,FALSE);
3961     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3962     aopOp((result=IC_RESULT(ic)),ic,TRUE);
3963
3964 /*
3965     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3966                          AopType(AOP_TYPE(IC_RESULT(ic))),
3967                          AopType(AOP_TYPE(IC_LEFT(ic))),
3968                          AopType(AOP_TYPE(IC_RIGHT(ic))));
3969 */
3970     size = max(AOP_SIZE(left),AOP_SIZE(right));
3971     DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
3972                          AopType(AOP_TYPE(result)),
3973                          aopGet(AOP(result),0,TRUE,FALSE),
3974                          AopType(AOP_TYPE(left)),
3975                          aopGet(AOP(left),0,TRUE,FALSE),
3976                          AopType(AOP_TYPE(right)),
3977                          aopGet(AOP(right),0,FALSE,FALSE),
3978                          size);
3979
3980
3981     /* if literal, literal on the right or 
3982     if the right is in a pointer register and left 
3983     is not */
3984     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
3985         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3986         operand *t = IC_RIGHT(ic);
3987         IC_RIGHT(ic) = IC_LEFT(ic);
3988         IC_LEFT(ic) = t;
3989     }
3990
3991     if(ifx && !AOP_SIZE(result)){
3992         symbol *tlbl;
3993         /* if they are both bit variables */
3994         if (AOP_TYPE(left) == AOP_CRY &&
3995             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3996             if(AOP_TYPE(right) == AOP_LIT){
3997                 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3998                 if(lit == 0L){
3999                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4000                     pic14_emitcode("cpl","c");
4001                 } else if(lit == 1L) {
4002                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4003                 } else {
4004                     pic14_emitcode("clr","c");
4005                 }
4006                 /* AOP_TYPE(right) == AOP_CRY */
4007             } else {
4008                 symbol *lbl = newiTempLabel(NULL);
4009                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4010                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4011                 pic14_emitcode("cpl","c");
4012                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4013             }
4014             /* if true label then we jump if condition
4015             supplied is true */
4016             tlbl = newiTempLabel(NULL);
4017             if ( IC_TRUE(ifx) ) {
4018                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4019                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4020             } else {
4021                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4022                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4023             }
4024             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4025         } else {
4026
4027           /* They're not both bit variables. Is the right a literal? */
4028           if(AOP_TYPE(right) == AOP_LIT) {
4029             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4030             
4031
4032             switch(size) {
4033
4034             case 1:
4035               switch(lit & 0xff) {
4036               case 1:
4037                 if ( IC_TRUE(ifx) ) {
4038                   emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4039                   emitSKPNZ;
4040                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4041                 } else {
4042                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4043                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4044                 }
4045                 break;
4046               case 0xff:
4047                 if ( IC_TRUE(ifx) ) {
4048                   emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4049                   emitSKPNZ;
4050                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4051                 } else {
4052                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4053                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4054                 }
4055                 break;
4056               default:
4057                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4058                 if(lit)
4059                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4060                 genSkip(ifx,'z');
4061               }
4062
4063
4064               /* end of size == 1 */
4065               break;
4066               
4067             case 2:
4068               genc16bit2lit(left,lit,offset);
4069               genSkip(ifx,'z');
4070               break;
4071               /* end of size == 2 */
4072
4073             default:
4074               /* size is 4 */
4075               if(lit==0) {
4076                 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4077                 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4078                 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4079                 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4080
4081               } else {
4082
4083                 /* search for patterns that can be optimized */
4084
4085                 genc16bit2lit(left,lit,0);
4086                 lit >>= 16;
4087                 if(lit) {
4088                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4089                   //genSkip(ifx,'z');
4090                   genc16bit2lit(left,lit,2);
4091                 } else {
4092                   emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4093                   emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4094
4095                 }
4096                 
4097               }
4098
4099               genSkip(ifx,'z');
4100             }
4101           
4102             ifx->generated = 1;
4103             goto release ;
4104             
4105
4106           } else if(AOP_TYPE(right) == AOP_CRY ) {
4107             /* we know the left is not a bit, but that the right is */
4108             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4109             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4110                       popGet(AOP(right),offset,FALSE,FALSE));
4111             emitpcode(POC_XORLW,popGetLit(1));
4112
4113             pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4114             if ( IC_TRUE(ifx) )
4115               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4116                        AOP(right)->aopu.aop_dir,
4117                        AOP(right)->aopu.aop_dir);
4118             else
4119               pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4120                        AOP(right)->aopu.aop_dir,
4121                        AOP(right)->aopu.aop_dir);
4122
4123             pic14_emitcode("xorlw","1");
4124
4125             /* if the two are equal, then W will be 0 and the Z bit is set
4126              * we could test Z now, or go ahead and check the high order bytes if
4127              * the variable we're comparing is larger than a byte. */
4128
4129             while(--size)
4130               emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4131             //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4132
4133             if ( IC_TRUE(ifx) ) {
4134               emitSKPNZ;
4135               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4136               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4137             } else {
4138               emitSKPZ;
4139               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4140               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4141             }
4142
4143           } else {
4144             /* They're both variables that are larger than bits */
4145             int s = size;
4146
4147             tlbl = newiTempLabel(NULL);
4148
4149             while(size--) {
4150               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4151               emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4152
4153               pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4154               pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4155
4156               if ( IC_TRUE(ifx) ) {
4157                 if(size) {
4158                   emitSKPZ;
4159                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4160                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4161                 } else {
4162                   emitSKPNZ;
4163                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4164                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4165                 }
4166               } else {
4167                 emitSKPZ;
4168                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4169                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4170               }
4171               offset++;
4172             }
4173             if(s>1 && IC_TRUE(ifx)) {
4174               emitpLabel(tlbl->key);
4175               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4176             }
4177           }
4178         }
4179         /* mark the icode as generated */
4180         ifx->generated = 1;
4181         goto release ;
4182     }
4183
4184     /* if they are both bit variables */
4185     if (AOP_TYPE(left) == AOP_CRY &&
4186         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4187         if(AOP_TYPE(right) == AOP_LIT){
4188             unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4189             if(lit == 0L){
4190                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4191                 pic14_emitcode("cpl","c");
4192             } else if(lit == 1L) {
4193                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4194             } else {
4195                 pic14_emitcode("clr","c");
4196             }
4197             /* AOP_TYPE(right) == AOP_CRY */
4198         } else {
4199             symbol *lbl = newiTempLabel(NULL);
4200             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4201             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4202             pic14_emitcode("cpl","c");
4203             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4204         }
4205         /* c = 1 if egal */
4206         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4207             pic14_outBitC(result);
4208             goto release ;
4209         }
4210         if (ifx) {
4211             genIfxJump (ifx,"c");
4212             goto release ;
4213         }
4214         /* if the result is used in an arithmetic operation
4215         then put the result in place */
4216         pic14_outBitC(result);
4217     } else {
4218       
4219       gencjne(left,right,ifx);
4220 /*
4221       if(ifx) 
4222         gencjne(left,right,newiTempLabel(NULL));
4223       else {
4224         if(IC_TRUE(ifx)->key)
4225           gencjne(left,right,IC_TRUE(ifx)->key);
4226         else
4227           gencjne(left,right,IC_FALSE(ifx)->key);
4228         ifx->generated = 1;
4229         goto release ;
4230       }
4231       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4232         aopPut(AOP(result),"a",0);
4233         goto release ;
4234       }
4235
4236       if (ifx) {
4237         genIfxJump (ifx,"a");
4238         goto release ;
4239       }
4240 */
4241       /* if the result is used in an arithmetic operation
4242          then put the result in place */
4243       if (AOP_TYPE(result) != AOP_CRY) 
4244         pic14_outAcc(result);
4245       /* leave the result in acc */
4246     }
4247
4248 release:
4249     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4250     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4251     freeAsmop(result,NULL,ic,TRUE);
4252 }
4253
4254 /*-----------------------------------------------------------------*/
4255 /* ifxForOp - returns the icode containing the ifx for operand     */
4256 /*-----------------------------------------------------------------*/
4257 static iCode *ifxForOp ( operand *op, iCode *ic )
4258 {
4259     /* if true symbol then needs to be assigned */
4260     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4261     if (IS_TRUE_SYMOP(op))
4262         return NULL ;
4263
4264     /* if this has register type condition and
4265     the next instruction is ifx with the same operand
4266     and live to of the operand is upto the ifx only then */
4267     if (ic->next &&
4268         ic->next->op == IFX &&
4269         IC_COND(ic->next)->key == op->key &&
4270         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4271         return ic->next;
4272
4273     if (ic->next &&
4274         ic->next->op == IFX &&
4275         IC_COND(ic->next)->key == op->key) {
4276       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4277       return ic->next;
4278     }
4279
4280     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4281     if (ic->next &&
4282         ic->next->op == IFX)
4283       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4284
4285     if (ic->next &&
4286         ic->next->op == IFX &&
4287         IC_COND(ic->next)->key == op->key) {
4288       DEBUGpic14_emitcode ("; "," key is okay");
4289       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4290                            OP_SYMBOL(op)->liveTo,
4291                            ic->next->seq);
4292     }
4293
4294
4295     return NULL;
4296 }
4297 /*-----------------------------------------------------------------*/
4298 /* genAndOp - for && operation                                     */
4299 /*-----------------------------------------------------------------*/
4300 static void genAndOp (iCode *ic)
4301 {
4302     operand *left,*right, *result;
4303     symbol *tlbl;
4304
4305     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4306     /* note here that && operations that are in an
4307     if statement are taken away by backPatchLabels
4308     only those used in arthmetic operations remain */
4309     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4310     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4311     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4312
4313     /* if both are bit variables */
4314     if (AOP_TYPE(left) == AOP_CRY &&
4315         AOP_TYPE(right) == AOP_CRY ) {
4316         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4317         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4318         pic14_outBitC(result);
4319     } else {
4320         tlbl = newiTempLabel(NULL);
4321         pic14_toBoolean(left);    
4322         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4323         pic14_toBoolean(right);
4324         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4325         pic14_outBitAcc(result);
4326     }
4327
4328     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4329     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4330     freeAsmop(result,NULL,ic,TRUE);
4331 }
4332
4333
4334 /*-----------------------------------------------------------------*/
4335 /* genOrOp - for || operation                                      */
4336 /*-----------------------------------------------------------------*/
4337 /*
4338   tsd pic port -
4339   modified this code, but it doesn't appear to ever get called
4340 */
4341
4342 static void genOrOp (iCode *ic)
4343 {
4344     operand *left,*right, *result;
4345     symbol *tlbl;
4346
4347     /* note here that || operations that are in an
4348     if statement are taken away by backPatchLabels
4349     only those used in arthmetic operations remain */
4350     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4351     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4352     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4353     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4354
4355     /* if both are bit variables */
4356     if (AOP_TYPE(left) == AOP_CRY &&
4357         AOP_TYPE(right) == AOP_CRY ) {
4358       pic14_emitcode("clrc","");
4359       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4360                AOP(left)->aopu.aop_dir,
4361                AOP(left)->aopu.aop_dir);
4362       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4363                AOP(right)->aopu.aop_dir,
4364                AOP(right)->aopu.aop_dir);
4365       pic14_emitcode("setc","");
4366
4367     } else {
4368         tlbl = newiTempLabel(NULL);
4369         pic14_toBoolean(left);
4370         emitSKPZ;
4371         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4372         pic14_toBoolean(right);
4373         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4374
4375         pic14_outBitAcc(result);
4376     }
4377
4378     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4379     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380     freeAsmop(result,NULL,ic,TRUE);            
4381 }
4382
4383 /*-----------------------------------------------------------------*/
4384 /* isLiteralBit - test if lit == 2^n                               */
4385 /*-----------------------------------------------------------------*/
4386 static int isLiteralBit(unsigned long lit)
4387 {
4388     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4389     0x100L,0x200L,0x400L,0x800L,
4390     0x1000L,0x2000L,0x4000L,0x8000L,
4391     0x10000L,0x20000L,0x40000L,0x80000L,
4392     0x100000L,0x200000L,0x400000L,0x800000L,
4393     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4394     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4395     int idx;
4396     
4397     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4398     for(idx = 0; idx < 32; idx++)
4399         if(lit == pw[idx])
4400             return idx+1;
4401     return 0;
4402 }
4403
4404 /*-----------------------------------------------------------------*/
4405 /* continueIfTrue -                                                */
4406 /*-----------------------------------------------------------------*/
4407 static void continueIfTrue (iCode *ic)
4408 {
4409     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4410     if(IC_TRUE(ic))
4411         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4412     ic->generated = 1;
4413 }
4414
4415 /*-----------------------------------------------------------------*/
4416 /* jmpIfTrue -                                                     */
4417 /*-----------------------------------------------------------------*/
4418 static void jumpIfTrue (iCode *ic)
4419 {
4420     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4421     if(!IC_TRUE(ic))
4422         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4423     ic->generated = 1;
4424 }
4425
4426 /*-----------------------------------------------------------------*/
4427 /* jmpTrueOrFalse -                                                */
4428 /*-----------------------------------------------------------------*/
4429 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4430 {
4431     // ugly but optimized by peephole
4432     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4433     if(IC_TRUE(ic)){
4434         symbol *nlbl = newiTempLabel(NULL);
4435         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
4436         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4437         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4438         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4439     }
4440     else{
4441         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4442         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4443     }
4444     ic->generated = 1;
4445 }
4446
4447 /*-----------------------------------------------------------------*/
4448 /* genAnd  - code for and                                          */
4449 /*-----------------------------------------------------------------*/
4450 static void genAnd (iCode *ic, iCode *ifx)
4451 {
4452   operand *left, *right, *result;
4453   int size, offset=0;  
4454   unsigned long lit = 0L;
4455   int bytelit = 0;
4456   resolvedIfx rIfx;
4457
4458
4459   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4460   aopOp((left = IC_LEFT(ic)),ic,FALSE);
4461   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4462   aopOp((result=IC_RESULT(ic)),ic,TRUE);
4463
4464   resolveIfx(&rIfx,ifx);
4465
4466   /* if left is a literal & right is not then exchange them */
4467   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4468       AOP_NEEDSACC(left)) {
4469     operand *tmp = right ;
4470     right = left;
4471     left = tmp;
4472   }
4473
4474   /* if result = right then exchange them */
4475   if(pic14_sameRegs(AOP(result),AOP(right))){
4476     operand *tmp = right ;
4477     right = left;
4478     left = tmp;
4479   }
4480
4481   /* if right is bit then exchange them */
4482   if (AOP_TYPE(right) == AOP_CRY &&
4483       AOP_TYPE(left) != AOP_CRY){
4484     operand *tmp = right ;
4485     right = left;
4486     left = tmp;
4487   }
4488   if(AOP_TYPE(right) == AOP_LIT)
4489     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4490
4491   size = AOP_SIZE(result);
4492
4493   DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4494                        AopType(AOP_TYPE(result)),
4495                        aopGet(AOP(result),0,TRUE,FALSE),
4496                        AopType(AOP_TYPE(left)),
4497                        aopGet(AOP(left),0,TRUE,FALSE),
4498                        AopType(AOP_TYPE(right)),
4499                        aopGet(AOP(right),0,FALSE,FALSE),
4500                        size);
4501   // if(bit & yy)
4502   // result = bit & yy;
4503   if (AOP_TYPE(left) == AOP_CRY){
4504     // c = bit & literal;
4505     if(AOP_TYPE(right) == AOP_LIT){
4506       if(lit & 1) {
4507         if(size && pic14_sameRegs(AOP(result),AOP(left)))
4508           // no change
4509           goto release;
4510         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4511       } else {
4512         // bit(result) = 0;
4513         if(size && (AOP_TYPE(result) == AOP_CRY)){
4514           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4515           goto release;
4516         }
4517         if((AOP_TYPE(result) == AOP_CRY) && ifx){
4518           jumpIfTrue(ifx);
4519           goto release;
4520         }
4521         pic14_emitcode("clr","c");
4522       }
4523     } else {
4524       if (AOP_TYPE(right) == AOP_CRY){
4525         // c = bit & bit;
4526         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4527         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4528       } else {
4529         // c = bit & val;
4530         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4531         // c = lsb
4532         pic14_emitcode("rrc","a");
4533         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4534       }
4535     }
4536     // bit = c
4537     // val = c
4538     if(size)
4539       pic14_outBitC(result);
4540     // if(bit & ...)
4541     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4542       genIfxJump(ifx, "c");           
4543     goto release ;
4544   }
4545
4546   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
4547   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
4548   if((AOP_TYPE(right) == AOP_LIT) &&
4549      (AOP_TYPE(result) == AOP_CRY) &&
4550      (AOP_TYPE(left) != AOP_CRY)){
4551     int posbit = isLiteralBit(lit);
4552     /* left &  2^n */
4553     if(posbit){
4554       posbit--;
4555       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4556       // bit = left & 2^n
4557       if(size)
4558         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4559       // if(left &  2^n)
4560       else{
4561         if(ifx){
4562 /*
4563           if(IC_TRUE(ifx)) {
4564             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4565             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4566           } else {
4567             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4568             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4569           }
4570 */
4571           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4572                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4573           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4574           
4575           ifx->generated = 1;
4576         }
4577         goto release;
4578       }
4579     } else {
4580       symbol *tlbl = newiTempLabel(NULL);
4581       int sizel = AOP_SIZE(left);
4582       if(size)
4583         pic14_emitcode("setb","c");
4584       while(sizel--){
4585         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4586           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4587           // byte ==  2^n ?
4588           if((posbit = isLiteralBit(bytelit)) != 0)
4589             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4590           else{
4591             if(bytelit != 0x0FFL)
4592               pic14_emitcode("anl","a,%s",
4593                              aopGet(AOP(right),offset,FALSE,TRUE));
4594             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4595           }
4596         }
4597         offset++;
4598       }
4599       // bit = left & literal
4600       if(size){
4601         pic14_emitcode("clr","c");
4602         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4603       }
4604       // if(left & literal)
4605       else{
4606         if(ifx)
4607           jmpTrueOrFalse(ifx, tlbl);
4608         goto release ;
4609       }
4610     }
4611     pic14_outBitC(result);
4612     goto release ;
4613   }
4614
4615   /* if left is same as result */
4616   if(pic14_sameRegs(AOP(result),AOP(left))){
4617     int know_W = -1;
4618     for(;size--; offset++,lit>>=8) {
4619       if(AOP_TYPE(right) == AOP_LIT){
4620         switch(lit & 0xff) {
4621         case 0x00:
4622           /*  and'ing with 0 has clears the result */
4623           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4624           emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4625           break;
4626         case 0xff:
4627           /* and'ing with 0xff is a nop when the result and left are the same */
4628           break;
4629
4630         default:
4631           {
4632             int p = my_powof2( (~lit) & 0xff );
4633             if(p>=0) {
4634               /* only one bit is set in the literal, so use a bcf instruction */
4635               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4636               //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4637               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4638
4639             } else {
4640               pic14_emitcode("movlw","0x%x", (lit & 0xff));
4641               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4642               if(know_W != (lit&0xff))
4643                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4644               know_W = lit &0xff;
4645               emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4646             }
4647           }    
4648         }
4649       } else {
4650         if (AOP_TYPE(left) == AOP_ACC) {
4651           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4652         } else {                    
4653           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4654           emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4655
4656         }
4657       }
4658     }
4659
4660   } else {
4661     // left & result in different registers
4662     if(AOP_TYPE(result) == AOP_CRY){
4663       // result = bit
4664       // if(size), result in bit
4665       // if(!size && ifx), conditional oper: if(left & right)
4666       symbol *tlbl = newiTempLabel(NULL);
4667       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4668       if(size)
4669         pic14_emitcode("setb","c");
4670       while(sizer--){
4671         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4672         pic14_emitcode("anl","a,%s",
4673                        aopGet(AOP(left),offset,FALSE,FALSE));
4674         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4675         offset++;
4676       }
4677       if(size){
4678         CLRC;
4679         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4680         pic14_outBitC(result);
4681       } else if(ifx)
4682         jmpTrueOrFalse(ifx, tlbl);
4683     } else {
4684       for(;(size--);offset++) {
4685         // normal case
4686         // result = left & right
4687         if(AOP_TYPE(right) == AOP_LIT){
4688           int t = (lit >> (offset*8)) & 0x0FFL;
4689           switch(t) { 
4690           case 0x00:
4691             pic14_emitcode("clrf","%s",
4692                            aopGet(AOP(result),offset,FALSE,FALSE));
4693             emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4694             break;
4695           case 0xff:
4696             pic14_emitcode("movf","%s,w",
4697                            aopGet(AOP(left),offset,FALSE,FALSE));
4698             pic14_emitcode("movwf","%s",
4699                            aopGet(AOP(result),offset,FALSE,FALSE));
4700             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4701             emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4702             break;
4703           default:
4704             pic14_emitcode("movlw","0x%x",t);
4705             pic14_emitcode("andwf","%s,w",
4706                            aopGet(AOP(left),offset,FALSE,FALSE));
4707             pic14_emitcode("movwf","%s",
4708                            aopGet(AOP(result),offset,FALSE,FALSE));
4709               
4710             emitpcode(POC_MOVLW, popGetLit(t));
4711             emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4712             emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4713           }
4714           continue;
4715         }
4716
4717         if (AOP_TYPE(left) == AOP_ACC) {
4718           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4719           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4720         } else {
4721           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4722           pic14_emitcode("andwf","%s,w",
4723                          aopGet(AOP(left),offset,FALSE,FALSE));
4724           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4725           emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4726         }
4727         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4728         emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4729       }
4730     }
4731   }
4732
4733   release :
4734     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4735   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4736   freeAsmop(result,NULL,ic,TRUE);     
4737 }
4738
4739 /*-----------------------------------------------------------------*/
4740 /* genOr  - code for or                                            */
4741 /*-----------------------------------------------------------------*/
4742 static void genOr (iCode *ic, iCode *ifx)
4743 {
4744     operand *left, *right, *result;
4745     int size, offset=0;
4746     unsigned long lit = 0L;
4747
4748     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4749
4750     aopOp((left = IC_LEFT(ic)),ic,FALSE);
4751     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4752     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4753
4754
4755     /* if left is a literal & right is not then exchange them */
4756     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4757         AOP_NEEDSACC(left)) {
4758         operand *tmp = right ;
4759         right = left;
4760         left = tmp;
4761     }
4762
4763     /* if result = right then exchange them */
4764     if(pic14_sameRegs(AOP(result),AOP(right))){
4765         operand *tmp = right ;
4766         right = left;
4767         left = tmp;
4768     }
4769
4770     /* if right is bit then exchange them */
4771     if (AOP_TYPE(right) == AOP_CRY &&
4772         AOP_TYPE(left) != AOP_CRY){
4773         operand *tmp = right ;
4774         right = left;
4775         left = tmp;
4776     }
4777
4778     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4779                          AopType(AOP_TYPE(result)),
4780                          AopType(AOP_TYPE(left)),
4781                          AopType(AOP_TYPE(right)));
4782
4783     if(AOP_TYPE(right) == AOP_LIT)
4784         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4785
4786     size = AOP_SIZE(result);
4787
4788     // if(bit | yy)
4789     // xx = bit | yy;
4790     if (AOP_TYPE(left) == AOP_CRY){
4791         if(AOP_TYPE(right) == AOP_LIT){
4792             // c = bit & literal;
4793             if(lit){
4794                 // lit != 0 => result = 1
4795                 if(AOP_TYPE(result) == AOP_CRY){
4796                   if(size)
4797                     emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4798                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4799                   //     AOP(result)->aopu.aop_dir,
4800                   //     AOP(result)->aopu.aop_dir);
4801                     else if(ifx)
4802                         continueIfTrue(ifx);
4803                     goto release;
4804                 }
4805             } else {
4806                 // lit == 0 => result = left
4807                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4808                     goto release;
4809                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4810             }
4811         } else {
4812             if (AOP_TYPE(right) == AOP_CRY){
4813               if(pic14_sameRegs(AOP(result),AOP(left))){
4814                 // c = bit | bit;
4815                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4816                 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4817                 emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4818
4819                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4820                          AOP(result)->aopu.aop_dir,
4821                          AOP(result)->aopu.aop_dir);
4822                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4823                          AOP(right)->aopu.aop_dir,
4824                          AOP(right)->aopu.aop_dir);
4825                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4826                          AOP(result)->aopu.aop_dir,
4827                          AOP(result)->aopu.aop_dir);
4828               } else {
4829                 if( AOP_TYPE(result) == AOP_ACC) {
4830                   emitpcode(POC_MOVLW, popGetLit(0));
4831                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4832                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4833                   emitpcode(POC_MOVLW, popGetLit(1));
4834
4835                 } else {
4836
4837                   emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4838                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4839                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4840                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4841
4842                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4843                                  AOP(result)->aopu.aop_dir,
4844                                  AOP(result)->aopu.aop_dir);
4845                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4846                                  AOP(right)->aopu.aop_dir,
4847                                  AOP(right)->aopu.aop_dir);
4848                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4849                                  AOP(left)->aopu.aop_dir,
4850                                  AOP(left)->aopu.aop_dir);
4851                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4852                                  AOP(result)->aopu.aop_dir,
4853                                  AOP(result)->aopu.aop_dir);
4854                 }
4855               }
4856             } else {
4857                 // c = bit | val;
4858                 symbol *tlbl = newiTempLabel(NULL);
4859                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4860
4861
4862                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4863                 if( AOP_TYPE(right) == AOP_ACC) {
4864                   emitpcode(POC_IORLW, popGetLit(0));
4865                   emitSKPNZ;
4866                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4867                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4868                 }
4869
4870
4871
4872                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4873                     pic14_emitcode(";XXX setb","c");
4874                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4875                          AOP(left)->aopu.aop_dir,tlbl->key+100);
4876                 pic14_toBoolean(right);
4877                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4878                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4879                     jmpTrueOrFalse(ifx, tlbl);
4880                     goto release;
4881                 } else {
4882                     CLRC;
4883                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4884                 }
4885             }
4886         }
4887         // bit = c
4888         // val = c
4889         if(size)
4890             pic14_outBitC(result);
4891         // if(bit | ...)
4892         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4893             genIfxJump(ifx, "c");           
4894         goto release ;
4895     }
4896
4897     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
4898     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
4899     if((AOP_TYPE(right) == AOP_LIT) &&
4900        (AOP_TYPE(result) == AOP_CRY) &&
4901        (AOP_TYPE(left) != AOP_CRY)){
4902         if(lit){
4903           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4904             // result = 1
4905             if(size)
4906                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4907             else 
4908                 continueIfTrue(ifx);
4909             goto release;
4910         } else {
4911           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4912             // lit = 0, result = boolean(left)
4913             if(size)
4914                 pic14_emitcode(";XXX setb","c");
4915             pic14_toBoolean(right);
4916             if(size){
4917                 symbol *tlbl = newiTempLabel(NULL);
4918                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4919                 CLRC;
4920                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4921             } else {
4922                 genIfxJump (ifx,"a");
4923                 goto release;
4924             }
4925         }
4926         pic14_outBitC(result);
4927         goto release ;
4928     }
4929
4930     /* if left is same as result */
4931     if(pic14_sameRegs(AOP(result),AOP(left))){
4932       int know_W = -1;
4933       for(;size--; offset++,lit>>=8) {
4934         if(AOP_TYPE(right) == AOP_LIT){
4935           if((lit & 0xff) == 0)
4936             /*  or'ing with 0 has no effect */
4937             continue;
4938           else {
4939             int p = my_powof2(lit & 0xff);
4940             if(p>=0) {
4941               /* only one bit is set in the literal, so use a bsf instruction */
4942               emitpcode(POC_BSF,
4943                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4944             } else {
4945               if(know_W != (lit & 0xff))
4946                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4947               know_W = lit & 0xff;
4948               emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4949             }
4950                     
4951           }
4952         } else {
4953           if (AOP_TYPE(left) == AOP_ACC) {
4954             emitpcode(POC_IORFW,  popGet(AOP(right),offset,FALSE,FALSE));
4955             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4956           } else {                  
4957             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
4958             emitpcode(POC_IORWF,  popGet(AOP(left),offset,FALSE,FALSE));
4959
4960             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4961             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4962
4963           }
4964         }
4965       }
4966     } else {
4967         // left & result in different registers
4968         if(AOP_TYPE(result) == AOP_CRY){
4969             // result = bit
4970             // if(size), result in bit
4971             // if(!size && ifx), conditional oper: if(left | right)
4972             symbol *tlbl = newiTempLabel(NULL);
4973             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4974             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4975
4976
4977             if(size)
4978                 pic14_emitcode(";XXX setb","c");
4979             while(sizer--){
4980                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4981                 pic14_emitcode(";XXX orl","a,%s",
4982                          aopGet(AOP(left),offset,FALSE,FALSE));
4983                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4984                 offset++;
4985             }
4986             if(size){
4987                 CLRC;
4988                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4989                 pic14_outBitC(result);
4990             } else if(ifx)
4991                 jmpTrueOrFalse(ifx, tlbl);
4992         } else for(;(size--);offset++){
4993           // normal case
4994           // result = left & right
4995           if(AOP_TYPE(right) == AOP_LIT){
4996             int t = (lit >> (offset*8)) & 0x0FFL;
4997             switch(t) { 
4998             case 0x00:
4999               emitpcode(POC_MOVFW,  popGet(AOP(left),offset,FALSE,FALSE));
5000               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5001
5002               pic14_emitcode("movf","%s,w",
5003                        aopGet(AOP(left),offset,FALSE,FALSE));
5004               pic14_emitcode("movwf","%s",
5005                        aopGet(AOP(result),offset,FALSE,FALSE));
5006               break;
5007             default:
5008               emitpcode(POC_MOVLW,  popGetLit(t));
5009               emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
5010               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5011
5012               pic14_emitcode("movlw","0x%x",t);
5013               pic14_emitcode("iorwf","%s,w",
5014                        aopGet(AOP(left),offset,FALSE,FALSE));
5015               pic14_emitcode("movwf","%s",
5016                        aopGet(AOP(result),offset,FALSE,FALSE));
5017               
5018             }
5019             continue;
5020           }
5021
5022           // faster than result <- left, anl result,right
5023           // and better if result is SFR
5024           if (AOP_TYPE(left) == AOP_ACC) {
5025             emitpcode(POC_IORWF,  popGet(AOP(right),offset,FALSE,FALSE));
5026             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5027           } else {
5028             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
5029             emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
5030
5031             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5032             pic14_emitcode("iorwf","%s,w",
5033                      aopGet(AOP(left),offset,FALSE,FALSE));
5034           }
5035           emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5036           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5037         }
5038     }
5039
5040 release :
5041     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5043     freeAsmop(result,NULL,ic,TRUE);     
5044 }
5045
5046 /*-----------------------------------------------------------------*/
5047 /* genXor - code for xclusive or                                   */
5048 /*-----------------------------------------------------------------*/
5049 static void genXor (iCode *ic, iCode *ifx)
5050 {
5051     operand *left, *right, *result;
5052     int size, offset=0;
5053     unsigned long lit = 0L;
5054
5055     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5056
5057     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5058     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5059     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5060
5061     /* if left is a literal & right is not ||
5062        if left needs acc & right does not */
5063     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5064         (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5065         operand *tmp = right ;
5066         right = left;
5067         left = tmp;
5068     }
5069
5070     /* if result = right then exchange them */
5071     if(pic14_sameRegs(AOP(result),AOP(right))){
5072         operand *tmp = right ;
5073         right = left;
5074         left = tmp;
5075     }
5076
5077     /* if right is bit then exchange them */
5078     if (AOP_TYPE(right) == AOP_CRY &&
5079         AOP_TYPE(left) != AOP_CRY){
5080         operand *tmp = right ;
5081         right = left;
5082         left = tmp;
5083     }
5084     if(AOP_TYPE(right) == AOP_LIT)
5085         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5086
5087     size = AOP_SIZE(result);
5088
5089     // if(bit ^ yy)
5090     // xx = bit ^ yy;
5091     if (AOP_TYPE(left) == AOP_CRY){
5092         if(AOP_TYPE(right) == AOP_LIT){
5093             // c = bit & literal;
5094             if(lit>>1){
5095                 // lit>>1  != 0 => result = 1
5096                 if(AOP_TYPE(result) == AOP_CRY){
5097                     if(size)
5098                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5099                     else if(ifx)
5100                         continueIfTrue(ifx);
5101                     goto release;
5102                 }
5103                 pic14_emitcode("setb","c");
5104             } else{
5105                 // lit == (0 or 1)
5106                 if(lit == 0){
5107                     // lit == 0, result = left
5108                     if(size && pic14_sameRegs(AOP(result),AOP(left)))
5109                         goto release;
5110                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5111                 } else{
5112                     // lit == 1, result = not(left)
5113                     if(size && pic14_sameRegs(AOP(result),AOP(left))){
5114                         pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5115                         goto release;
5116                     } else {
5117                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5118                         pic14_emitcode("cpl","c");
5119                     }
5120                 }
5121             }
5122
5123         } else {
5124             // right != literal
5125             symbol *tlbl = newiTempLabel(NULL);
5126             if (AOP_TYPE(right) == AOP_CRY){
5127                 // c = bit ^ bit;
5128                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5129             }
5130             else{
5131                 int sizer = AOP_SIZE(right);
5132                 // c = bit ^ val
5133                 // if val>>1 != 0, result = 1
5134                 pic14_emitcode("setb","c");
5135                 while(sizer){
5136                     MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5137                     if(sizer == 1)
5138                         // test the msb of the lsb
5139                         pic14_emitcode("anl","a,#0xfe");
5140                     pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5141                     sizer--;
5142                 }
5143                 // val = (0,1)
5144                 pic14_emitcode("rrc","a");
5145             }
5146             pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5147             pic14_emitcode("cpl","c");
5148             pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5149         }
5150         // bit = c
5151         // val = c
5152         if(size)
5153             pic14_outBitC(result);
5154         // if(bit | ...)
5155         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5156             genIfxJump(ifx, "c");           
5157         goto release ;
5158     }
5159
5160     if(pic14_sameRegs(AOP(result),AOP(left))){
5161         /* if left is same as result */
5162         for(;size--; offset++) {
5163             if(AOP_TYPE(right) == AOP_LIT){
5164               int t  = (lit >> (offset*8)) & 0x0FFL;
5165                 if(t == 0x00L)
5166                     continue;
5167                 else
5168                     if (IS_AOP_PREG(left)) {
5169                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5170                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5171                         aopPut(AOP(result),"a",offset);
5172                     } else {
5173                       emitpcode(POC_MOVLW, popGetLit(t));
5174                       emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5175                       pic14_emitcode("xrl","%s,%s",
5176                                      aopGet(AOP(left),offset,FALSE,TRUE),
5177                                      aopGet(AOP(right),offset,FALSE,FALSE));
5178                     }
5179             } else {
5180                 if (AOP_TYPE(left) == AOP_ACC)
5181                     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5182                 else {
5183                     MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5184                     if (IS_AOP_PREG(left)) {
5185                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5186                         aopPut(AOP(result),"a",offset);
5187                     } else
5188                         pic14_emitcode("xrl","%s,a",
5189                                  aopGet(AOP(left),offset,FALSE,TRUE));
5190                 }
5191             }
5192         }
5193     } else {
5194         // left & result in different registers
5195         if(AOP_TYPE(result) == AOP_CRY){
5196             // result = bit
5197             // if(size), result in bit
5198             // if(!size && ifx), conditional oper: if(left ^ right)
5199             symbol *tlbl = newiTempLabel(NULL);
5200             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5201             if(size)
5202                 pic14_emitcode("setb","c");
5203             while(sizer--){
5204                 if((AOP_TYPE(right) == AOP_LIT) &&
5205                    (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5206                     MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5207                 } else {
5208                     MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5209                     pic14_emitcode("xrl","a,%s",
5210                              aopGet(AOP(left),offset,FALSE,FALSE));
5211                 }
5212                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5213                 offset++;
5214             }
5215             if(size){
5216                 CLRC;
5217                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5218                 pic14_outBitC(result);
5219             } else if(ifx)
5220                 jmpTrueOrFalse(ifx, tlbl);
5221         } else for(;(size--);offset++){
5222             // normal case
5223             // result = left & right
5224             if(AOP_TYPE(right) == AOP_LIT){
5225               int t = (lit >> (offset*8)) & 0x0FFL;
5226               switch(t) { 
5227               case 0x00:
5228                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5229                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5230                 pic14_emitcode("movf","%s,w",
5231                          aopGet(AOP(left),offset,FALSE,FALSE));
5232                 pic14_emitcode("movwf","%s",
5233                          aopGet(AOP(result),offset,FALSE,FALSE));
5234                 break;
5235               case 0xff:
5236                 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5237                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5238                 pic14_emitcode("comf","%s,w",
5239                          aopGet(AOP(left),offset,FALSE,FALSE));
5240                 pic14_emitcode("movwf","%s",
5241                          aopGet(AOP(result),offset,FALSE,FALSE));
5242                 break;
5243               default:
5244                 emitpcode(POC_MOVLW, popGetLit(t));
5245                 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5246                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5247                 pic14_emitcode("movlw","0x%x",t);
5248                 pic14_emitcode("xorwf","%s,w",
5249                          aopGet(AOP(left),offset,FALSE,FALSE));
5250                 pic14_emitcode("movwf","%s",
5251                          aopGet(AOP(result),offset,FALSE,FALSE));
5252
5253               }
5254               continue;
5255             }
5256
5257             // faster than result <- left, anl result,right
5258             // and better if result is SFR
5259             if (AOP_TYPE(left) == AOP_ACC) {
5260                 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5261                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5262             } else {
5263                 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5264                 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5265                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5266                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5267             }
5268             if ( AOP_TYPE(result) != AOP_ACC){
5269                 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5270               pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5271             }
5272         }
5273     }
5274
5275 release :
5276     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5277     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5278     freeAsmop(result,NULL,ic,TRUE);     
5279 }
5280
5281 /*-----------------------------------------------------------------*/
5282 /* genInline - write the inline code out                           */
5283 /*-----------------------------------------------------------------*/
5284 static void genInline (iCode *ic)
5285 {
5286     char *buffer, *bp, *bp1;
5287     
5288     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5289
5290     _G.inLine += (!options.asmpeep);
5291
5292     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5293     strcpy(buffer,IC_INLINE(ic));
5294
5295     /* emit each line as a code */
5296     while (*bp) {
5297         if (*bp == '\n') {
5298             *bp++ = '\0';
5299             pic14_emitcode(bp1,"");
5300             bp1 = bp;
5301         } else {
5302             if (*bp == ':') {
5303                 bp++;
5304                 *bp = '\0';
5305                 bp++;
5306                 pic14_emitcode(bp1,"");
5307                 bp1 = bp;
5308             } else
5309                 bp++;
5310         }
5311     }
5312     if (bp1 != bp)
5313         pic14_emitcode(bp1,"");
5314     /*     pic14_emitcode("",buffer); */
5315     _G.inLine -= (!options.asmpeep);
5316 }
5317
5318 /*-----------------------------------------------------------------*/
5319 /* genRRC - rotate right with carry                                */
5320 /*-----------------------------------------------------------------*/
5321 static void genRRC (iCode *ic)
5322 {
5323     operand *left , *result ;
5324     int size, offset = 0;
5325     char *l;    
5326
5327     /* rotate right with carry */
5328     left = IC_LEFT(ic);
5329     result=IC_RESULT(ic);
5330     aopOp (left,ic,FALSE);
5331     aopOp (result,ic,FALSE);
5332
5333     /* move it to the result */
5334     size = AOP_SIZE(result);    
5335     offset = size - 1 ;
5336     CLRC;
5337     while (size--) {
5338         l = aopGet(AOP(left),offset,FALSE,FALSE);
5339         MOVA(l);
5340         pic14_emitcode("rrc","a");
5341         if (AOP_SIZE(result) > 1)
5342             aopPut(AOP(result),"a",offset--);
5343     }
5344     /* now we need to put the carry into the
5345     highest order byte of the result */
5346     if (AOP_SIZE(result) > 1) {
5347         l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5348         MOVA(l);
5349     }
5350     pic14_emitcode("mov","acc.7,c");
5351     aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5352     freeAsmop(left,NULL,ic,TRUE);
5353     freeAsmop(result,NULL,ic,TRUE);
5354 }
5355
5356 /*-----------------------------------------------------------------*/
5357 /* genRLC - generate code for rotate left with carry               */
5358 /*-----------------------------------------------------------------*/
5359 static void genRLC (iCode *ic)
5360 {    
5361     operand *left , *result ;
5362     int size, offset = 0;
5363     char *l;    
5364
5365     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5366     /* rotate right with carry */
5367     left = IC_LEFT(ic);
5368     result=IC_RESULT(ic);
5369     aopOp (left,ic,FALSE);
5370     aopOp (result,ic,FALSE);
5371
5372     /* move it to the result */
5373     size = AOP_SIZE(result);    
5374     offset = 0 ;
5375     if (size--) {
5376         l = aopGet(AOP(left),offset,FALSE,FALSE);
5377         MOVA(l);
5378         pic14_emitcode("add","a,acc");
5379         if (AOP_SIZE(result) > 1)
5380             aopPut(AOP(result),"a",offset++);
5381         while (size--) {
5382             l = aopGet(AOP(left),offset,FALSE,FALSE);
5383             MOVA(l);
5384             pic14_emitcode("rlc","a");
5385             if (AOP_SIZE(result) > 1)
5386                 aopPut(AOP(result),"a",offset++);
5387         }
5388     }
5389     /* now we need to put the carry into the
5390     highest order byte of the result */
5391     if (AOP_SIZE(result) > 1) {
5392         l = aopGet(AOP(result),0,FALSE,FALSE);
5393         MOVA(l);
5394     }
5395     pic14_emitcode("mov","acc.0,c");
5396     aopPut(AOP(result),"a",0);
5397     freeAsmop(left,NULL,ic,TRUE);
5398     freeAsmop(result,NULL,ic,TRUE);
5399 }
5400
5401 /*-----------------------------------------------------------------*/
5402 /* genGetHbit - generates code get highest order bit               */
5403 /*-----------------------------------------------------------------*/
5404 static void genGetHbit (iCode *ic)
5405 {
5406     operand *left, *result;
5407     left = IC_LEFT(ic);
5408     result=IC_RESULT(ic);
5409     aopOp (left,ic,FALSE);
5410     aopOp (result,ic,FALSE);
5411
5412     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5413     /* get the highest order byte into a */
5414     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5415     if(AOP_TYPE(result) == AOP_CRY){
5416         pic14_emitcode("rlc","a");
5417         pic14_outBitC(result);
5418     }
5419     else{
5420         pic14_emitcode("rl","a");
5421         pic14_emitcode("anl","a,#0x01");
5422         pic14_outAcc(result);
5423     }
5424
5425
5426     freeAsmop(left,NULL,ic,TRUE);
5427     freeAsmop(result,NULL,ic,TRUE);
5428 }
5429
5430 /*-----------------------------------------------------------------*/
5431 /* AccRol - rotate left accumulator by known count                 */
5432 /*-----------------------------------------------------------------*/
5433 static void AccRol (int shCount)
5434 {
5435     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5436     shCount &= 0x0007;              // shCount : 0..7
5437     switch(shCount){
5438         case 0 :
5439             break;
5440         case 1 :
5441             pic14_emitcode("rl","a");
5442             break;
5443         case 2 :
5444             pic14_emitcode("rl","a");
5445             pic14_emitcode("rl","a");
5446             break;
5447         case 3 :
5448             pic14_emitcode("swap","a");
5449             pic14_emitcode("rr","a");
5450             break;
5451         case 4 :
5452             pic14_emitcode("swap","a");
5453             break;
5454         case 5 :
5455             pic14_emitcode("swap","a");
5456             pic14_emitcode("rl","a");
5457             break;
5458         case 6 :
5459             pic14_emitcode("rr","a");
5460             pic14_emitcode("rr","a");
5461             break;
5462         case 7 :
5463             pic14_emitcode("rr","a");
5464             break;
5465     }
5466 }
5467
5468 /*-----------------------------------------------------------------*/
5469 /* AccLsh - left shift accumulator by known count                  */
5470 /*-----------------------------------------------------------------*/
5471 static void AccLsh (int shCount)
5472 {
5473     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5474     if(shCount != 0){
5475         if(shCount == 1)
5476             pic14_emitcode("add","a,acc");
5477         else 
5478             if(shCount == 2) {
5479             pic14_emitcode("add","a,acc");
5480             pic14_emitcode("add","a,acc");
5481         } else {
5482             /* rotate left accumulator */
5483             AccRol(shCount);
5484             /* and kill the lower order bits */
5485             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5486         }
5487     }
5488 }
5489
5490 /*-----------------------------------------------------------------*/
5491 /* AccRsh - right shift accumulator by known count                 */
5492 /*-----------------------------------------------------------------*/
5493 static void AccRsh (int shCount)
5494 {
5495     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5496     if(shCount != 0){
5497         if(shCount == 1){
5498             CLRC;
5499             pic14_emitcode("rrc","a");
5500         } else {
5501             /* rotate right accumulator */
5502             AccRol(8 - shCount);
5503             /* and kill the higher order bits */
5504             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5505         }
5506     }
5507 }
5508
5509 #if 0
5510 /*-----------------------------------------------------------------*/
5511 /* AccSRsh - signed right shift accumulator by known count                 */
5512 /*-----------------------------------------------------------------*/
5513 static void AccSRsh (int shCount)
5514 {
5515     symbol *tlbl ;
5516     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5517     if(shCount != 0){
5518         if(shCount == 1){
5519             pic14_emitcode("mov","c,acc.7");
5520             pic14_emitcode("rrc","a");
5521         } else if(shCount == 2){
5522             pic14_emitcode("mov","c,acc.7");
5523             pic14_emitcode("rrc","a");
5524             pic14_emitcode("mov","c,acc.7");
5525             pic14_emitcode("rrc","a");
5526         } else {
5527             tlbl = newiTempLabel(NULL);
5528             /* rotate right accumulator */
5529             AccRol(8 - shCount);
5530             /* and kill the higher order bits */
5531             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5532             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5533             pic14_emitcode("orl","a,#0x%02x",
5534                      (unsigned char)~SRMask[shCount]);
5535             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5536         }
5537     }
5538 }
5539 #endif
5540 /*-----------------------------------------------------------------*/
5541 /* shiftR1Left2Result - shift right one byte from left to result   */
5542 /*-----------------------------------------------------------------*/
5543 static void shiftR1Left2ResultSigned (operand *left, int offl,
5544                                 operand *result, int offr,
5545                                 int shCount)
5546 {
5547   int same;
5548
5549   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5550
5551   same = (left == result) || (AOP(left) == AOP(result));
5552
5553   switch(shCount) {
5554   case 1:
5555     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5556     if(same) 
5557       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5558     else {
5559       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5560       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5561     }
5562
5563     break;
5564
5565   default:
5566     break;
5567   }
5568 }
5569
5570 /*-----------------------------------------------------------------*/
5571 /* shiftR1Left2Result - shift right one byte from left to result   */
5572 /*-----------------------------------------------------------------*/
5573 static void shiftR1Left2Result (operand *left, int offl,
5574                                 operand *result, int offr,
5575                                 int shCount, int sign)
5576 {
5577   int same;
5578
5579   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5580
5581   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5582
5583   /* Copy the msb into the carry if signed. */
5584   if(sign) {
5585     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5586     return;
5587   }
5588
5589
5590
5591   switch(shCount) {
5592   case 1:
5593     emitCLRC;
5594     if(same) 
5595       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5596     else {
5597       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5598       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5599     }
5600     break;
5601   case 2:
5602     emitCLRC;
5603     if(same) {
5604       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5605     } else {
5606       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5607       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5608     }
5609     emitCLRC;
5610     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5611
5612     break;
5613   case 3:
5614     if(same) 
5615       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5616     else {
5617       emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5618       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5619     }
5620
5621     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5622     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5623     emitpcode(POC_ANDLW, popGetLit(0x1f));
5624     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5625     break;
5626       
5627   case 4:
5628     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5629     emitpcode(POC_ANDLW, popGetLit(0x0f));
5630     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5631     break;
5632
5633   case 5:
5634     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5635     emitpcode(POC_ANDLW, popGetLit(0x0f));
5636     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5637     emitCLRC;
5638     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5639
5640     break;
5641   case 6:
5642
5643     emitpcode(POC_RLFW,  popGet(AOP(left),offl,FALSE,FALSE));
5644     emitpcode(POC_ANDLW, popGetLit(0x80));
5645     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5646     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5647     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5648     break;
5649
5650   case 7:
5651
5652     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5653     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5654     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5655
5656     break;
5657
5658   default:
5659     break;
5660   }
5661
5662
5663 #if 0
5664     
5665   MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5666
5667   /* shift right accumulator */
5668   if(sign)
5669     AccSRsh(shCount);
5670   else
5671     AccRsh(shCount);
5672   aopPut(AOP(result),"a",offr);
5673 #endif
5674 }
5675
5676 /*-----------------------------------------------------------------*/
5677 /* shiftL1Left2Result - shift left one byte from left to result    */
5678 /*-----------------------------------------------------------------*/
5679 static void shiftL1Left2Result (operand *left, int offl,
5680                                 operand *result, int offr, int shCount)
5681 {
5682   int same;
5683
5684   //    char *l;
5685   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5686
5687   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5688   DEBUGpic14_emitcode ("; ***","same =  %d",same);
5689     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
5690     //    MOVA(l);
5691     /* shift left accumulator */
5692     //AccLsh(shCount); // don't comment out just yet...
5693   //    aopPut(AOP(result),"a",offr);
5694
5695   switch(shCount) {
5696   case 1:
5697     /* Shift left 1 bit position */
5698     emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5699     if(same) {
5700       emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5701     } else {
5702       emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5703       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5704     }
5705     break;
5706   case 2:
5707     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5708     emitpcode(POC_ANDLW,popGetLit(0x7e));
5709     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5710     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5711     break;
5712   case 3:
5713     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5714     emitpcode(POC_ANDLW,popGetLit(0x3e));
5715     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5716     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5717     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5718     break;
5719   case 4:
5720     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5721     emitpcode(POC_ANDLW, popGetLit(0xf0));
5722     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5723     break;
5724   case 5:
5725     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5726     emitpcode(POC_ANDLW, popGetLit(0xf0));
5727     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5728     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5729     break;
5730   case 6:
5731     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5732     emitpcode(POC_ANDLW, popGetLit(0x30));
5733     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5734     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5735     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5736     break;
5737   case 7:
5738     emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5739     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5740     emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
5741     break;
5742
5743   default:
5744     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5745   }
5746
5747 }
5748
5749 /*-----------------------------------------------------------------*/
5750 /* movLeft2Result - move byte from left to result                  */
5751 /*-----------------------------------------------------------------*/
5752 static void movLeft2Result (operand *left, int offl,
5753                             operand *result, int offr, int sign)
5754 {
5755     char *l;
5756     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5757     if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5758         l = aopGet(AOP(left),offl,FALSE,FALSE);
5759
5760         if (*l == '@' && (IS_AOP_PREG(result))) {
5761             pic14_emitcode("mov","a,%s",l);
5762             aopPut(AOP(result),"a",offr);
5763         } else {
5764           if(!sign) {
5765             emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5766             emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5767
5768             //aopPut(AOP(result),l,offr);
5769           }else{
5770                 /* MSB sign in acc.7 ! */
5771                 if(pic14_getDataSize(left) == offl+1){
5772                     pic14_emitcode("mov","a,%s",l);
5773                     aopPut(AOP(result),"a",offr);
5774                 }
5775             }
5776         }
5777     }
5778 }
5779
5780 /*-----------------------------------------------------------------*/
5781 /* AccAXRrl1 - right rotate c->a:x->c by 1                         */
5782 /*-----------------------------------------------------------------*/
5783 static void AccAXRrl1 (char *x)
5784 {
5785     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5786     pic14_emitcode("rrc","a");
5787     pic14_emitcode("xch","a,%s", x);
5788     pic14_emitcode("rrc","a");
5789     pic14_emitcode("xch","a,%s", x);
5790 }
5791
5792 /*-----------------------------------------------------------------*/
5793 /* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
5794 /*-----------------------------------------------------------------*/
5795 static void AccAXLrl1 (char *x)
5796 {
5797     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5798     pic14_emitcode("xch","a,%s",x);
5799     pic14_emitcode("rlc","a");
5800     pic14_emitcode("xch","a,%s",x);
5801     pic14_emitcode("rlc","a");
5802 }
5803 #if 0
5804 /*-----------------------------------------------------------------*/
5805 /* AccAXLsh1 - left shift a:x<-0 by 1                              */
5806 /*-----------------------------------------------------------------*/
5807 static void AccAXLsh1 (char *x)
5808 {
5809     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5810     pic14_emitcode("xch","a,%s",x);
5811     pic14_emitcode("add","a,acc");
5812     pic14_emitcode("xch","a,%s",x);
5813     pic14_emitcode("rlc","a");
5814 }
5815 #endif
5816 #if 0
5817 /*-----------------------------------------------------------------*/
5818 /* AccAXLsh - left shift a:x by known count (0..7)                 */
5819 /*-----------------------------------------------------------------*/
5820 static void AccAXLsh (char *x, int shCount)
5821 {
5822     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5823     switch(shCount){
5824         case 0 :
5825             break;
5826         case 1 :
5827             AccAXLsh1(x);
5828             break;
5829         case 2 :
5830             AccAXLsh1(x);
5831             AccAXLsh1(x);
5832             break;
5833         case 3 :
5834         case 4 :
5835         case 5 :                        // AAAAABBB:CCCCCDDD
5836             AccRol(shCount);            // BBBAAAAA:CCCCCDDD
5837             pic14_emitcode("anl","a,#0x%02x",
5838                      SLMask[shCount]);  // BBB00000:CCCCCDDD
5839             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBB00000
5840             AccRol(shCount);            // DDDCCCCC:BBB00000
5841             pic14_emitcode("xch","a,%s",x);   // BBB00000:DDDCCCCC
5842             pic14_emitcode("xrl","a,%s",x);   // (BBB^DDD)CCCCC:DDDCCCCC
5843             pic14_emitcode("xch","a,%s",x);   // DDDCCCCC:(BBB^DDD)CCCCC
5844             pic14_emitcode("anl","a,#0x%02x",
5845                      SLMask[shCount]);  // DDD00000:(BBB^DDD)CCCCC
5846             pic14_emitcode("xch","a,%s",x);   // (BBB^DDD)CCCCC:DDD00000
5847             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:DDD00000            
5848             break;
5849         case 6 :                        // AAAAAABB:CCCCCCDD
5850             pic14_emitcode("anl","a,#0x%02x",
5851                      SRMask[shCount]);  // 000000BB:CCCCCCDD
5852             pic14_emitcode("mov","c,acc.0");  // c = B
5853             pic14_emitcode("xch","a,%s",x);   // CCCCCCDD:000000BB
5854             AccAXRrl1(x);               // BCCCCCCD:D000000B
5855             AccAXRrl1(x);               // BBCCCCCC:DD000000
5856             break;
5857         case 7 :                        // a:x <<= 7
5858             pic14_emitcode("anl","a,#0x%02x",
5859                      SRMask[shCount]);  // 0000000B:CCCCCCCD
5860             pic14_emitcode("mov","c,acc.0");  // c = B
5861             pic14_emitcode("xch","a,%s",x);   // CCCCCCCD:0000000B
5862             AccAXRrl1(x);               // BCCCCCCC:D0000000
5863             break;
5864         default :
5865             break;
5866     }
5867 }
5868 #endif
5869 #if 0
5870 /*-----------------------------------------------------------------*/
5871 /* AccAXRsh - right shift a:x known count (0..7)                   */
5872 /*-----------------------------------------------------------------*/
5873 static void AccAXRsh (char *x, int shCount)
5874 {   
5875     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5876     switch(shCount){
5877         case 0 :
5878             break;
5879         case 1 :
5880             CLRC;
5881             AccAXRrl1(x);               // 0->a:x
5882             break;
5883         case 2 :
5884             CLRC;
5885             AccAXRrl1(x);               // 0->a:x
5886             CLRC;
5887             AccAXRrl1(x);               // 0->a:x
5888             break;
5889         case 3 :
5890         case 4 :
5891         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
5892             AccRol(8 - shCount);        // BBBAAAAA:DDDCCCCC
5893             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
5894             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
5895             pic14_emitcode("anl","a,#0x%02x",
5896                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
5897             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
5898             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
5899             pic14_emitcode("anl","a,#0x%02x",
5900                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
5901             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
5902             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
5903             pic14_emitcode("xch","a,%s",x);   // 000AAAAA:BBBCCCCC
5904             break;
5905         case 6 :                        // AABBBBBB:CCDDDDDD
5906             pic14_emitcode("mov","c,acc.7");
5907             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
5908             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
5909             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
5910             pic14_emitcode("anl","a,#0x%02x",
5911                      SRMask[shCount]);  // 000000AA:BBBBBBCC
5912             break;
5913         case 7 :                        // ABBBBBBB:CDDDDDDD
5914             pic14_emitcode("mov","c,acc.7");  // c = A
5915             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
5916             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
5917             pic14_emitcode("anl","a,#0x%02x",
5918                      SRMask[shCount]);  // 0000000A:BBBBBBBC
5919             break;
5920         default :
5921             break;
5922     }
5923 }
5924 #endif
5925 /*-----------------------------------------------------------------*/
5926 /* AccAXRshS - right shift signed a:x known count (0..7)           */
5927 /*-----------------------------------------------------------------*/
5928 static void AccAXRshS (char *x, int shCount)
5929 {   
5930     symbol *tlbl ;
5931     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5932     switch(shCount){
5933         case 0 :
5934             break;
5935         case 1 :
5936             pic14_emitcode("mov","c,acc.7");
5937             AccAXRrl1(x);               // s->a:x
5938             break;
5939         case 2 :
5940             pic14_emitcode("mov","c,acc.7");
5941             AccAXRrl1(x);               // s->a:x
5942             pic14_emitcode("mov","c,acc.7");
5943             AccAXRrl1(x);               // s->a:x
5944             break;
5945         case 3 :
5946         case 4 :
5947         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
5948             tlbl = newiTempLabel(NULL);
5949             AccRol(8 - shCount);        // BBBAAAAA:CCCCCDDD
5950             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
5951             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
5952             pic14_emitcode("anl","a,#0x%02x",
5953                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
5954             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
5955             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
5956             pic14_emitcode("anl","a,#0x%02x",
5957                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
5958             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
5959             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
5960             pic14_emitcode("xch","a,%s",x);   // 000SAAAA:BBBCCCCC
5961             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5962             pic14_emitcode("orl","a,#0x%02x",
5963                      (unsigned char)~SRMask[shCount]);  // 111AAAAA:BBBCCCCC
5964             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5965             break;                      // SSSSAAAA:BBBCCCCC
5966         case 6 :                        // AABBBBBB:CCDDDDDD
5967             tlbl = newiTempLabel(NULL);
5968             pic14_emitcode("mov","c,acc.7");
5969             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
5970             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
5971             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
5972             pic14_emitcode("anl","a,#0x%02x",
5973                      SRMask[shCount]);  // 000000AA:BBBBBBCC
5974             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5975             pic14_emitcode("orl","a,#0x%02x",
5976                      (unsigned char)~SRMask[shCount]);  // 111111AA:BBBBBBCC
5977             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5978             break;
5979         case 7 :                        // ABBBBBBB:CDDDDDDD
5980             tlbl = newiTempLabel(NULL);
5981             pic14_emitcode("mov","c,acc.7");  // c = A
5982             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
5983             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
5984             pic14_emitcode("anl","a,#0x%02x",
5985                      SRMask[shCount]);  // 0000000A:BBBBBBBC
5986             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
5987             pic14_emitcode("orl","a,#0x%02x",
5988                      (unsigned char)~SRMask[shCount]);  // 1111111A:BBBBBBBC
5989             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5990             break;
5991         default :
5992             break;
5993     }
5994 }
5995
5996 /*-----------------------------------------------------------------*/
5997 /* shiftL2Left2Result - shift left two bytes from left to result   */
5998 /*-----------------------------------------------------------------*/
5999 static void shiftL2Left2Result (operand *left, int offl,
6000                                 operand *result, int offr, int shCount)
6001 {
6002
6003
6004   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6005
6006   if(pic14_sameRegs(AOP(result), AOP(left))) {
6007     switch(shCount) {
6008     case 0:
6009       break;
6010     case 1:
6011     case 2:
6012     case 3:
6013
6014       emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6015       emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6016       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6017
6018       while(--shCount) {
6019         emitCLRC;
6020         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6021         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6022       }
6023
6024       break;
6025     case 4:
6026     case 5:
6027       emitpcode(POC_MOVLW, popGetLit(0x0f));
6028       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6029       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6030       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6031       emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6032       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6033       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6034       if(shCount >=5) {
6035         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6036         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6037       }
6038       break;
6039     case 6:
6040       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6041       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6042       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6043       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6044       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6045       emitpcode(POC_ANDLW,popGetLit(0xc0));
6046       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6047       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6048       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6049       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6050       break;
6051     case 7:
6052       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6053       emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6054       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6055       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6056       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6057     }
6058
6059   } else {
6060     switch(shCount) {
6061     case 0:
6062       break;
6063     case 1:
6064     case 2:
6065     case 3:
6066       /* note, use a mov/add for the shift since the mov has a
6067          chance of getting optimized out */
6068       emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6069       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6070       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6071       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6072       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6073
6074       while(--shCount) {
6075         emitCLRC;
6076         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6077         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6078       }
6079       break;
6080
6081     case 4:
6082     case 5:
6083       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6084       emitpcode(POC_ANDLW, popGetLit(0xF0));
6085       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6086       emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6087       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6088       emitpcode(POC_ANDLW, popGetLit(0xF0));
6089       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6090       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6091
6092
6093       if(shCount == 5) {
6094         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6095         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6096       }
6097       break;
6098     case 6:
6099       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6100       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6101       emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6102       emitpcode(POC_MOVWF,  popGet(AOP(result),offr,FALSE,FALSE));
6103
6104       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6105       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6106       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6107       emitpcode(POC_ANDLW,popGetLit(0xc0));
6108       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6109       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6110       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6111       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6112       break;
6113     case 7:
6114       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6115       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6116       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6117       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6118       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6119     }
6120   }
6121
6122 }
6123 /*-----------------------------------------------------------------*/
6124 /* shiftR2Left2Result - shift right two bytes from left to result  */
6125 /*-----------------------------------------------------------------*/
6126 static void shiftR2Left2Result (operand *left, int offl,
6127                                 operand *result, int offr,
6128                                 int shCount, int sign)
6129 {
6130   int same=0;
6131
6132   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6133   same = pic14_sameRegs(AOP(result), AOP(left));
6134
6135   if(same && ((offl + MSB16) == offr)){
6136     same=1;
6137     /* don't crash result[offr] */
6138     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6139     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6140   } else {
6141     movLeft2Result(left,offl, result, offr, 0);
6142     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6143   }
6144   /* a:x >> shCount (x = lsb(result))*/
6145   if(sign)
6146     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6147   else {
6148     //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6149     
6150     switch(shCount) {
6151     case 0:
6152       break;
6153     case 1:
6154     case 2:
6155     case 3:
6156       emitCLRC;
6157       if(same) {
6158         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6159         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6160       } else {
6161
6162         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6163         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6164         emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6165         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6166       }
6167
6168       while(--shCount) {
6169         emitCLRC;
6170         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6171         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6172       }
6173       break;
6174     case 4:
6175     case 5:
6176       if(same) {
6177
6178         emitpcode(POC_MOVLW, popGetLit(0xf0));
6179         emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6180         emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6181
6182         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6183         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6185         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6186       } else {
6187         emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6188         emitpcode(POC_ANDLW, popGetLit(0x0f));
6189         emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6190
6191         emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6192         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6193         emitpcode(POC_ANDLW, popGetLit(0xf0));
6194         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6195         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6196       }
6197
6198       if(shCount >=5) {
6199         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6200         emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6201       }
6202
6203       break;
6204
6205     case 6:
6206       if(same) {
6207
6208         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6209         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6210
6211         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6212         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6213         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6214         emitpcode(POC_ANDLW,popGetLit(0x03));
6215         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6216         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6217         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6218         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6219       } else {
6220         emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6221         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6222         emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6223         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6224         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6225         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6226         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6227         emitpcode(POC_ANDLW,popGetLit(0x03));
6228         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6229       }
6230
6231       break;
6232     case 7:
6233       emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6234       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6235       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6236       emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6237       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6238     }
6239   }
6240 }
6241
6242 /*-----------------------------------------------------------------*/
6243 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6244 /*-----------------------------------------------------------------*/
6245 static void shiftLLeftOrResult (operand *left, int offl,
6246                                 operand *result, int offr, int shCount)
6247 {
6248     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6249     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6250     /* shift left accumulator */
6251     AccLsh(shCount);
6252     /* or with result */
6253     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6254     /* back to result */
6255     aopPut(AOP(result),"a",offr);
6256 }
6257
6258 /*-----------------------------------------------------------------*/
6259 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6260 /*-----------------------------------------------------------------*/
6261 static void shiftRLeftOrResult (operand *left, int offl,
6262                                 operand *result, int offr, int shCount)
6263 {
6264     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6265     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6266     /* shift right accumulator */
6267     AccRsh(shCount);
6268     /* or with result */
6269     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6270     /* back to result */
6271     aopPut(AOP(result),"a",offr);
6272 }
6273
6274 /*-----------------------------------------------------------------*/
6275 /* genlshOne - left shift a one byte quantity by known count       */
6276 /*-----------------------------------------------------------------*/
6277 static void genlshOne (operand *result, operand *left, int shCount)
6278 {       
6279     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6280     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6281 }
6282
6283 /*-----------------------------------------------------------------*/
6284 /* genlshTwo - left shift two bytes by known amount != 0           */
6285 /*-----------------------------------------------------------------*/
6286 static void genlshTwo (operand *result,operand *left, int shCount)
6287 {
6288     int size;
6289     
6290     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6291     size = pic14_getDataSize(result);
6292
6293     /* if shCount >= 8 */
6294     if (shCount >= 8) {
6295         shCount -= 8 ;
6296
6297         if (size > 1){
6298             if (shCount)
6299                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6300             else 
6301                 movLeft2Result(left, LSB, result, MSB16, 0);
6302         }
6303         emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6304     }
6305
6306     /*  1 <= shCount <= 7 */
6307     else {  
6308         if(size == 1)
6309             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6310         else 
6311             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6312     }
6313 }
6314
6315 /*-----------------------------------------------------------------*/
6316 /* shiftLLong - shift left one long from left to result            */
6317 /* offl = LSB or MSB16                                             */
6318 /*-----------------------------------------------------------------*/
6319 static void shiftLLong (operand *left, operand *result, int offr )
6320 {
6321     char *l;
6322     int size = AOP_SIZE(result);
6323
6324     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6325     if(size >= LSB+offr){
6326         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6327         MOVA(l);
6328         pic14_emitcode("add","a,acc");
6329         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6330             size >= MSB16+offr && offr != LSB )
6331             pic14_emitcode("xch","a,%s",
6332                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6333         else        
6334             aopPut(AOP(result),"a",LSB+offr);
6335     }
6336
6337     if(size >= MSB16+offr){
6338         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6339             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6340             MOVA(l);
6341         }
6342         pic14_emitcode("rlc","a");
6343         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6344             size >= MSB24+offr && offr != LSB)
6345             pic14_emitcode("xch","a,%s",
6346                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6347         else        
6348             aopPut(AOP(result),"a",MSB16+offr);
6349     }
6350
6351     if(size >= MSB24+offr){
6352         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6353             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6354             MOVA(l);
6355         }
6356         pic14_emitcode("rlc","a");
6357         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6358             size >= MSB32+offr && offr != LSB )
6359             pic14_emitcode("xch","a,%s",
6360                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6361         else        
6362             aopPut(AOP(result),"a",MSB24+offr);
6363     }
6364
6365     if(size > MSB32+offr){
6366         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6367             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6368             MOVA(l);    
6369         }
6370         pic14_emitcode("rlc","a");
6371         aopPut(AOP(result),"a",MSB32+offr);
6372     }
6373     if(offr != LSB)
6374         aopPut(AOP(result),zero,LSB);       
6375 }
6376
6377 /*-----------------------------------------------------------------*/
6378 /* genlshFour - shift four byte by a known amount != 0             */
6379 /*-----------------------------------------------------------------*/
6380 static void genlshFour (operand *result, operand *left, int shCount)
6381 {
6382     int size;
6383
6384     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6385     size = AOP_SIZE(result);
6386
6387     /* if shifting more that 3 bytes */
6388     if (shCount >= 24 ) {
6389         shCount -= 24;
6390         if (shCount)
6391             /* lowest order of left goes to the highest
6392             order of the destination */
6393             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6394         else
6395             movLeft2Result(left, LSB, result, MSB32, 0);
6396         aopPut(AOP(result),zero,LSB);
6397         aopPut(AOP(result),zero,MSB16);
6398         aopPut(AOP(result),zero,MSB32);
6399         return;
6400     }
6401
6402     /* more than two bytes */
6403     else if ( shCount >= 16 ) {
6404         /* lower order two bytes goes to higher order two bytes */
6405         shCount -= 16;
6406         /* if some more remaining */
6407         if (shCount)
6408             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6409         else {
6410             movLeft2Result(left, MSB16, result, MSB32, 0);
6411             movLeft2Result(left, LSB, result, MSB24, 0);
6412         }
6413         aopPut(AOP(result),zero,MSB16);
6414         aopPut(AOP(result),zero,LSB);
6415         return;
6416     }    
6417
6418     /* if more than 1 byte */
6419     else if ( shCount >= 8 ) {
6420         /* lower order three bytes goes to higher order  three bytes */
6421         shCount -= 8;
6422         if(size == 2){
6423             if(shCount)
6424                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6425             else
6426                 movLeft2Result(left, LSB, result, MSB16, 0);
6427         }
6428         else{   /* size = 4 */
6429             if(shCount == 0){
6430                 movLeft2Result(left, MSB24, result, MSB32, 0);
6431                 movLeft2Result(left, MSB16, result, MSB24, 0);
6432                 movLeft2Result(left, LSB, result, MSB16, 0);
6433                 aopPut(AOP(result),zero,LSB);
6434             }
6435             else if(shCount == 1)
6436                 shiftLLong(left, result, MSB16);
6437             else{
6438                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6439                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6440                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6441                 aopPut(AOP(result),zero,LSB);
6442             }
6443         }
6444     }
6445
6446     /* 1 <= shCount <= 7 */
6447     else if(shCount <= 2){
6448         shiftLLong(left, result, LSB);
6449         if(shCount == 2)
6450             shiftLLong(result, result, LSB);
6451     }
6452     /* 3 <= shCount <= 7, optimize */
6453     else{
6454         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6455         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6456         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6457     }
6458 }
6459
6460 /*-----------------------------------------------------------------*/
6461 /* genLeftShiftLiteral - left shifting by known count              */
6462 /*-----------------------------------------------------------------*/
6463 static void genLeftShiftLiteral (operand *left,
6464                                  operand *right,
6465                                  operand *result,
6466                                  iCode *ic)
6467 {    
6468     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6469     int size;
6470
6471     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6472     freeAsmop(right,NULL,ic,TRUE);
6473
6474     aopOp(left,ic,FALSE);
6475     aopOp(result,ic,FALSE);
6476
6477     size = getSize(operandType(result));
6478
6479 #if VIEW_SIZE
6480     pic14_emitcode("; shift left ","result %d, left %d",size,
6481              AOP_SIZE(left));
6482 #endif
6483
6484     /* I suppose that the left size >= result size */
6485     if(shCount == 0){
6486         while(size--){
6487             movLeft2Result(left, size, result, size, 0);
6488         }
6489     }
6490
6491     else if(shCount >= (size * 8))
6492         while(size--)
6493             aopPut(AOP(result),zero,size);
6494     else{
6495         switch (size) {
6496             case 1:
6497                 genlshOne (result,left,shCount);
6498                 break;
6499
6500             case 2:
6501             case 3:
6502                 genlshTwo (result,left,shCount);
6503                 break;
6504
6505             case 4:
6506                 genlshFour (result,left,shCount);
6507                 break;
6508         }
6509     }
6510     freeAsmop(left,NULL,ic,TRUE);
6511     freeAsmop(result,NULL,ic,TRUE);
6512 }
6513
6514 /*-----------------------------------------------------------------*/
6515 /* genLeftShift - generates code for left shifting                 */
6516 /*-----------------------------------------------------------------*/
6517 static void genLeftShift (iCode *ic)
6518 {
6519     operand *left,*right, *result;
6520     int size, offset;
6521     char *l;
6522     symbol *tlbl , *tlbl1;
6523
6524     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6525
6526     right = IC_RIGHT(ic);
6527     left  = IC_LEFT(ic);
6528     result = IC_RESULT(ic);
6529
6530     aopOp(right,ic,FALSE);
6531
6532     /* if the shift count is known then do it 
6533     as efficiently as possible */
6534     if (AOP_TYPE(right) == AOP_LIT) {
6535         genLeftShiftLiteral (left,right,result,ic);
6536         return ;
6537     }
6538
6539     /* shift count is unknown then we have to form 
6540     a loop get the loop count in B : Note: we take
6541     only the lower order byte since shifting
6542     more that 32 bits make no sense anyway, ( the
6543     largest size of an object can be only 32 bits ) */  
6544
6545     
6546     aopOp(left,ic,FALSE);
6547     aopOp(result,ic,FALSE);
6548
6549     /* now move the left to the result if they are not the
6550     same */
6551     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6552         AOP_SIZE(result) > 1) {
6553
6554         size = AOP_SIZE(result);
6555         offset=0;
6556         while (size--) {
6557             l = aopGet(AOP(left),offset,FALSE,TRUE);
6558             if (*l == '@' && (IS_AOP_PREG(result))) {
6559
6560                 pic14_emitcode("mov","a,%s",l);
6561                 aopPut(AOP(result),"a",offset);
6562             } else
6563                 aopPut(AOP(result),l,offset);
6564             offset++;
6565         }
6566     }
6567
6568     size = AOP_SIZE(result);
6569
6570     /* if it is only one byte then */
6571     if (size == 1) {
6572       if(optimized_for_speed) {
6573         emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6574         emitpcode(POC_ANDLW,  popGetLit(0xf0));
6575         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6576         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6577         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6578         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6579         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6580         emitpcode(POC_RLFW,   popGet(AOP(result),0,FALSE,FALSE));
6581         emitpcode(POC_ANDLW,  popGetLit(0xfe));
6582         emitpcode(POC_ADDFW,  popGet(AOP(result),0,FALSE,FALSE));
6583         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6584         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6585       } else {
6586
6587         tlbl = newiTempLabel(NULL);
6588         if (!pic14_sameRegs(AOP(left),AOP(result))) {
6589           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6590           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6591         }
6592
6593         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
6594         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
6595         emitpLabel(tlbl->key);
6596         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
6597         emitpcode(POC_ADDLW,  popGetLit(1));
6598         emitSKPC;
6599         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6600       }
6601       goto release ;
6602     }
6603     
6604
6605     tlbl = newiTempLabel(NULL);
6606     offset = 0 ;   
6607     tlbl1 = newiTempLabel(NULL);
6608
6609     reAdjustPreg(AOP(result));    
6610     
6611     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
6612     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6613     l = aopGet(AOP(result),offset,FALSE,FALSE);
6614     MOVA(l);
6615     pic14_emitcode("add","a,acc");         
6616     aopPut(AOP(result),"a",offset++);
6617     while (--size) {
6618         l = aopGet(AOP(result),offset,FALSE,FALSE);
6619         MOVA(l);
6620         pic14_emitcode("rlc","a");         
6621         aopPut(AOP(result),"a",offset++);
6622     }
6623     reAdjustPreg(AOP(result));
6624
6625     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6626     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6627 release:
6628     freeAsmop (right,NULL,ic,TRUE);
6629     freeAsmop(left,NULL,ic,TRUE);
6630     freeAsmop(result,NULL,ic,TRUE);
6631 }
6632
6633 /*-----------------------------------------------------------------*/
6634 /* genrshOne - right shift a one byte quantity by known count      */
6635 /*-----------------------------------------------------------------*/
6636 static void genrshOne (operand *result, operand *left,
6637                        int shCount, int sign)
6638 {
6639     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6640     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6641 }
6642
6643 /*-----------------------------------------------------------------*/
6644 /* genrshTwo - right shift two bytes by known amount != 0          */
6645 /*-----------------------------------------------------------------*/
6646 static void genrshTwo (operand *result,operand *left,
6647                        int shCount, int sign)
6648 {
6649     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6650     /* if shCount >= 8 */
6651     if (shCount >= 8) {
6652         shCount -= 8 ;
6653         if (shCount)
6654             shiftR1Left2Result(left, MSB16, result, LSB,
6655                                shCount, sign);
6656         else 
6657             movLeft2Result(left, MSB16, result, LSB, sign);
6658         if(sign)
6659           addSign(result, MSB16, sign);
6660         else
6661           emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6662
6663     }
6664
6665     /*  1 <= shCount <= 7 */
6666     else
6667         shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
6668 }
6669
6670 /*-----------------------------------------------------------------*/
6671 /* shiftRLong - shift right one long from left to result           */
6672 /* offl = LSB or MSB16                                             */
6673 /*-----------------------------------------------------------------*/
6674 static void shiftRLong (operand *left, int offl,
6675                         operand *result, int sign)
6676 {
6677     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6678     if(!sign)
6679         pic14_emitcode("clr","c");
6680     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6681     if(sign)
6682         pic14_emitcode("mov","c,acc.7");
6683     pic14_emitcode("rrc","a");
6684     aopPut(AOP(result),"a",MSB32-offl);
6685     if(offl == MSB16)
6686         /* add sign of "a" */
6687         addSign(result, MSB32, sign);
6688
6689     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6690     pic14_emitcode("rrc","a");
6691     aopPut(AOP(result),"a",MSB24-offl);
6692
6693     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6694     pic14_emitcode("rrc","a");
6695     aopPut(AOP(result),"a",MSB16-offl);
6696
6697     if(offl == LSB){
6698         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6699         pic14_emitcode("rrc","a");
6700         aopPut(AOP(result),"a",LSB);
6701     }
6702 }
6703
6704 /*-----------------------------------------------------------------*/
6705 /* genrshFour - shift four byte by a known amount != 0             */
6706 /*-----------------------------------------------------------------*/
6707 static void genrshFour (operand *result, operand *left,
6708                         int shCount, int sign)
6709 {
6710     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6711     /* if shifting more that 3 bytes */
6712     if(shCount >= 24 ) {
6713         shCount -= 24;
6714         if(shCount)
6715             shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6716         else
6717             movLeft2Result(left, MSB32, result, LSB, sign);
6718         addSign(result, MSB16, sign);
6719     }
6720     else if(shCount >= 16){
6721         shCount -= 16;
6722         if(shCount)
6723             shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6724         else{
6725             movLeft2Result(left, MSB24, result, LSB, 0);
6726             movLeft2Result(left, MSB32, result, MSB16, sign);
6727         }
6728         addSign(result, MSB24, sign);
6729     }
6730     else if(shCount >= 8){
6731         shCount -= 8;
6732         if(shCount == 1)
6733             shiftRLong(left, MSB16, result, sign);
6734         else if(shCount == 0){
6735             movLeft2Result(left, MSB16, result, LSB, 0);
6736             movLeft2Result(left, MSB24, result, MSB16, 0);
6737             movLeft2Result(left, MSB32, result, MSB24, sign);
6738             addSign(result, MSB32, sign);
6739         }
6740         else{
6741             shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6742             shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6743             /* the last shift is signed */
6744             shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6745             addSign(result, MSB32, sign);
6746         }
6747     }
6748     else{   /* 1 <= shCount <= 7 */
6749         if(shCount <= 2){
6750             shiftRLong(left, LSB, result, sign);
6751             if(shCount == 2)
6752                 shiftRLong(result, LSB, result, sign);
6753         }
6754         else{
6755             shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6756             shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6757             shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6758         }
6759     }
6760 }
6761
6762 /*-----------------------------------------------------------------*/
6763 /* genRightShiftLiteral - right shifting by known count            */
6764 /*-----------------------------------------------------------------*/
6765 static void genRightShiftLiteral (operand *left,
6766                                   operand *right,
6767                                   operand *result,
6768                                   iCode *ic,
6769                                   int sign)
6770 {    
6771     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6772     int size;
6773
6774     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6775     freeAsmop(right,NULL,ic,TRUE);
6776
6777     aopOp(left,ic,FALSE);
6778     aopOp(result,ic,FALSE);
6779
6780 #if VIEW_SIZE
6781     pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6782              AOP_SIZE(left));
6783 #endif
6784
6785     size = pic14_getDataSize(left);
6786     /* test the LEFT size !!! */
6787
6788     /* I suppose that the left size >= result size */
6789     if(shCount == 0){
6790         size = pic14_getDataSize(result);
6791         while(size--)
6792             movLeft2Result(left, size, result, size, 0);
6793     }
6794
6795     else if(shCount >= (size * 8)){
6796         if(sign)
6797             /* get sign in acc.7 */
6798             MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6799         addSign(result, LSB, sign);
6800     } else{
6801         switch (size) {
6802             case 1:
6803                 genrshOne (result,left,shCount,sign);
6804                 break;
6805
6806             case 2:
6807                 genrshTwo (result,left,shCount,sign);
6808                 break;
6809
6810             case 4:
6811                 genrshFour (result,left,shCount,sign);
6812                 break;
6813             default :
6814                 break;
6815         }
6816
6817         freeAsmop(left,NULL,ic,TRUE);
6818         freeAsmop(result,NULL,ic,TRUE);
6819     }
6820 }
6821
6822 /*-----------------------------------------------------------------*/
6823 /* genSignedRightShift - right shift of signed number              */
6824 /*-----------------------------------------------------------------*/
6825 static void genSignedRightShift (iCode *ic)
6826 {
6827     operand *right, *left, *result;
6828     int size, offset;
6829     char *l;
6830     symbol *tlbl, *tlbl1 ;
6831
6832     /* we do it the hard way put the shift count in b
6833     and loop thru preserving the sign */
6834     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6835
6836     right = IC_RIGHT(ic);
6837     left  = IC_LEFT(ic);
6838     result = IC_RESULT(ic);
6839
6840     aopOp(right,ic,FALSE);  
6841
6842
6843     if ( AOP_TYPE(right) == AOP_LIT) {
6844         genRightShiftLiteral (left,right,result,ic,1);
6845         return ;
6846     }
6847         /* shift count is unknown then we have to form 
6848        a loop get the loop count in B : Note: we take
6849        only the lower order byte since shifting
6850        more that 32 bits make no sense anyway, ( the
6851        largest size of an object can be only 32 bits ) */  
6852
6853     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6854     pic14_emitcode("inc","b");
6855     freeAsmop (right,NULL,ic,TRUE);
6856     aopOp(left,ic,FALSE);
6857     aopOp(result,ic,FALSE);
6858
6859     /* now move the left to the result if they are not the
6860     same */
6861     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6862         AOP_SIZE(result) > 1) {
6863
6864         size = AOP_SIZE(result);
6865         offset=0;
6866         while (size--) {
6867             l = aopGet(AOP(left),offset,FALSE,TRUE);
6868             if (*l == '@' && IS_AOP_PREG(result)) {
6869
6870                 pic14_emitcode("mov","a,%s",l);
6871                 aopPut(AOP(result),"a",offset);
6872             } else
6873                 aopPut(AOP(result),l,offset);
6874             offset++;
6875         }
6876     }
6877
6878     /* mov the highest order bit to OVR */    
6879     tlbl = newiTempLabel(NULL);
6880     tlbl1= newiTempLabel(NULL);
6881
6882     size = AOP_SIZE(result);
6883     offset = size - 1;
6884     pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6885     pic14_emitcode("rlc","a");
6886     pic14_emitcode("mov","ov,c");
6887     /* if it is only one byte then */
6888     if (size == 1) {
6889         l = aopGet(AOP(left),0,FALSE,FALSE);
6890         MOVA(l);
6891         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6892         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6893         pic14_emitcode("mov","c,ov");
6894         pic14_emitcode("rrc","a");
6895         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6896         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6897         aopPut(AOP(result),"a",0);
6898         goto release ;
6899     }
6900
6901     reAdjustPreg(AOP(result));
6902     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6903     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6904     pic14_emitcode("mov","c,ov");
6905     while (size--) {
6906         l = aopGet(AOP(result),offset,FALSE,FALSE);
6907         MOVA(l);
6908         pic14_emitcode("rrc","a");         
6909         aopPut(AOP(result),"a",offset--);
6910     }
6911     reAdjustPreg(AOP(result));
6912     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6913     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6914
6915 release:
6916     freeAsmop(left,NULL,ic,TRUE);
6917     freeAsmop(result,NULL,ic,TRUE);
6918 }
6919
6920 /*-----------------------------------------------------------------*/
6921 /* genRightShift - generate code for right shifting                */
6922 /*-----------------------------------------------------------------*/
6923 static void genRightShift (iCode *ic)
6924 {
6925     operand *right, *left, *result;
6926     sym_link *retype ;
6927     int size, offset;
6928     char *l;
6929     symbol *tlbl, *tlbl1 ;
6930
6931     /* if signed then we do it the hard way preserve the
6932     sign bit moving it inwards */
6933     retype = getSpec(operandType(IC_RESULT(ic)));
6934     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6935
6936     if (!SPEC_USIGN(retype)) {
6937         genSignedRightShift (ic);
6938         return ;
6939     }
6940
6941     /* signed & unsigned types are treated the same : i.e. the
6942     signed is NOT propagated inwards : quoting from the
6943     ANSI - standard : "for E1 >> E2, is equivalent to division
6944     by 2**E2 if unsigned or if it has a non-negative value,
6945     otherwise the result is implementation defined ", MY definition
6946     is that the sign does not get propagated */
6947
6948     right = IC_RIGHT(ic);
6949     left  = IC_LEFT(ic);
6950     result = IC_RESULT(ic);
6951
6952     aopOp(right,ic,FALSE);
6953
6954     /* if the shift count is known then do it 
6955     as efficiently as possible */
6956     if (AOP_TYPE(right) == AOP_LIT) {
6957         genRightShiftLiteral (left,right,result,ic, 0);
6958         return ;
6959     }
6960
6961     /* shift count is unknown then we have to form 
6962     a loop get the loop count in B : Note: we take
6963     only the lower order byte since shifting
6964     more that 32 bits make no sense anyway, ( the
6965     largest size of an object can be only 32 bits ) */  
6966
6967     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6968     pic14_emitcode("inc","b");
6969     aopOp(left,ic,FALSE);
6970     aopOp(result,ic,FALSE);
6971
6972     /* now move the left to the result if they are not the
6973     same */
6974     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6975         AOP_SIZE(result) > 1) {
6976
6977         size = AOP_SIZE(result);
6978         offset=0;
6979         while (size--) {
6980             l = aopGet(AOP(left),offset,FALSE,TRUE);
6981             if (*l == '@' && IS_AOP_PREG(result)) {
6982
6983                 pic14_emitcode("mov","a,%s",l);
6984                 aopPut(AOP(result),"a",offset);
6985             } else
6986                 aopPut(AOP(result),l,offset);
6987             offset++;
6988         }
6989     }
6990
6991     tlbl = newiTempLabel(NULL);
6992     tlbl1= newiTempLabel(NULL);
6993     size = AOP_SIZE(result);
6994     offset = size - 1;
6995
6996     /* if it is only one byte then */
6997     if (size == 1) {
6998 /*
6999         l = aopGet(AOP(left),0,FALSE,FALSE);
7000         MOVA(l);
7001         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7002         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7003         CLRC;
7004         pic14_emitcode("rrc","a");
7005         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7006         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7007         aopPut(AOP(result),"a",0);
7008 */
7009         tlbl = newiTempLabel(NULL);
7010         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7011           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
7012           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
7013         }
7014
7015         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
7016         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
7017         emitpLabel(tlbl->key);
7018         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
7019         emitpcode(POC_ADDLW,  popGetLit(1));
7020         emitSKPC;
7021         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7022
7023         goto release ;
7024     }
7025
7026     reAdjustPreg(AOP(result));
7027     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7028     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7029     CLRC;
7030     while (size--) {
7031         l = aopGet(AOP(result),offset,FALSE,FALSE);
7032         MOVA(l);
7033         pic14_emitcode("rrc","a");         
7034         aopPut(AOP(result),"a",offset--);
7035     }
7036     reAdjustPreg(AOP(result));
7037
7038     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7039     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7040
7041 release:
7042     freeAsmop(left,NULL,ic,TRUE);
7043     freeAsmop (right,NULL,ic,TRUE);
7044     freeAsmop(result,NULL,ic,TRUE);
7045 }
7046
7047 /*-----------------------------------------------------------------*/
7048 /* genUnpackBits - generates code for unpacking bits               */
7049 /*-----------------------------------------------------------------*/
7050 static void genUnpackBits (operand *result, char *rname, int ptype)
7051 {    
7052     int shCnt ;
7053     int rlen = 0 ;
7054     sym_link *etype;
7055     int offset = 0 ;
7056
7057     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7058     etype = getSpec(operandType(result));
7059
7060     /* read the first byte  */
7061     switch (ptype) {
7062
7063     case POINTER:
7064     case IPOINTER:
7065         pic14_emitcode("mov","a,@%s",rname);
7066         break;
7067         
7068     case PPOINTER:
7069         pic14_emitcode("movx","a,@%s",rname);
7070         break;
7071         
7072     case FPOINTER:
7073         pic14_emitcode("movx","a,@dptr");
7074         break;
7075
7076     case CPOINTER:
7077         pic14_emitcode("clr","a");
7078         pic14_emitcode("movc","a","@a+dptr");
7079         break;
7080
7081     case GPOINTER:
7082         pic14_emitcode("lcall","__gptrget");
7083         break;
7084     }
7085
7086     /* if we have bitdisplacement then it fits   */
7087     /* into this byte completely or if length is */
7088     /* less than a byte                          */
7089     if ((shCnt = SPEC_BSTR(etype)) || 
7090         (SPEC_BLEN(etype) <= 8))  {
7091
7092         /* shift right acc */
7093         AccRsh(shCnt);
7094
7095         pic14_emitcode("anl","a,#0x%02x",
7096                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7097         aopPut(AOP(result),"a",offset);
7098         return ;
7099     }
7100
7101     /* bit field did not fit in a byte  */
7102     rlen = SPEC_BLEN(etype) - 8;
7103     aopPut(AOP(result),"a",offset++);
7104
7105     while (1)  {
7106
7107         switch (ptype) {
7108         case POINTER:
7109         case IPOINTER:
7110             pic14_emitcode("inc","%s",rname);
7111             pic14_emitcode("mov","a,@%s",rname);
7112             break;
7113             
7114         case PPOINTER:
7115             pic14_emitcode("inc","%s",rname);
7116             pic14_emitcode("movx","a,@%s",rname);
7117             break;
7118
7119         case FPOINTER:
7120             pic14_emitcode("inc","dptr");
7121             pic14_emitcode("movx","a,@dptr");
7122             break;
7123             
7124         case CPOINTER:
7125             pic14_emitcode("clr","a");
7126             pic14_emitcode("inc","dptr");
7127             pic14_emitcode("movc","a","@a+dptr");
7128             break;
7129             
7130         case GPOINTER:
7131             pic14_emitcode("inc","dptr");
7132             pic14_emitcode("lcall","__gptrget");
7133             break;
7134         }
7135
7136         rlen -= 8;            
7137         /* if we are done */
7138         if ( rlen <= 0 )
7139             break ;
7140         
7141         aopPut(AOP(result),"a",offset++);
7142                               
7143     }
7144     
7145     if (rlen) {
7146         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7147         aopPut(AOP(result),"a",offset);        
7148     }
7149     
7150     return ;
7151 }
7152
7153
7154 /*-----------------------------------------------------------------*/
7155 /* genDataPointerGet - generates code when ptr offset is known     */
7156 /*-----------------------------------------------------------------*/
7157 static void genDataPointerGet (operand *left, 
7158                                operand *result, 
7159                                iCode *ic)
7160 {
7161   int size , offset = 0;
7162
7163
7164   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7165
7166
7167   /* optimization - most of the time, left and result are the same
7168    * address, but different types. for the pic code, we could omit
7169    * the following
7170    */
7171
7172   aopOp(result,ic,TRUE);
7173
7174   emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7175
7176   size = AOP_SIZE(result);
7177
7178   while (size--) {
7179     emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7180     offset++;
7181   }
7182
7183   freeAsmop(left,NULL,ic,TRUE);
7184   freeAsmop(result,NULL,ic,TRUE);
7185 }
7186
7187 /*-----------------------------------------------------------------*/
7188 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7189 /*-----------------------------------------------------------------*/
7190 static void genNearPointerGet (operand *left, 
7191                                operand *result, 
7192                                iCode *ic)
7193 {
7194     asmop *aop = NULL;
7195     regs *preg = NULL ;
7196     char *rname ;
7197     sym_link *rtype, *retype;
7198     sym_link *ltype = operandType(left);    
7199     char buffer[80];
7200
7201     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7202
7203     rtype = operandType(result);
7204     retype= getSpec(rtype);
7205     
7206     aopOp(left,ic,FALSE);
7207     
7208     /* if left is rematerialisable and
7209        result is not bit variable type and
7210        the left is pointer to data space i.e
7211        lower 128 bytes of space */
7212     if (AOP_TYPE(left) == AOP_IMMD &&
7213         !IS_BITVAR(retype)         &&
7214         DCL_TYPE(ltype) == POINTER) {
7215         genDataPointerGet (left,result,ic);
7216         return ;
7217     }
7218     
7219     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7220
7221         /* if the value is already in a pointer register
7222        then don't need anything more */
7223     if (!AOP_INPREG(AOP(left))) {
7224         /* otherwise get a free pointer register */
7225     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7226         aop = newAsmop(0);
7227         preg = getFreePtr(ic,&aop,FALSE);
7228         pic14_emitcode("mov","%s,%s",
7229                 preg->name,
7230                 aopGet(AOP(left),0,FALSE,TRUE));
7231         rname = preg->name ;
7232     } else
7233         rname = aopGet(AOP(left),0,FALSE,FALSE);
7234     
7235     freeAsmop(left,NULL,ic,TRUE);
7236     aopOp (result,ic,FALSE);
7237     
7238       /* if bitfield then unpack the bits */
7239     if (IS_BITVAR(retype)) 
7240         genUnpackBits (result,rname,POINTER);
7241     else {
7242         /* we have can just get the values */
7243         int size = AOP_SIZE(result);
7244         int offset = 0 ;        
7245         
7246     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7247         while (size--) {
7248             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7249
7250                 pic14_emitcode("mov","a,@%s",rname);
7251                 aopPut(AOP(result),"a",offset);
7252             } else {
7253                 sprintf(buffer,"@%s",rname);
7254                 aopPut(AOP(result),buffer,offset);
7255             }
7256             offset++ ;
7257             if (size)
7258                 pic14_emitcode("inc","%s",rname);
7259         }
7260     }
7261
7262     /* now some housekeeping stuff */
7263     if (aop) {
7264         /* we had to allocate for this iCode */
7265     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7266         freeAsmop(NULL,aop,ic,TRUE);
7267     } else { 
7268         /* we did not allocate which means left
7269            already in a pointer register, then
7270            if size > 0 && this could be used again
7271            we have to point it back to where it 
7272            belongs */
7273     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7274         if (AOP_SIZE(result) > 1 &&
7275             !OP_SYMBOL(left)->remat &&
7276             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7277               ic->depth )) {
7278             int size = AOP_SIZE(result) - 1;
7279             while (size--)
7280                 pic14_emitcode("dec","%s",rname);
7281         }
7282     }
7283
7284     /* done */
7285     freeAsmop(result,NULL,ic,TRUE);
7286      
7287 }
7288
7289 /*-----------------------------------------------------------------*/
7290 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7291 /*-----------------------------------------------------------------*/
7292 static void genPagedPointerGet (operand *left, 
7293                                operand *result, 
7294                                iCode *ic)
7295 {
7296     asmop *aop = NULL;
7297     regs *preg = NULL ;
7298     char *rname ;
7299     sym_link *rtype, *retype;    
7300
7301     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7302
7303     rtype = operandType(result);
7304     retype= getSpec(rtype);
7305     
7306     aopOp(left,ic,FALSE);
7307
7308   /* if the value is already in a pointer register
7309        then don't need anything more */
7310     if (!AOP_INPREG(AOP(left))) {
7311         /* otherwise get a free pointer register */
7312         aop = newAsmop(0);
7313         preg = getFreePtr(ic,&aop,FALSE);
7314         pic14_emitcode("mov","%s,%s",
7315                 preg->name,
7316                 aopGet(AOP(left),0,FALSE,TRUE));
7317         rname = preg->name ;
7318     } else
7319         rname = aopGet(AOP(left),0,FALSE,FALSE);
7320     
7321     freeAsmop(left,NULL,ic,TRUE);
7322     aopOp (result,ic,FALSE);
7323
7324     /* if bitfield then unpack the bits */
7325     if (IS_BITVAR(retype)) 
7326         genUnpackBits (result,rname,PPOINTER);
7327     else {
7328         /* we have can just get the values */
7329         int size = AOP_SIZE(result);
7330         int offset = 0 ;        
7331         
7332         while (size--) {
7333             
7334             pic14_emitcode("movx","a,@%s",rname);
7335             aopPut(AOP(result),"a",offset);
7336             
7337             offset++ ;
7338             
7339             if (size)
7340                 pic14_emitcode("inc","%s",rname);
7341         }
7342     }
7343
7344     /* now some housekeeping stuff */
7345     if (aop) {
7346         /* we had to allocate for this iCode */
7347         freeAsmop(NULL,aop,ic,TRUE);
7348     } else { 
7349         /* we did not allocate which means left
7350            already in a pointer register, then
7351            if size > 0 && this could be used again
7352            we have to point it back to where it 
7353            belongs */
7354         if (AOP_SIZE(result) > 1 &&
7355             !OP_SYMBOL(left)->remat &&
7356             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7357               ic->depth )) {
7358             int size = AOP_SIZE(result) - 1;
7359             while (size--)
7360                 pic14_emitcode("dec","%s",rname);
7361         }
7362     }
7363
7364     /* done */
7365     freeAsmop(result,NULL,ic,TRUE);
7366     
7367         
7368 }
7369
7370 /*-----------------------------------------------------------------*/
7371 /* genFarPointerGet - gget value from far space                    */
7372 /*-----------------------------------------------------------------*/
7373 static void genFarPointerGet (operand *left,
7374                               operand *result, iCode *ic)
7375 {
7376     int size, offset ;
7377     sym_link *retype = getSpec(operandType(result));
7378
7379     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7380
7381     aopOp(left,ic,FALSE);
7382
7383     /* if the operand is already in dptr 
7384     then we do nothing else we move the value to dptr */
7385     if (AOP_TYPE(left) != AOP_STR) {
7386         /* if this is remateriazable */
7387         if (AOP_TYPE(left) == AOP_IMMD)
7388             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7389         else { /* we need to get it byte by byte */
7390             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7391             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7392             if (options.model == MODEL_FLAT24)
7393             {
7394                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7395             }
7396         }
7397     }
7398     /* so dptr know contains the address */
7399     freeAsmop(left,NULL,ic,TRUE);
7400     aopOp(result,ic,FALSE);
7401
7402     /* if bit then unpack */
7403     if (IS_BITVAR(retype)) 
7404         genUnpackBits(result,"dptr",FPOINTER);
7405     else {
7406         size = AOP_SIZE(result);
7407         offset = 0 ;
7408
7409         while (size--) {
7410             pic14_emitcode("movx","a,@dptr");
7411             aopPut(AOP(result),"a",offset++);
7412             if (size)
7413                 pic14_emitcode("inc","dptr");
7414         }
7415     }
7416
7417     freeAsmop(result,NULL,ic,TRUE);
7418 }
7419
7420 /*-----------------------------------------------------------------*/
7421 /* pic14_emitcodePointerGet - gget value from code space                  */
7422 /*-----------------------------------------------------------------*/
7423 static void pic14_emitcodePointerGet (operand *left,
7424                                 operand *result, iCode *ic)
7425 {
7426     int size, offset ;
7427     sym_link *retype = getSpec(operandType(result));
7428
7429     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7430
7431     aopOp(left,ic,FALSE);
7432
7433     /* if the operand is already in dptr 
7434     then we do nothing else we move the value to dptr */
7435     if (AOP_TYPE(left) != AOP_STR) {
7436         /* if this is remateriazable */
7437         if (AOP_TYPE(left) == AOP_IMMD)
7438             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7439         else { /* we need to get it byte by byte */
7440             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7441             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7442             if (options.model == MODEL_FLAT24)
7443             {
7444                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7445             }
7446         }
7447     }
7448     /* so dptr know contains the address */
7449     freeAsmop(left,NULL,ic,TRUE);
7450     aopOp(result,ic,FALSE);
7451
7452     /* if bit then unpack */
7453     if (IS_BITVAR(retype)) 
7454         genUnpackBits(result,"dptr",CPOINTER);
7455     else {
7456         size = AOP_SIZE(result);
7457         offset = 0 ;
7458
7459         while (size--) {
7460             pic14_emitcode("clr","a");
7461             pic14_emitcode("movc","a,@a+dptr");
7462             aopPut(AOP(result),"a",offset++);
7463             if (size)
7464                 pic14_emitcode("inc","dptr");
7465         }
7466     }
7467
7468     freeAsmop(result,NULL,ic,TRUE);
7469 }
7470
7471 /*-----------------------------------------------------------------*/
7472 /* genGenPointerGet - gget value from generic pointer space        */
7473 /*-----------------------------------------------------------------*/
7474 static void genGenPointerGet (operand *left,
7475                               operand *result, iCode *ic)
7476 {
7477   int size, offset ;
7478   sym_link *retype = getSpec(operandType(result));
7479
7480   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7481   aopOp(left,ic,FALSE);
7482   aopOp(result,ic,FALSE);
7483
7484
7485   DEBUGpic14_emitcode ("; ","result %s, left %s",
7486                          AopType(AOP_TYPE(result)),
7487                          AopType(AOP_TYPE(left)));
7488
7489   /* if the operand is already in dptr 
7490      then we do nothing else we move the value to dptr */
7491   if (AOP_TYPE(left) != AOP_STR) {
7492     /* if this is remateriazable */
7493     if (AOP_TYPE(left) == AOP_IMMD) {
7494       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7495       pic14_emitcode("mov","b,#%d",pointerCode(retype));
7496     }
7497     else { /* we need to get it byte by byte */
7498
7499       size = AOP_SIZE(result);
7500       offset = 0 ;
7501
7502       while(size--) {
7503         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7504         emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7505         if(size)
7506           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7507       }
7508       goto release;
7509     }
7510   }
7511   /* so dptr know contains the address */
7512
7513   /* if bit then unpack */
7514   if (IS_BITVAR(retype)) 
7515     genUnpackBits(result,"dptr",GPOINTER);
7516
7517  release:
7518   freeAsmop(left,NULL,ic,TRUE);
7519   freeAsmop(result,NULL,ic,TRUE);
7520
7521 }
7522
7523 /*-----------------------------------------------------------------*/
7524 /* genPointerGet - generate code for pointer get                   */
7525 /*-----------------------------------------------------------------*/
7526 static void genPointerGet (iCode *ic)
7527 {
7528     operand *left, *result ;
7529     sym_link *type, *etype;
7530     int p_type;
7531
7532     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7533
7534     left = IC_LEFT(ic);
7535     result = IC_RESULT(ic) ;
7536
7537     /* depending on the type of pointer we need to
7538     move it to the correct pointer register */
7539     type = operandType(left);
7540     etype = getSpec(type);
7541     /* if left is of type of pointer then it is simple */
7542     if (IS_PTR(type) && !IS_FUNC(type->next)) 
7543         p_type = DCL_TYPE(type);
7544     else {
7545         /* we have to go by the storage class */
7546         p_type = PTR_TYPE(SPEC_OCLS(etype));
7547
7548 /*      if (SPEC_OCLS(etype)->codesp ) { */
7549 /*          p_type = CPOINTER ;  */
7550 /*      } */
7551 /*      else */
7552 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7553 /*              p_type = FPOINTER ; */
7554 /*          else */
7555 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7556 /*                  p_type = PPOINTER; */
7557 /*              else */
7558 /*                  if (SPEC_OCLS(etype) == idata ) */
7559 /*                      p_type = IPOINTER; */
7560 /*                  else */
7561 /*                      p_type = POINTER ; */
7562     }
7563
7564     /* now that we have the pointer type we assign
7565     the pointer values */
7566     switch (p_type) {
7567
7568     case POINTER:       
7569     case IPOINTER:
7570         genNearPointerGet (left,result,ic);
7571         break;
7572
7573     case PPOINTER:
7574         genPagedPointerGet(left,result,ic);
7575         break;
7576
7577     case FPOINTER:
7578         genFarPointerGet (left,result,ic);
7579         break;
7580
7581     case CPOINTER:
7582         pic14_emitcodePointerGet (left,result,ic);
7583         break;
7584
7585     case GPOINTER:
7586         genGenPointerGet (left,result,ic);
7587         break;
7588     }
7589
7590 }
7591
7592 /*-----------------------------------------------------------------*/
7593 /* genPackBits - generates code for packed bit storage             */
7594 /*-----------------------------------------------------------------*/
7595 static void genPackBits (sym_link    *etype ,
7596                          operand *right ,
7597                          char *rname, int p_type)
7598 {
7599     int shCount = 0 ;
7600     int offset = 0  ;
7601     int rLen = 0 ;
7602     int blen, bstr ;   
7603     char *l ;
7604
7605     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7606     blen = SPEC_BLEN(etype);
7607     bstr = SPEC_BSTR(etype);
7608
7609     l = aopGet(AOP(right),offset++,FALSE,FALSE);
7610     MOVA(l);   
7611
7612     /* if the bit lenth is less than or    */
7613     /* it exactly fits a byte then         */
7614     if (SPEC_BLEN(etype) <= 8 )  {
7615         shCount = SPEC_BSTR(etype) ;
7616
7617         /* shift left acc */
7618         AccLsh(shCount);
7619
7620         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7621
7622
7623             switch (p_type) {
7624                 case POINTER:
7625                     pic14_emitcode ("mov","b,a");
7626                     pic14_emitcode("mov","a,@%s",rname);
7627                     break;
7628
7629                 case FPOINTER:
7630                     pic14_emitcode ("mov","b,a");
7631                     pic14_emitcode("movx","a,@dptr");
7632                     break;
7633
7634                 case GPOINTER:
7635                     pic14_emitcode ("push","b");
7636                     pic14_emitcode ("push","acc");
7637                     pic14_emitcode ("lcall","__gptrget");
7638                     pic14_emitcode ("pop","b");
7639                     break;
7640             }
7641
7642             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7643                       ((unsigned char)(0xFF << (blen+bstr)) | 
7644                        (unsigned char)(0xFF >> (8-bstr)) ) );
7645             pic14_emitcode ("orl","a,b");
7646             if (p_type == GPOINTER)
7647                 pic14_emitcode("pop","b");
7648         }
7649     }
7650
7651     switch (p_type) {
7652         case POINTER:
7653             pic14_emitcode("mov","@%s,a",rname);
7654             break;
7655
7656         case FPOINTER:
7657             pic14_emitcode("movx","@dptr,a");
7658             break;
7659
7660         case GPOINTER:
7661             DEBUGpic14_emitcode(";lcall","__gptrput");
7662             break;
7663     }
7664
7665     /* if we r done */
7666     if ( SPEC_BLEN(etype) <= 8 )
7667         return ;
7668
7669     pic14_emitcode("inc","%s",rname);
7670     rLen = SPEC_BLEN(etype) ;     
7671
7672     /* now generate for lengths greater than one byte */
7673     while (1) {
7674
7675         l = aopGet(AOP(right),offset++,FALSE,TRUE);
7676
7677         rLen -= 8 ;
7678         if (rLen <= 0 )
7679             break ;
7680
7681         switch (p_type) {
7682             case POINTER:
7683                 if (*l == '@') {
7684                     MOVA(l);
7685                     pic14_emitcode("mov","@%s,a",rname);
7686                 } else
7687                     pic14_emitcode("mov","@%s,%s",rname,l);
7688                 break;
7689
7690             case FPOINTER:
7691                 MOVA(l);
7692                 pic14_emitcode("movx","@dptr,a");
7693                 break;
7694
7695             case GPOINTER:
7696                 MOVA(l);
7697                 DEBUGpic14_emitcode(";lcall","__gptrput");
7698                 break;  
7699         }   
7700         pic14_emitcode ("inc","%s",rname);
7701     }
7702
7703     MOVA(l);
7704
7705     /* last last was not complete */
7706     if (rLen)   {
7707         /* save the byte & read byte */
7708         switch (p_type) {
7709             case POINTER:
7710                 pic14_emitcode ("mov","b,a");
7711                 pic14_emitcode("mov","a,@%s",rname);
7712                 break;
7713
7714             case FPOINTER:
7715                 pic14_emitcode ("mov","b,a");
7716                 pic14_emitcode("movx","a,@dptr");
7717                 break;
7718
7719             case GPOINTER:
7720                 pic14_emitcode ("push","b");
7721                 pic14_emitcode ("push","acc");
7722                 pic14_emitcode ("lcall","__gptrget");
7723                 pic14_emitcode ("pop","b");
7724                 break;
7725         }
7726
7727         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7728         pic14_emitcode ("orl","a,b");
7729     }
7730
7731     if (p_type == GPOINTER)
7732         pic14_emitcode("pop","b");
7733
7734     switch (p_type) {
7735
7736     case POINTER:
7737         pic14_emitcode("mov","@%s,a",rname);
7738         break;
7739         
7740     case FPOINTER:
7741         pic14_emitcode("movx","@dptr,a");
7742         break;
7743         
7744     case GPOINTER:
7745         DEBUGpic14_emitcode(";lcall","__gptrput");
7746         break;                  
7747     }
7748 }
7749 /*-----------------------------------------------------------------*/
7750 /* genDataPointerSet - remat pointer to data space                 */
7751 /*-----------------------------------------------------------------*/
7752 static void genDataPointerSet(operand *right,
7753                               operand *result,
7754                               iCode *ic)
7755 {
7756     int size, offset = 0 ;
7757     char *l, buffer[256];
7758
7759     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7760     aopOp(right,ic,FALSE);
7761     
7762     l = aopGet(AOP(result),0,FALSE,TRUE);
7763     size = AOP_SIZE(right);
7764     // tsd, was l+1 - the underline `_' prefix was being stripped
7765     while (size--) {
7766         if (offset)
7767             sprintf(buffer,"(%s + %d)",l,offset);
7768         else
7769             sprintf(buffer,"%s",l);
7770
7771         if (AOP_TYPE(right) == AOP_LIT) {
7772           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7773           lit = lit >> (8*offset);
7774           if(lit&0xff) {
7775             pic14_emitcode("movlw","%d",lit);
7776             pic14_emitcode("movwf","%s",buffer);
7777
7778             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7779             emitpcode(POC_MOVWF, popRegFromString(buffer));
7780
7781           } else {
7782             pic14_emitcode("clrf","%s",buffer);
7783             emitpcode(POC_CLRF, popRegFromString(buffer));
7784           }
7785         }else {
7786           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7787           pic14_emitcode("movwf","%s",buffer);
7788
7789           emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7790           emitpcode(POC_MOVWF, popRegFromString(buffer));
7791
7792         }
7793
7794         offset++;
7795     }
7796
7797     freeAsmop(right,NULL,ic,TRUE);
7798     freeAsmop(result,NULL,ic,TRUE);
7799 }
7800
7801 /*-----------------------------------------------------------------*/
7802 /* genNearPointerSet - pic14_emitcode for near pointer put                */
7803 /*-----------------------------------------------------------------*/
7804 static void genNearPointerSet (operand *right,
7805                                operand *result, 
7806                                iCode *ic)
7807 {
7808     asmop *aop = NULL;
7809     char *l;
7810     sym_link *retype;
7811     sym_link *ptype = operandType(result);
7812
7813     
7814     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7815     retype= getSpec(operandType(right));
7816
7817     aopOp(result,ic,FALSE);
7818     
7819     /* if the result is rematerializable &
7820        in data space & not a bit variable */
7821     if (AOP_TYPE(result) == AOP_IMMD &&
7822         DCL_TYPE(ptype) == POINTER   &&
7823         !IS_BITVAR(retype)) {
7824         genDataPointerSet (right,result,ic);
7825         return;
7826     }
7827
7828     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7829
7830     /* if the value is already in a pointer register
7831     then don't need anything more */
7832     if (!AOP_INPREG(AOP(result))) {
7833         /* otherwise get a free pointer register */
7834         //aop = newAsmop(0);
7835         //preg = getFreePtr(ic,&aop,FALSE);
7836         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7837         //pic14_emitcode("mov","%s,%s",
7838         //         preg->name,
7839         //         aopGet(AOP(result),0,FALSE,TRUE));
7840         //rname = preg->name ;
7841         pic14_emitcode("movwf","fsr");
7842     }// else
7843     //   rname = aopGet(AOP(result),0,FALSE,FALSE);
7844
7845     freeAsmop(result,NULL,ic,TRUE);
7846     aopOp (right,ic,FALSE);
7847     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7848
7849     /* if bitfield then unpack the bits */
7850     if (IS_BITVAR(retype)) {
7851       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7852              "The programmer is obviously confused");
7853       //genPackBits (retype,right,rname,POINTER);
7854       exit(1);
7855     }
7856     else {
7857         /* we have can just get the values */
7858         int size = AOP_SIZE(right);
7859         int offset = 0 ;    
7860
7861     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7862         while (size--) {
7863             l = aopGet(AOP(right),offset,FALSE,TRUE);
7864             if (*l == '@' ) {
7865               //MOVA(l);
7866               //pic14_emitcode("mov","@%s,a",rname);
7867               pic14_emitcode("movf","indf,w ;1");
7868             } else {
7869
7870               if (AOP_TYPE(right) == AOP_LIT) {
7871                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7872                 if(lit) {
7873                   pic14_emitcode("movlw","%s",l);
7874                   pic14_emitcode("movwf","indf ;2");
7875                 } else 
7876                   pic14_emitcode("clrf","indf");
7877               }else {
7878                 pic14_emitcode("movf","%s,w",l);
7879                 pic14_emitcode("movwf","indf ;2");
7880               }
7881             //pic14_emitcode("mov","@%s,%s",rname,l);
7882             }
7883             if (size)
7884               pic14_emitcode("incf","fsr,f ;3");
7885             //pic14_emitcode("inc","%s",rname);
7886             offset++;
7887         }
7888     }
7889
7890     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7891     /* now some housekeeping stuff */
7892     if (aop) {
7893         /* we had to allocate for this iCode */
7894         freeAsmop(NULL,aop,ic,TRUE);
7895     } else { 
7896         /* we did not allocate which means left
7897         already in a pointer register, then
7898         if size > 0 && this could be used again
7899         we have to point it back to where it 
7900         belongs */
7901     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7902         if (AOP_SIZE(right) > 1 &&
7903             !OP_SYMBOL(result)->remat &&
7904             ( OP_SYMBOL(result)->liveTo > ic->seq ||
7905               ic->depth )) {
7906             int size = AOP_SIZE(right) - 1;
7907             while (size--)
7908               pic14_emitcode("decf","fsr,f");
7909               //pic14_emitcode("dec","%s",rname);
7910         }
7911     }
7912
7913     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7914     /* done */
7915     freeAsmop(right,NULL,ic,TRUE);
7916
7917
7918 }
7919
7920 /*-----------------------------------------------------------------*/
7921 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
7922 /*-----------------------------------------------------------------*/
7923 static void genPagedPointerSet (operand *right,
7924                                operand *result, 
7925                                iCode *ic)
7926 {
7927     asmop *aop = NULL;
7928     regs *preg = NULL ;
7929     char *rname , *l;
7930     sym_link *retype;
7931        
7932     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7933
7934     retype= getSpec(operandType(right));
7935     
7936     aopOp(result,ic,FALSE);
7937     
7938     /* if the value is already in a pointer register
7939        then don't need anything more */
7940     if (!AOP_INPREG(AOP(result))) {
7941         /* otherwise get a free pointer register */
7942         aop = newAsmop(0);
7943         preg = getFreePtr(ic,&aop,FALSE);
7944         pic14_emitcode("mov","%s,%s",
7945                 preg->name,
7946                 aopGet(AOP(result),0,FALSE,TRUE));
7947         rname = preg->name ;
7948     } else
7949         rname = aopGet(AOP(result),0,FALSE,FALSE);
7950     
7951     freeAsmop(result,NULL,ic,TRUE);
7952     aopOp (right,ic,FALSE);
7953
7954     /* if bitfield then unpack the bits */
7955     if (IS_BITVAR(retype)) 
7956         genPackBits (retype,right,rname,PPOINTER);
7957     else {
7958         /* we have can just get the values */
7959         int size = AOP_SIZE(right);
7960         int offset = 0 ;        
7961         
7962         while (size--) {
7963             l = aopGet(AOP(right),offset,FALSE,TRUE);
7964             
7965             MOVA(l);
7966             pic14_emitcode("movx","@%s,a",rname);
7967
7968             if (size)
7969                 pic14_emitcode("inc","%s",rname);
7970
7971             offset++;
7972         }
7973     }
7974     
7975     /* now some housekeeping stuff */
7976     if (aop) {
7977         /* we had to allocate for this iCode */
7978         freeAsmop(NULL,aop,ic,TRUE);
7979     } else { 
7980         /* we did not allocate which means left
7981            already in a pointer register, then
7982            if size > 0 && this could be used again
7983            we have to point it back to where it 
7984            belongs */
7985         if (AOP_SIZE(right) > 1 &&
7986             !OP_SYMBOL(result)->remat &&
7987             ( OP_SYMBOL(result)->liveTo > ic->seq ||
7988               ic->depth )) {
7989             int size = AOP_SIZE(right) - 1;
7990             while (size--)
7991                 pic14_emitcode("dec","%s",rname);
7992         }
7993     }
7994
7995     /* done */
7996     freeAsmop(right,NULL,ic,TRUE);
7997     
7998         
7999 }
8000
8001 /*-----------------------------------------------------------------*/
8002 /* genFarPointerSet - set value from far space                     */
8003 /*-----------------------------------------------------------------*/
8004 static void genFarPointerSet (operand *right,
8005                               operand *result, iCode *ic)
8006 {
8007     int size, offset ;
8008     sym_link *retype = getSpec(operandType(right));
8009
8010     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8011     aopOp(result,ic,FALSE);
8012
8013     /* if the operand is already in dptr 
8014     then we do nothing else we move the value to dptr */
8015     if (AOP_TYPE(result) != AOP_STR) {
8016         /* if this is remateriazable */
8017         if (AOP_TYPE(result) == AOP_IMMD)
8018             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8019         else { /* we need to get it byte by byte */
8020             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8021             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8022             if (options.model == MODEL_FLAT24)
8023             {
8024                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8025             }
8026         }
8027     }
8028     /* so dptr know contains the address */
8029     freeAsmop(result,NULL,ic,TRUE);
8030     aopOp(right,ic,FALSE);
8031
8032     /* if bit then unpack */
8033     if (IS_BITVAR(retype)) 
8034         genPackBits(retype,right,"dptr",FPOINTER);
8035     else {
8036         size = AOP_SIZE(right);
8037         offset = 0 ;
8038
8039         while (size--) {
8040             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8041             MOVA(l);
8042             pic14_emitcode("movx","@dptr,a");
8043             if (size)
8044                 pic14_emitcode("inc","dptr");
8045         }
8046     }
8047
8048     freeAsmop(right,NULL,ic,TRUE);
8049 }
8050
8051 /*-----------------------------------------------------------------*/
8052 /* genGenPointerSet - set value from generic pointer space         */
8053 /*-----------------------------------------------------------------*/
8054 static void genGenPointerSet (operand *right,
8055                               operand *result, iCode *ic)
8056 {
8057   int size, offset ;
8058   sym_link *retype = getSpec(operandType(right));
8059
8060   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8061
8062   aopOp(result,ic,FALSE);
8063   aopOp(right,ic,FALSE);
8064   size = AOP_SIZE(right);
8065
8066   DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8067                        AopType(AOP_TYPE(result)),
8068                        aopGet(AOP(result),0,TRUE,FALSE),
8069                        AopType(AOP_TYPE(right)),
8070                        aopGet(AOP(right),0,FALSE,FALSE),
8071                        size);
8072
8073   /* if the operand is already in dptr 
8074      then we do nothing else we move the value to dptr */
8075   if (AOP_TYPE(result) != AOP_STR) {
8076     /* if this is remateriazable */
8077     if (AOP_TYPE(result) == AOP_IMMD) {
8078       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8079       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8080     }
8081     else { /* we need to get it byte by byte */
8082       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8083       size = AOP_SIZE(right);
8084       offset = 0 ;
8085
8086       /* hack hack! see if this the FSR. If so don't load W */
8087       if(AOP_TYPE(right) != AOP_ACC) {
8088
8089         if(size==2)
8090           emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8091
8092         if(size==4) {
8093           emitpcode(POC_MOVLW,popGetLit(0xfd));
8094           emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8095         }
8096
8097         while(size--) {
8098           emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8099           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8100           
8101           if(size)
8102             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8103         }
8104
8105
8106         goto release;
8107       } 
8108
8109       if(aopIdx(AOP(result),0) != 4) {
8110
8111         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8112         goto release;
8113       }
8114
8115       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8116       goto release;
8117
8118     }
8119   }
8120   /* so dptr know contains the address */
8121
8122
8123   /* if bit then unpack */
8124   if (IS_BITVAR(retype)) 
8125     genPackBits(retype,right,"dptr",GPOINTER);
8126   else {
8127     size = AOP_SIZE(right);
8128     offset = 0 ;
8129
8130     while (--size) {
8131       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8132       if(size)
8133         pic14_emitcode("incf","fsr,f");
8134       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8135       pic14_emitcode("movwf","indf");
8136       //MOVA(l);
8137       //DEBUGpic14_emitcode(";lcall","__gptrput");
8138       //if (size)
8139       //    pic14_emitcode("inc","dptr");
8140     }
8141   }
8142
8143  release:
8144   freeAsmop(right,NULL,ic,TRUE);
8145   freeAsmop(result,NULL,ic,TRUE);
8146 }
8147
8148 /*-----------------------------------------------------------------*/
8149 /* genPointerSet - stores the value into a pointer location        */
8150 /*-----------------------------------------------------------------*/
8151 static void genPointerSet (iCode *ic)
8152 {    
8153     operand *right, *result ;
8154     sym_link *type, *etype;
8155     int p_type;
8156
8157     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8158
8159     right = IC_RIGHT(ic);
8160     result = IC_RESULT(ic) ;
8161
8162     /* depending on the type of pointer we need to
8163     move it to the correct pointer register */
8164     type = operandType(result);
8165     etype = getSpec(type);
8166     /* if left is of type of pointer then it is simple */
8167     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8168         p_type = DCL_TYPE(type);
8169     }
8170     else {
8171         /* we have to go by the storage class */
8172         p_type = PTR_TYPE(SPEC_OCLS(etype));
8173
8174 /*      if (SPEC_OCLS(etype)->codesp ) { */
8175 /*          p_type = CPOINTER ;  */
8176 /*      } */
8177 /*      else */
8178 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8179 /*              p_type = FPOINTER ; */
8180 /*          else */
8181 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8182 /*                  p_type = PPOINTER ; */
8183 /*              else */
8184 /*                  if (SPEC_OCLS(etype) == idata ) */
8185 /*                      p_type = IPOINTER ; */
8186 /*                  else */
8187 /*                      p_type = POINTER ; */
8188     }
8189
8190     /* now that we have the pointer type we assign
8191     the pointer values */
8192     switch (p_type) {
8193
8194     case POINTER:
8195     case IPOINTER:
8196         genNearPointerSet (right,result,ic);
8197         break;
8198
8199     case PPOINTER:
8200         genPagedPointerSet (right,result,ic);
8201         break;
8202
8203     case FPOINTER:
8204         genFarPointerSet (right,result,ic);
8205         break;
8206
8207     case GPOINTER:
8208         genGenPointerSet (right,result,ic);
8209         break;
8210     }
8211
8212 }
8213
8214 /*-----------------------------------------------------------------*/
8215 /* genIfx - generate code for Ifx statement                        */
8216 /*-----------------------------------------------------------------*/
8217 static void genIfx (iCode *ic, iCode *popIc)
8218 {
8219   operand *cond = IC_COND(ic);
8220   int isbit =0;
8221
8222   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8223
8224   aopOp(cond,ic,FALSE);
8225
8226   /* get the value into acc */
8227   if (AOP_TYPE(cond) != AOP_CRY)
8228     pic14_toBoolean(cond);
8229   else
8230     isbit = 1;
8231   /* the result is now in the accumulator */
8232   freeAsmop(cond,NULL,ic,TRUE);
8233
8234   /* if there was something to be popped then do it */
8235   if (popIc)
8236     genIpop(popIc);
8237
8238   /* if the condition is  a bit variable */
8239   if (isbit && IS_ITEMP(cond) && 
8240       SPIL_LOC(cond)) {
8241     genIfxJump(ic,SPIL_LOC(cond)->rname);
8242     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8243   }
8244   else {
8245     if (isbit && !IS_ITEMP(cond))
8246       genIfxJump(ic,OP_SYMBOL(cond)->rname);
8247     else
8248       genIfxJump(ic,"a");
8249   }
8250   ic->generated = 1;
8251
8252 }
8253
8254 /*-----------------------------------------------------------------*/
8255 /* genAddrOf - generates code for address of                       */
8256 /*-----------------------------------------------------------------*/
8257 static void genAddrOf (iCode *ic)
8258 {
8259   //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8260   operand *right, *result, *left;
8261   //int size, offset ;
8262
8263   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8264
8265
8266   //aopOp(IC_RESULT(ic),ic,FALSE);
8267
8268   aopOp((left=IC_LEFT(ic)),ic,FALSE);
8269   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8270   aopOp((result=IC_RESULT(ic)),ic,TRUE);
8271
8272   if(result)
8273     DEBUGpic14_emitcode ("; ","result %s",
8274                          AopType(AOP_TYPE(IC_RESULT(ic))));
8275
8276   if(left)
8277     DEBUGpic14_emitcode ("; ","left %s",
8278                          AopType(AOP_TYPE(IC_LEFT(ic))));
8279   if(right)
8280     DEBUGpic14_emitcode ("; ","right %s",
8281                          AopType(AOP_TYPE(IC_RIGHT(ic))));
8282   
8283   emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8284   emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8285
8286 #if 0
8287   /* object not on stack then we need the name */
8288   size = AOP_SIZE(IC_RESULT(ic));
8289   offset = 0;
8290
8291   while (size--) {
8292     char s[SDCC_NAME_MAX];
8293     if (offset) 
8294       sprintf(s,"#(%s >> %d)",
8295               sym->rname,
8296               offset*8);
8297     else
8298       sprintf(s,"#%s",sym->rname);
8299     aopPut(AOP(IC_RESULT(ic)),s,offset++);
8300   }
8301 #endif
8302
8303
8304   //  freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8305   freeAsmop(left,NULL,ic,FALSE);
8306   freeAsmop(result,NULL,ic,TRUE);
8307
8308 }
8309
8310 #if 0
8311 /*-----------------------------------------------------------------*/
8312 /* genFarFarAssign - assignment when both are in far space         */
8313 /*-----------------------------------------------------------------*/
8314 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8315 {
8316     int size = AOP_SIZE(right);
8317     int offset = 0;
8318     char *l ;
8319     /* first push the right side on to the stack */
8320     while (size--) {
8321         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8322         MOVA(l);
8323         pic14_emitcode ("push","acc");
8324     }
8325     
8326     freeAsmop(right,NULL,ic,FALSE);
8327     /* now assign DPTR to result */
8328     aopOp(result,ic,FALSE);
8329     size = AOP_SIZE(result);
8330     while (size--) {
8331         pic14_emitcode ("pop","acc");
8332         aopPut(AOP(result),"a",--offset);
8333     }
8334     freeAsmop(result,NULL,ic,FALSE);
8335         
8336 }
8337 #endif
8338
8339 /*-----------------------------------------------------------------*/
8340 /* genAssign - generate code for assignment                        */
8341 /*-----------------------------------------------------------------*/
8342 static void genAssign (iCode *ic)
8343 {
8344   operand *result, *right;
8345   int size, offset,know_W;
8346   unsigned long lit = 0L;
8347
8348   result = IC_RESULT(ic);
8349   right  = IC_RIGHT(ic) ;
8350
8351   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8352
8353   /* if they are the same */
8354   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8355     return ;
8356
8357   aopOp(right,ic,FALSE);
8358   aopOp(result,ic,TRUE);
8359
8360   DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8361                        AopType(AOP_TYPE(IC_RESULT(ic))),
8362                        AopType(AOP_TYPE(IC_RIGHT(ic))),
8363                        AOP_SIZE(result));
8364
8365   /* if they are the same registers */
8366   if (pic14_sameRegs(AOP(right),AOP(result)))
8367     goto release;
8368
8369   /* if the result is a bit */
8370   if (AOP_TYPE(result) == AOP_CRY) {
8371
8372     /* if the right size is a literal then
8373        we know what the value is */
8374     if (AOP_TYPE(right) == AOP_LIT) {
8375           
8376       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8377                   popGet(AOP(result),0,FALSE,FALSE));
8378
8379       if (((int) operandLitValue(right))) 
8380         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8381                        AOP(result)->aopu.aop_dir,
8382                        AOP(result)->aopu.aop_dir);
8383       else
8384         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8385                        AOP(result)->aopu.aop_dir,
8386                        AOP(result)->aopu.aop_dir);
8387       goto release;
8388     }
8389
8390     /* the right is also a bit variable */
8391     if (AOP_TYPE(right) == AOP_CRY) {
8392       emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8393       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8394       emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8395
8396       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8397                      AOP(result)->aopu.aop_dir,
8398                      AOP(result)->aopu.aop_dir);
8399       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8400                      AOP(right)->aopu.aop_dir,
8401                      AOP(right)->aopu.aop_dir);
8402       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8403                      AOP(result)->aopu.aop_dir,
8404                      AOP(result)->aopu.aop_dir);
8405       goto release ;
8406     }
8407
8408     /* we need to or */
8409     emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8410     pic14_toBoolean(right);
8411     emitSKPZ;
8412     emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8413     //aopPut(AOP(result),"a",0);
8414     goto release ;
8415   }
8416
8417   /* bit variables done */
8418   /* general case */
8419   size = AOP_SIZE(result);
8420   offset = 0 ;
8421   if(AOP_TYPE(right) == AOP_LIT)
8422     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8423
8424   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
8425     if(aopIdx(AOP(result),0) == 4) {
8426       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8427       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8428       goto release;
8429     } else
8430       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
8431   }
8432
8433   know_W=-1;
8434   while (size--) {
8435     if(AOP_TYPE(right) == AOP_LIT) {
8436       if(lit&0xff) {
8437         if(know_W != (lit&0xff))
8438           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8439         know_W = lit&0xff;
8440         emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8441       } else
8442         emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8443
8444       lit >>= 8;
8445
8446     } else if (AOP_TYPE(right) == AOP_CRY) {
8447       emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8448       if(offset == 0) {
8449         emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8450         emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8451       }
8452     } else {
8453       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8454       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8455     }
8456             
8457     offset++;
8458   }
8459
8460     
8461  release:
8462   freeAsmop (right,NULL,ic,FALSE);
8463   freeAsmop (result,NULL,ic,TRUE);
8464 }   
8465
8466 /*-----------------------------------------------------------------*/
8467 /* genJumpTab - genrates code for jump table                       */
8468 /*-----------------------------------------------------------------*/
8469 static void genJumpTab (iCode *ic)
8470 {
8471     symbol *jtab;
8472     char *l;
8473
8474     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8475
8476     aopOp(IC_JTCOND(ic),ic,FALSE);
8477     /* get the condition into accumulator */
8478     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8479     MOVA(l);
8480     /* multiply by three */
8481     pic14_emitcode("add","a,acc");
8482     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8483
8484     jtab = newiTempLabel(NULL);
8485     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8486     pic14_emitcode("jmp","@a+dptr");
8487     pic14_emitcode("","%05d_DS_:",jtab->key+100);
8488
8489     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8490     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8491     emitSKPNC;
8492     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8493     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8494     emitpLabel(jtab->key);
8495
8496     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8497
8498     /* now generate the jump labels */
8499     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8500          jtab = setNextItem(IC_JTLABELS(ic))) {
8501         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8502         emitpcode(POC_GOTO,popGetLabel(jtab->key));
8503         
8504     }
8505
8506 }
8507
8508 /*-----------------------------------------------------------------*/
8509 /* genMixedOperation - gen code for operators between mixed types  */
8510 /*-----------------------------------------------------------------*/
8511 /*
8512   TSD - Written for the PIC port - but this unfortunately is buggy.
8513   This routine is good in that it is able to efficiently promote 
8514   types to different (larger) sizes. Unfortunately, the temporary
8515   variables that are optimized out by this routine are sometimes
8516   used in other places. So until I know how to really parse the 
8517   iCode tree, I'm going to not be using this routine :(.
8518 */
8519 static int genMixedOperation (iCode *ic)
8520 {
8521 #if 0
8522   operand *result = IC_RESULT(ic);
8523   sym_link *ctype = operandType(IC_LEFT(ic));
8524   operand *right = IC_RIGHT(ic);
8525   int ret = 0;
8526   int big,small;
8527   int offset;
8528
8529   iCode *nextic;
8530   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8531
8532   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8533
8534   nextic = ic->next;
8535   if(!nextic)
8536     return 0;
8537
8538   nextright = IC_RIGHT(nextic);
8539   nextleft  = IC_LEFT(nextic);
8540   nextresult = IC_RESULT(nextic);
8541
8542   aopOp(right,ic,FALSE);
8543   aopOp(result,ic,FALSE);
8544   aopOp(nextright,  nextic, FALSE);
8545   aopOp(nextleft,   nextic, FALSE);
8546   aopOp(nextresult, nextic, FALSE);
8547
8548   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8549
8550     operand *t = right;
8551     right = nextright;
8552     nextright = t; 
8553
8554     pic14_emitcode(";remove right +","");
8555
8556   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8557 /*
8558     operand *t = right;
8559     right = nextleft;
8560     nextleft = t; 
8561 */
8562     pic14_emitcode(";remove left +","");
8563   } else
8564     return 0;
8565
8566   big = AOP_SIZE(nextleft);
8567   small = AOP_SIZE(nextright);
8568
8569   switch(nextic->op) {
8570
8571   case '+':
8572     pic14_emitcode(";optimize a +","");
8573     /* if unsigned or not an integral type */
8574     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8575       pic14_emitcode(";add a bit to something","");
8576     } else {
8577
8578       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8579
8580       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8581         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8582         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8583       } else
8584         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8585
8586       offset = 0;
8587       while(--big) {
8588
8589         offset++;
8590
8591         if(--small) {
8592           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8593             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8594             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8595           }
8596
8597           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8598           emitSKPNC;
8599           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8600                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8601                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8602           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8603           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8604
8605         } else {
8606           pic14_emitcode("rlf","known_zero,w");
8607
8608           /*
8609             if right is signed
8610               btfsc  right,7
8611                addlw ff
8612           */
8613           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8614             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8615             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8616           } else {
8617             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8618           }
8619         }
8620       }
8621       ret = 1;
8622     }
8623   }
8624   ret = 1;
8625
8626 release:
8627   freeAsmop(right,NULL,ic,TRUE);
8628   freeAsmop(result,NULL,ic,TRUE);
8629   freeAsmop(nextright,NULL,ic,TRUE);
8630   freeAsmop(nextleft,NULL,ic,TRUE);
8631   if(ret)
8632     nextic->generated = 1;
8633
8634   return ret;
8635 #else
8636   return 0;
8637 #endif
8638 }
8639 /*-----------------------------------------------------------------*/
8640 /* genCast - gen code for casting                                  */
8641 /*-----------------------------------------------------------------*/
8642 static void genCast (iCode *ic)
8643 {
8644     operand *result = IC_RESULT(ic);
8645     sym_link *ctype = operandType(IC_LEFT(ic));
8646     operand *right = IC_RIGHT(ic);
8647     int size, offset ;
8648
8649     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8650     /* if they are equivalent then do nothing */
8651     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8652         return ;
8653
8654     aopOp(right,ic,FALSE) ;
8655     aopOp(result,ic,FALSE);
8656
8657     /* if the result is a bit */
8658     if (AOP_TYPE(result) == AOP_CRY) {
8659         /* if the right size is a literal then
8660         we know what the value is */
8661         if (AOP_TYPE(right) == AOP_LIT) {
8662
8663           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8664                       popGet(AOP(result),0,FALSE,FALSE));
8665
8666             if (((int) operandLitValue(right))) 
8667               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8668                        AOP(result)->aopu.aop_dir,
8669                        AOP(result)->aopu.aop_dir);
8670             else
8671               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8672                        AOP(result)->aopu.aop_dir,
8673                        AOP(result)->aopu.aop_dir);
8674
8675             goto release;
8676         }
8677
8678         /* the right is also a bit variable */
8679         if (AOP_TYPE(right) == AOP_CRY) {
8680
8681           emitCLRC;
8682           emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8683
8684           pic14_emitcode("clrc","");
8685           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8686                    AOP(right)->aopu.aop_dir,
8687                    AOP(right)->aopu.aop_dir);
8688             aopPut(AOP(result),"c",0);
8689             goto release ;
8690         }
8691
8692         /* we need to or */
8693         pic14_toBoolean(right);
8694         aopPut(AOP(result),"a",0);
8695         goto release ;
8696     }
8697
8698     /* if they are the same size : or less */
8699     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8700
8701         /* if they are in the same place */
8702         if (pic14_sameRegs(AOP(right),AOP(result)))
8703             goto release;
8704
8705         /* if they in different places then copy */
8706         size = AOP_SIZE(result);
8707         offset = 0 ;
8708         while (size--) {
8709             aopPut(AOP(result),
8710                    aopGet(AOP(right),offset,FALSE,FALSE),
8711                    offset);
8712             offset++;
8713         }
8714         goto release;
8715     }
8716
8717
8718     /* if the result is of type pointer */
8719     if (IS_PTR(ctype)) {
8720
8721         int p_type;
8722         sym_link *type = operandType(right);
8723         sym_link *etype = getSpec(type);
8724
8725         /* pointer to generic pointer */
8726         if (IS_GENPTR(ctype)) {
8727             char *l = zero;
8728             
8729             if (IS_PTR(type)) 
8730                 p_type = DCL_TYPE(type);
8731             else {
8732                 /* we have to go by the storage class */
8733                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8734
8735 /*              if (SPEC_OCLS(etype)->codesp )  */
8736 /*                  p_type = CPOINTER ;  */
8737 /*              else */
8738 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8739 /*                      p_type = FPOINTER ; */
8740 /*                  else */
8741 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8742 /*                          p_type = PPOINTER; */
8743 /*                      else */
8744 /*                          if (SPEC_OCLS(etype) == idata ) */
8745 /*                              p_type = IPOINTER ; */
8746 /*                          else */
8747 /*                              p_type = POINTER ; */
8748             }
8749                 
8750             /* the first two bytes are known */
8751             size = GPTRSIZE - 1; 
8752             offset = 0 ;
8753             while (size--) {
8754                 aopPut(AOP(result),
8755                        aopGet(AOP(right),offset,FALSE,FALSE),
8756                        offset);
8757                 offset++;
8758             }
8759             /* the last byte depending on type */
8760             switch (p_type) {
8761             case IPOINTER:
8762             case POINTER:
8763                 l = zero;
8764                 break;
8765             case FPOINTER:
8766                 l = one;
8767                 break;
8768             case CPOINTER:
8769                 l = "#0x02";
8770                 break;                          
8771             case PPOINTER:
8772                 l = "#0x03";
8773                 break;
8774                 
8775             default:
8776                 /* this should never happen */
8777                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8778                        "got unknown pointer type");
8779                 exit(1);
8780             }
8781             aopPut(AOP(result),l, GPTRSIZE - 1);            
8782             goto release ;
8783         }
8784         
8785         /* just copy the pointers */
8786         size = AOP_SIZE(result);
8787         offset = 0 ;
8788         while (size--) {
8789             aopPut(AOP(result),
8790                    aopGet(AOP(right),offset,FALSE,FALSE),
8791                    offset);
8792             offset++;
8793         }
8794         goto release ;
8795     }
8796     
8797
8798     if (AOP_TYPE(right) == AOP_CRY) {
8799       int offset = 1;
8800       size = AOP_SIZE(right);
8801
8802       emitpcode(POC_CLRF,   popGet(AOP(result),0,FALSE,FALSE));
8803       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8804       emitpcode(POC_INCF,   popGet(AOP(result),0,FALSE,FALSE));
8805
8806       pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8807       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8808                AOP(right)->aopu.aop_dir,
8809                AOP(right)->aopu.aop_dir);
8810       pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8811       while (size--) {
8812         pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8813         emitpcode(POC_CLRF,   popGet(AOP(result),offset++,FALSE,FALSE));
8814       }
8815       goto release;
8816     }
8817
8818     /* so we now know that the size of destination is greater
8819     than the size of the source.
8820     Now, if the next iCode is an operator then we might be
8821     able to optimize the operation without performing a cast.
8822     */
8823     if(genMixedOperation(ic))
8824       goto release;
8825
8826     
8827     /* we move to result for the size of source */
8828     size = AOP_SIZE(right);
8829     offset = 0 ;
8830     while (size--) {
8831       pic14_emitcode(";","%d",__LINE__);
8832       /* aopPut(AOP(result),
8833              aopGet(AOP(right),offset,FALSE,FALSE),
8834              offset); */
8835       emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
8836       emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8837       offset++;
8838     }
8839
8840     /* now depending on the sign of the destination */
8841     size = AOP_SIZE(result) - AOP_SIZE(right);
8842     /* if unsigned or not an integral type */
8843     if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8844       while (size--) {
8845           emitpcode(POC_CLRF,   popGet(AOP(result),offset,FALSE,FALSE));
8846           pic14_emitcode("clrf","%s  ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8847           offset++;
8848       }
8849     } else {
8850       /* we need to extend the sign :{ */
8851
8852       emitpcodeNULLop(POC_CLRW);
8853
8854       if(offset)
8855         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8856       else
8857         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8858
8859       emitpcode(POC_MOVLW,   popGetLit(0xff));
8860
8861         pic14_emitcode("clrw","");
8862         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8863                  AOP(right)->aopu.aop_dir,
8864                  AOP(right)->aopu.aop_dir);
8865         pic14_emitcode("movlw","0xff");
8866         while (size--) {
8867           emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8868           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8869           offset++;
8870           // aopPut(AOP(result),"a",offset++);
8871         }
8872
8873     }
8874
8875     /* we are done hurray !!!! */
8876
8877 release:
8878     freeAsmop(right,NULL,ic,TRUE);
8879     freeAsmop(result,NULL,ic,TRUE);
8880
8881 }
8882
8883 /*-----------------------------------------------------------------*/
8884 /* genDjnz - generate decrement & jump if not zero instrucion      */
8885 /*-----------------------------------------------------------------*/
8886 static int genDjnz (iCode *ic, iCode *ifx)
8887 {
8888     symbol *lbl, *lbl1;
8889     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8890
8891     if (!ifx)
8892         return 0;
8893     
8894     /* if the if condition has a false label
8895        then we cannot save */
8896     if (IC_FALSE(ifx))
8897         return 0;
8898
8899     /* if the minus is not of the form 
8900        a = a - 1 */
8901     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8902         !IS_OP_LITERAL(IC_RIGHT(ic)))
8903         return 0;
8904
8905     if (operandLitValue(IC_RIGHT(ic)) != 1)
8906         return 0;
8907
8908     /* if the size of this greater than one then no
8909        saving */
8910     if (getSize(operandType(IC_RESULT(ic))) > 1)
8911         return 0;
8912
8913     /* otherwise we can save BIG */
8914     lbl = newiTempLabel(NULL);
8915     lbl1= newiTempLabel(NULL);
8916
8917     aopOp(IC_RESULT(ic),ic,FALSE);
8918     
8919     if (IS_AOP_PREG(IC_RESULT(ic))) {
8920         pic14_emitcode("dec","%s",
8921                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8922         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8923         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8924     } else {    
8925
8926
8927       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8928       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8929
8930       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8931       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8932
8933     }
8934 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8935 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8936 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8937 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8938
8939     
8940     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8941     ifx->generated = 1;
8942     return 1;
8943 }
8944
8945 /*-----------------------------------------------------------------*/
8946 /* genReceive - generate code for a receive iCode                  */
8947 /*-----------------------------------------------------------------*/
8948 static void genReceive (iCode *ic)
8949 {    
8950     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8951
8952     if (isOperandInFarSpace(IC_RESULT(ic)) && 
8953         ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8954           IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8955
8956         int size = getSize(operandType(IC_RESULT(ic)));
8957         int offset =  fReturnSizePic - size;
8958         while (size--) {
8959             pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8960                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
8961             offset++;
8962         }
8963         aopOp(IC_RESULT(ic),ic,FALSE);  
8964         size = AOP_SIZE(IC_RESULT(ic));
8965         offset = 0;
8966         while (size--) {
8967             pic14_emitcode ("pop","acc");
8968             aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8969         }
8970         
8971     } else {
8972         _G.accInUse++;
8973         aopOp(IC_RESULT(ic),ic,FALSE);  
8974         _G.accInUse--;
8975         assignResultValue(IC_RESULT(ic));       
8976     }
8977
8978     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8979 }
8980
8981 /*-----------------------------------------------------------------*/
8982 /* genpic14Code - generate code for pic14 based controllers        */
8983 /*-----------------------------------------------------------------*/
8984 /*
8985  * At this point, ralloc.c has gone through the iCode and attempted
8986  * to optimize in a way suitable for a PIC. Now we've got to generate
8987  * PIC instructions that correspond to the iCode.
8988  *
8989  * Once the instructions are generated, we'll pass through both the
8990  * peep hole optimizer and the pCode optimizer.
8991  *-----------------------------------------------------------------*/
8992
8993 void genpic14Code (iCode *lic)
8994 {
8995     iCode *ic;
8996     int cln = 0;
8997
8998     lineHead = lineCurr = NULL;
8999
9000     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9001     addpBlock(pb);
9002
9003     /* if debug information required */
9004 /*     if (options.debug && currFunc) { */
9005     if (currFunc) {
9006         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9007         _G.debugLine = 1;
9008         if (IS_STATIC(currFunc->etype)) {
9009             pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9010             //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9011         } else {
9012             pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9013             //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9014         }
9015         _G.debugLine = 0;
9016     }
9017
9018
9019     for (ic = lic ; ic ; ic = ic->next ) {
9020
9021       DEBUGpic14_emitcode(";ic","");
9022         if ( cln != ic->lineno ) {
9023             if ( options.debug ) {
9024                 _G.debugLine = 1;
9025                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9026                          FileBaseName(ic->filename),ic->lineno,
9027                          ic->level,ic->block);
9028                 _G.debugLine = 0;
9029             }
9030             pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9031             cln = ic->lineno ;
9032         }
9033         /* if the result is marked as
9034            spilt and rematerializable or code for
9035            this has already been generated then
9036            do nothing */
9037         if (resultRemat(ic) || ic->generated ) 
9038             continue ;
9039         
9040         /* depending on the operation */
9041         switch (ic->op) {
9042         case '!' :
9043             genNot(ic);
9044             break;
9045             
9046         case '~' :
9047             genCpl(ic);
9048             break;
9049             
9050         case UNARYMINUS:
9051             genUminus (ic);
9052             break;
9053             
9054         case IPUSH:
9055             genIpush (ic);
9056             break;
9057             
9058         case IPOP:
9059             /* IPOP happens only when trying to restore a 
9060                spilt live range, if there is an ifx statement
9061                following this pop then the if statement might
9062                be using some of the registers being popped which
9063                would destory the contents of the register so
9064                we need to check for this condition and handle it */
9065             if (ic->next            && 
9066                 ic->next->op == IFX &&
9067                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9068                 genIfx (ic->next,ic);
9069             else
9070                 genIpop (ic);
9071             break; 
9072             
9073         case CALL:
9074             genCall (ic);
9075             break;
9076             
9077         case PCALL:
9078             genPcall (ic);
9079             break;
9080             
9081         case FUNCTION:
9082             genFunction (ic);
9083             break;
9084             
9085         case ENDFUNCTION:
9086             genEndFunction (ic);
9087             break;
9088             
9089         case RETURN:
9090             genRet (ic);
9091             break;
9092             
9093         case LABEL:
9094             genLabel (ic);
9095             break;
9096             
9097         case GOTO:
9098             genGoto (ic);
9099             break;
9100             
9101         case '+' :
9102             genPlus (ic) ;
9103             break;
9104             
9105         case '-' :
9106             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9107                 genMinus (ic);
9108             break;
9109             
9110         case '*' :
9111             genMult (ic);
9112             break;
9113             
9114         case '/' :
9115             genDiv (ic) ;
9116             break;
9117             
9118         case '%' :
9119             genMod (ic);
9120             break;
9121             
9122         case '>' :
9123             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9124             break;
9125             
9126         case '<' :
9127             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9128             break;
9129             
9130         case LE_OP:
9131         case GE_OP:
9132         case NE_OP:
9133             
9134             /* note these two are xlated by algebraic equivalence
9135                during parsing SDCC.y */
9136             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9137                    "got '>=' or '<=' shouldn't have come here");
9138             break;      
9139             
9140         case EQ_OP:
9141             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9142             break;          
9143             
9144         case AND_OP:
9145             genAndOp (ic);
9146             break;
9147             
9148         case OR_OP:
9149             genOrOp (ic);
9150             break;
9151             
9152         case '^' :
9153             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9154             break;
9155             
9156         case '|' :
9157                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9158             break;
9159             
9160         case BITWISEAND:
9161             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9162             break;
9163             
9164         case INLINEASM:
9165             genInline (ic);
9166             break;
9167             
9168         case RRC:
9169             genRRC (ic);
9170             break;
9171             
9172         case RLC:
9173             genRLC (ic);
9174             break;
9175             
9176         case GETHBIT:
9177             genGetHbit (ic);
9178             break;
9179             
9180         case LEFT_OP:
9181             genLeftShift (ic);
9182             break;
9183             
9184         case RIGHT_OP:
9185             genRightShift (ic);
9186             break;
9187             
9188         case GET_VALUE_AT_ADDRESS:
9189             genPointerGet(ic);
9190             break;
9191             
9192         case '=' :
9193             if (POINTER_SET(ic))
9194                 genPointerSet(ic);
9195             else
9196                 genAssign(ic);
9197             break;
9198             
9199         case IFX:
9200             genIfx (ic,NULL);
9201             break;
9202             
9203         case ADDRESS_OF:
9204             genAddrOf (ic);
9205             break;
9206             
9207         case JUMPTABLE:
9208             genJumpTab (ic);
9209             break;
9210             
9211         case CAST:
9212             genCast (ic);
9213             break;
9214             
9215         case RECEIVE:
9216             genReceive(ic);
9217             break;
9218             
9219         case SEND:
9220             addSet(&_G.sendSet,ic);
9221             break;
9222
9223         default :
9224             ic = ic;
9225         }
9226     }
9227     
9228
9229     /* now we are ready to call the 
9230        peep hole optimizer */
9231     if (!options.nopeep) {
9232       printf("peep hole optimizing\n");
9233         peepHole (&lineHead);
9234     }
9235     /* now do the actual printing */
9236     printLine (lineHead,codeOutFile);
9237
9238     printf("printing pBlock\n\n");
9239     printpBlock(stdout,pb);
9240
9241     return;
9242 }