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