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