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