* src/SDCCicode.c (operandOperation): really fixed problem with bitops
[fw/sdcc] / src / pic16 / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for pic16
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   PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
9   
10   This program is free software; you can redistribute it and/or modify it
11   under the terms of the GNU General Public License as published by the
12   Free Software Foundation; either version 2, or (at your option) any
13   later version.
14   
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License for more details.
19   
20   You should have received a copy of the GNU General Public License
21   along with this program; if not, write to the Free Software
22   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23   
24   In other words, you are welcome to use, share and improve this program.
25   You are forbidden to forbid anyone else to use, share and improve
26   what you give them.   Help stamp out software-hoarding!
27   
28   Notes:
29   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
30                 Made everything static
31 -------------------------------------------------------------------------*/
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include "SDCCglobl.h"
38 #include "newalloc.h"
39
40 #include "common.h"
41 #include "SDCCpeeph.h"
42 #include "ralloc.h"
43 #include "pcode.h"
44 #include "gen.h"
45
46
47 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
49 void pic16_genMult8X8_8 (operand *, operand *,operand *);
50 pCode *pic16_AssembleLine(char *line);
51 extern void pic16_printpBlock(FILE *of, pBlock *pb);
52 static asmop *newAsmop (short type);
53 static pCodeOp *popRegFromString(char *str, int size, int offset);
54 static void mov2w (asmop *aop, int offset);
55 static int aopIdx (asmop *aop, int offset);
56
57 static int labelOffset=0;
58 extern int pic16_debug_verbose;
59 static int optimized_for_speed = 0;
60 /*
61   hack hack
62
63 */
64 int options_no_movff = 1;
65
66 /* max_key keeps track of the largest label number used in 
67    a function. This is then used to adjust the label offset
68    for the next function.
69 */
70 static int max_key=0;
71 static int GpsuedoStkPtr=0;
72
73 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
74 unsigned int pic16aopLiteral (value *val, int offset);
75 const char *pic16_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 *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic16;
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 pic16_ptrRegReq ;
119 extern int pic16_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 DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
159 {
160
161   DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
162                        line_no,
163                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
164                        ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
166                        ((left)   ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
168                        ((right)  ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169                        ((result) ? AOP_SIZE(result) : 0));
170
171 }
172
173 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
174 {
175
176   DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
177                        line_no,
178                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
179                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
180                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
181                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
182                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
183                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
184
185 }
186
187 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
188 {
189     va_list ap;
190     char lb[INITIAL_INLINEASM];  
191     char *lbp = lb;
192
193     if(!pic16_debug_verbose)
194       return;
195
196     va_start(ap,fmt);   
197
198     if (inst && *inst) {
199         if (fmt && *fmt)
200             sprintf(lb,"%s\t",inst);
201         else
202             sprintf(lb,"%s",inst);
203         vsprintf(lb+(strlen(lb)),fmt,ap);
204     }  else
205         vsprintf(lb,fmt,ap);
206
207     while (isspace(*lbp)) lbp++;
208
209     if (lbp && *lbp) 
210         lineCurr = (lineCurr ?
211                     connectLine(lineCurr,newLineNode(lb)) :
212                     (lineHead = newLineNode(lb)));
213     lineCurr->isInline = _G.inLine;
214     lineCurr->isDebug  = _G.debugLine;
215
216     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
217     va_end(ap);
218
219 //      fprintf(stderr, "%s\n", lb);
220 }
221
222
223 void pic16_emitpLabel(int key)
224 {
225   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
226 }
227
228 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
229 {
230
231   if(pcop)
232     pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
233   else
234     DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
235     
236 //    fprintf(stderr, "%s\n", pcop->name);
237 }
238
239 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
240 {
241
242   pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
243
244 }
245
246 /*-----------------------------------------------------------------*/
247 /* pic16_emitcode - writes the code into a file : for now it is simple    */
248 /*-----------------------------------------------------------------*/
249 void pic16_emitcode (char *inst,char *fmt, ...)
250 {
251     va_list ap;
252     char lb[INITIAL_INLINEASM];  
253     char *lbp = lb;
254
255     va_start(ap,fmt);   
256
257     if (inst && *inst) {
258         if (fmt && *fmt)
259             sprintf(lb,"%s\t",inst);
260         else
261             sprintf(lb,"%s",inst);
262         vsprintf(lb+(strlen(lb)),fmt,ap);
263     }  else
264         vsprintf(lb,fmt,ap);
265
266     while (isspace(*lbp)) lbp++;
267
268     if (lbp && *lbp) 
269         lineCurr = (lineCurr ?
270                     connectLine(lineCurr,newLineNode(lb)) :
271                     (lineHead = newLineNode(lb)));
272     lineCurr->isInline = _G.inLine;
273     lineCurr->isDebug  = _G.debugLine;
274
275 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
276
277     if(pic16_debug_verbose)
278       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
279
280     va_end(ap);
281 }
282
283
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
288 {
289     bool r0iu = FALSE , r1iu = FALSE;
290     bool r0ou = FALSE , r1ou = FALSE;
291
292         //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
293
294     /* the logic: if r0 & r1 used in the instruction
295     then we are in trouble otherwise */
296
297     /* first check if r0 & r1 are used by this
298     instruction, in which case we are in trouble */
299     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
301     {
302         goto endOfWorld;      
303     }
304
305     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
307
308     /* if no usage of r0 then return it */
309     if (!r0iu && !r0ou) {
310         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311         (*aopp)->type = AOP_R0;
312         
313         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
314     }
315
316     /* if no usage of r1 then return it */
317     if (!r1iu && !r1ou) {
318         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319         (*aopp)->type = AOP_R1;
320
321         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
322     }    
323
324     /* now we know they both have usage */
325     /* if r0 not used in this instruction */
326     if (!r0iu) {
327         /* push it if not already pushed */
328         if (!_G.r0Pushed) {
329           //pic16_emitcode ("push","%s",
330           //          pic16_regWithIdx(R0_IDX)->dname);
331             _G.r0Pushed++ ;
332         }
333         
334         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335         (*aopp)->type = AOP_R0;
336
337         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
338     }
339
340     /* if r1 not used then */
341
342     if (!r1iu) {
343         /* push it if not already pushed */
344         if (!_G.r1Pushed) {
345           //pic16_emitcode ("push","%s",
346           //          pic16_regWithIdx(R1_IDX)->dname);
347             _G.r1Pushed++ ;
348         }
349         
350         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351         (*aopp)->type = AOP_R1;
352         return pic16_regWithIdx(R1_IDX);
353     }
354
355 endOfWorld :
356     /* I said end of world but not quite end of world yet */
357     /* if this is a result then we can push it on the stack*/
358     if (result) {
359         (*aopp)->type = AOP_STK;    
360         return NULL;
361     }
362
363     /* other wise this is true end of the world */
364     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365            "getFreePtr should never reach here");
366     exit(0);
367 }
368
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp                                  */
371 /*-----------------------------------------------------------------*/
372 static asmop *newAsmop (short type)
373 {
374     asmop *aop;
375
376     aop = Safe_calloc(1,sizeof(asmop));
377     aop->type = type;
378     return aop;
379 }
380
381 static void genSetDPTR(int n)
382 {
383     if (!n)
384     {
385         pic16_emitcode(";", "Select standard DPTR");
386         pic16_emitcode("mov", "dps, #0x00");
387     }
388     else
389     {
390         pic16_emitcode(";", "Select alternate DPTR");
391         pic16_emitcode("mov", "dps, #0x01");
392     }
393 }
394
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for  */
397 /*              generating code                                    */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
400 {
401   if(!resIfx) 
402     return;
403
404   //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
405
406   resIfx->condition = 1;    /* assume that the ifx is true */
407   resIfx->generated = 0;    /* indicate that the ifx has not been used */
408
409   if(!ifx) {
410     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
411 /*
412     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
413                         __FUNCTION__,__LINE__,resIfx->lbl->key);
414 */
415   } else {
416     if(IC_TRUE(ifx)) {
417       resIfx->lbl = IC_TRUE(ifx);
418     } else {
419       resIfx->lbl = IC_FALSE(ifx);
420       resIfx->condition = 0;
421     }
422 /*
423     if(IC_TRUE(ifx)) 
424       DEBUGpic16_emitcode("; ***","ifx true is non-null");
425     if(IC_FALSE(ifx)) 
426       DEBUGpic16_emitcode("; ***","ifx false is non-null");
427 */
428   }
429
430   //  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
431
432 }
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type               */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
437 {
438
439     return PTR_TYPE(SPEC_OCLS(etype));
440
441 }
442
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol                                   */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
447 {
448     asmop *aop;
449     memmap *space= SPEC_OCLS(sym->etype);
450
451     DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452     /* if already has one */
453     if (sym->aop) {
454             DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
455         return sym->aop;
456     }
457
458     /* assign depending on the storage class */
459     /* if it is on the stack or indirectly addressable */
460     /* space we need to assign either r0 or r1 to it   */    
461     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
462         sym->aop = aop = newAsmop(0);
463         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
464         aop->size = getSize(sym->type);
465
466         /* now assign the address of the variable to 
467         the pointer register */
468         if (aop->type != AOP_STK) {
469
470             if (sym->onStack) {
471                     if ( _G.accInUse )
472                         pic16_emitcode("push","acc");
473
474                     pic16_emitcode("mov","a,_bp");
475                     pic16_emitcode("add","a,#0x%02x",
476                              ((sym->stack < 0) ?
477                               ((char)(sym->stack - _G.nRegsSaved )) :
478                               ((char)sym->stack)) & 0xff);
479                     pic16_emitcode("mov","%s,a",
480                              aop->aopu.aop_ptr->name);
481
482                     if ( _G.accInUse )
483                         pic16_emitcode("pop","acc");
484             } else
485                 pic16_emitcode("mov","%s,#%s",
486                          aop->aopu.aop_ptr->name,
487                          sym->rname);
488             aop->paged = space->paged;
489         } else
490             aop->aopu.aop_stk = sym->stack;
491         return aop;
492     }
493     
494     if (sym->onStack && options.stack10bit)
495     {
496         /* It's on the 10 bit stack, which is located in
497          * far data space.
498          */
499          
500       //DEBUGpic16_emitcode(";","%d",__LINE__);
501
502         if ( _G.accInUse )
503                 pic16_emitcode("push","acc");
504
505         pic16_emitcode("mov","a,_bp");
506         pic16_emitcode("add","a,#0x%02x",
507                  ((sym->stack < 0) ?
508                    ((char)(sym->stack - _G.nRegsSaved )) :
509                    ((char)sym->stack)) & 0xff);
510         
511         genSetDPTR(1);
512         pic16_emitcode ("mov","dpx1,#0x40");
513         pic16_emitcode ("mov","dph1,#0x00");
514         pic16_emitcode ("mov","dpl1, a");
515         genSetDPTR(0);
516         
517         if ( _G.accInUse )
518             pic16_emitcode("pop","acc");
519             
520         sym->aop = aop = newAsmop(AOP_DPTR2);
521         aop->size = getSize(sym->type); 
522         return aop;
523     }
524
525     //DEBUGpic16_emitcode(";","%d",__LINE__);
526     /* if in bit space */
527     if (IN_BITSPACE(space)) {
528         sym->aop = aop = newAsmop (AOP_CRY);
529         aop->aopu.aop_dir = sym->rname ;
530         aop->size = getSize(sym->type);
531         //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
532         return aop;
533     }
534     /* if it is in direct space */
535     if (IN_DIRSPACE(space)) {
536         sym->aop = aop = newAsmop (AOP_DIR);
537         aop->aopu.aop_dir = sym->rname ;
538         aop->size = getSize(sym->type);
539         DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
540         return aop;
541     }
542
543     /* special case for a function */
544     if (IS_FUNC(sym->type)) {   
545         sym->aop = aop = newAsmop(AOP_IMMD);    
546         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
547         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548         strcpy(aop->aopu.aop_immd,sym->rname);
549         aop->size = FPTRSIZE; 
550         DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
551         return aop;
552     }
553
554
555     /* only remaining is far space */
556     /* in which case DPTR gets the address */
557     sym->aop = aop = newAsmop(AOP_PCODE);
558
559     aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
560     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561     PCOI(aop->aopu.pcop)->index = 0;
562
563     DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
564                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
565
566     pic16_allocDirReg (IC_LEFT(ic));
567
568     aop->size = FPTRSIZE; 
569 /*
570     DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571     sym->aop = aop = newAsmop(AOP_DPTR);
572     pic16_emitcode ("mov","dptr,#%s", sym->rname);
573     aop->size = getSize(sym->type);
574
575     DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
576 */
577
578     /* if it is in code space */
579     if (IN_CODESPACE(space))
580         aop->code = 1;
581
582     return aop;     
583 }
584
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object                           */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
589 {
590   symbol *sym = OP_SYMBOL(op);
591   iCode *ic = NULL;
592   asmop *aop = newAsmop(AOP_PCODE);
593   int val = 0;
594   int offset = 0;
595
596   ic = sym->rematiCode;
597
598   DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599   if(IS_OP_POINTER(op)) {
600     DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
601   }
602   for (;;) {
603     if (ic->op == '+') {
604       val += (int) operandLitValue(IC_RIGHT(ic));
605     } else if (ic->op == '-') {
606       val -= (int) operandLitValue(IC_RIGHT(ic));
607     } else
608       break;
609         
610     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
611   }
612
613   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614   aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
615   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616   PCOI(aop->aopu.pcop)->index = val;
617
618   DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
619                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
620                       val, IS_PTR_CONST(operandType(op)));
621
622   //    DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
623
624   pic16_allocDirReg (IC_LEFT(ic));
625
626   return aop;        
627 }
628
629 static int aopIdx (asmop *aop, int offset)
630 {
631   if(!aop)
632     return -1;
633
634   if(aop->type !=  AOP_REG)
635     return -2;
636         
637   return aop->aopu.aop_reg[offset]->rIdx;
638
639 }
640 /*-----------------------------------------------------------------*/
641 /* regsInCommon - two operands have some registers in common       */
642 /*-----------------------------------------------------------------*/
643 static bool regsInCommon (operand *op1, operand *op2)
644 {
645     symbol *sym1, *sym2;
646     int i;
647
648     /* if they have registers in common */
649     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
650         return FALSE ;
651
652     sym1 = OP_SYMBOL(op1);
653     sym2 = OP_SYMBOL(op2);
654
655     if (sym1->nRegs == 0 || sym2->nRegs == 0)
656         return FALSE ;
657
658     for (i = 0 ; i < sym1->nRegs ; i++) {
659         int j;
660         if (!sym1->regs[i])
661             continue ;
662
663         for (j = 0 ; j < sym2->nRegs ;j++ ) {
664             if (!sym2->regs[j])
665                 continue ;
666
667             if (sym2->regs[j] == sym1->regs[i])
668                 return TRUE ;
669         }
670     }
671
672     return FALSE ;
673 }
674
675 /*-----------------------------------------------------------------*/
676 /* operandsEqu - equivalent                                        */
677 /*-----------------------------------------------------------------*/
678 static bool operandsEqu ( operand *op1, operand *op2)
679 {
680     symbol *sym1, *sym2;
681
682     /* if they not symbols */
683     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
684         return FALSE;
685
686     sym1 = OP_SYMBOL(op1);
687     sym2 = OP_SYMBOL(op2);
688
689     /* if both are itemps & one is spilt
690        and the other is not then false */
691     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
692         sym1->isspilt != sym2->isspilt )
693         return FALSE ;
694
695     /* if they are the same */
696     if (sym1 == sym2)
697         return TRUE ;
698
699     if (strcmp(sym1->rname,sym2->rname) == 0)
700         return TRUE;
701
702
703     /* if left is a tmp & right is not */
704     if (IS_ITEMP(op1)  && 
705         !IS_ITEMP(op2) &&
706         sym1->isspilt  &&
707         (sym1->usl.spillLoc == sym2))
708         return TRUE;
709
710     if (IS_ITEMP(op2)  && 
711         !IS_ITEMP(op1) &&
712         sym2->isspilt  &&
713         sym1->level > 0 &&
714         (sym2->usl.spillLoc == sym1))
715         return TRUE ;
716
717     return FALSE ;
718 }
719
720 /*-----------------------------------------------------------------*/
721 /* pic16_sameRegs - two asmops have the same registers                   */
722 /*-----------------------------------------------------------------*/
723 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
724 {
725     int i;
726
727     if (aop1 == aop2)
728         return TRUE ;
729
730     if (aop1->type != AOP_REG ||
731         aop2->type != AOP_REG )
732         return FALSE ;
733
734     if (aop1->size != aop2->size )
735         return FALSE ;
736
737     for (i = 0 ; i < aop1->size ; i++ )
738         if (aop1->aopu.aop_reg[i] !=
739             aop2->aopu.aop_reg[i] )
740             return FALSE ;
741
742     return TRUE ;
743 }
744
745 /*-----------------------------------------------------------------*/
746 /* pic16_aopOp - allocates an asmop for an operand  :                    */
747 /*-----------------------------------------------------------------*/
748 void pic16_aopOp (operand *op, iCode *ic, bool result)
749 {
750     asmop *aop;
751     symbol *sym;
752     int i;
753
754     if (!op)
755         return ;
756
757         DEBUGpic16_emitcode(";","%d",__LINE__);
758     /* if this a literal */
759     if (IS_OP_LITERAL(op)) {
760         op->aop = aop = newAsmop(AOP_LIT);
761         aop->aopu.aop_lit = op->operand.valOperand;
762         aop->size = getSize(operandType(op));
763         return;
764     }
765
766     {
767       sym_link *type = operandType(op);
768       if(IS_PTR_CONST(type))
769         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
770     }
771
772     /* if already has a asmop then continue */
773     if (op->aop)
774         return ;
775
776     /* if the underlying symbol has a aop */
777     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
778       DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
779         op->aop = OP_SYMBOL(op)->aop;
780         return;
781     }
782
783     /* if this is a true symbol */
784     if (IS_TRUE_SYMOP(op)) {    
785         DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
786       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
787       return ;
788     }
789
790     /* this is a temporary : this has
791     only four choices :
792     a) register
793     b) spillocation
794     c) rematerialize 
795     d) conditional   
796     e) can be a return use only */
797
798     sym = OP_SYMBOL(op);
799
800         DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
801     /* if the type is a conditional */
802     if (sym->regType == REG_CND) {
803         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
804         aop->size = 0;
805         return;
806     }
807
808     /* if it is spilt then two situations
809     a) is rematerialize 
810     b) has a spill location */
811     if (sym->isspilt || sym->nRegs == 0) {
812
813       DEBUGpic16_emitcode(";","%d",__LINE__);
814         /* rematerialize it NOW */
815         if (sym->remat) {
816
817             sym->aop = op->aop = aop =
818                                       aopForRemat (op);
819             aop->size = getSize(sym->type);
820             //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
821             return;
822         }
823
824         if (sym->accuse) {
825             int i;
826             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
827             aop->size = getSize(sym->type);
828             for ( i = 0 ; i < 2 ; i++ )
829                 aop->aopu.aop_str[i] = accUse[i];
830             DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
831             return;  
832         }
833
834         if (sym->ruonly ) {
835           /*
836           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
837           aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
838           //pic16_allocDirReg (IC_LEFT(ic));
839           aop->size = getSize(sym->type);
840           */
841
842           unsigned i;
843
844           aop = op->aop = sym->aop = newAsmop(AOP_STR);
845           aop->size = getSize(sym->type);
846           for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
847             aop->aopu.aop_str[i] = fReturn[i];
848
849           DEBUGpic16_emitcode(";","%d",__LINE__);
850           return;
851         }
852
853         /* else spill location  */
854         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
855             /* force a new aop if sizes differ */
856             sym->usl.spillLoc->aop = NULL;
857         }
858         DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
859                             __FUNCTION__,__LINE__,
860                             sym->usl.spillLoc->rname,
861                             sym->rname, sym->usl.spillLoc->offset);
862
863         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
864         //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
865         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
866                                           getSize(sym->type), 
867                                           sym->usl.spillLoc->offset);
868         aop->size = getSize(sym->type);
869
870         return;
871     }
872
873     {
874       sym_link *type = operandType(op);
875       if(IS_PTR_CONST(type)) 
876         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
877     }
878
879     /* must be in a register */
880     DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
881     sym->aop = op->aop = aop = newAsmop(AOP_REG);
882     aop->size = sym->nRegs;
883     for ( i = 0 ; i < sym->nRegs ;i++)
884         aop->aopu.aop_reg[i] = sym->regs[i];
885 }
886
887 /*-----------------------------------------------------------------*/
888 /* pic16_freeAsmop - free up the asmop given to an operand               */
889 /*----------------------------------------------------------------*/
890 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
891 {   
892     asmop *aop ;
893
894     if (!op)
895         aop = aaop;
896     else 
897         aop = op->aop;
898
899     if (!aop)
900         return ;
901
902     if (aop->freed)
903         goto dealloc; 
904
905     aop->freed = 1;
906
907     /* depending on the asmop type only three cases need work AOP_RO
908        , AOP_R1 && AOP_STK */
909 #if 0
910     switch (aop->type) {
911         case AOP_R0 :
912             if (_G.r0Pushed ) {
913                 if (pop) {
914                     pic16_emitcode ("pop","ar0");     
915                     _G.r0Pushed--;
916                 }
917             }
918             bitVectUnSetBit(ic->rUsed,R0_IDX);
919             break;
920
921         case AOP_R1 :
922             if (_G.r1Pushed ) {
923                 if (pop) {
924                     pic16_emitcode ("pop","ar1");
925                     _G.r1Pushed--;
926                 }
927             }
928             bitVectUnSetBit(ic->rUsed,R1_IDX);          
929             break;
930
931         case AOP_STK :
932         {
933             int sz = aop->size;    
934             int stk = aop->aopu.aop_stk + aop->size;
935             bitVectUnSetBit(ic->rUsed,R0_IDX);
936             bitVectUnSetBit(ic->rUsed,R1_IDX);          
937
938             getFreePtr(ic,&aop,FALSE);
939             
940             if (options.stack10bit)
941             {
942                 /* I'm not sure what to do here yet... */
943                 /* #STUB */
944                 fprintf(stderr, 
945                         "*** Warning: probably generating bad code for "
946                         "10 bit stack mode.\n");
947             }
948             
949             if (stk) {
950                 pic16_emitcode ("mov","a,_bp");
951                 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
952                 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
953             } else {
954                 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
955             }
956
957             while (sz--) {
958                 pic16_emitcode("pop","acc");
959                 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
960                 if (!sz) break;
961                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
962             }
963             op->aop = aop;
964             pic16_freeAsmop(op,NULL,ic,TRUE);
965             if (_G.r0Pushed) {
966                 pic16_emitcode("pop","ar0");
967                 _G.r0Pushed--;
968             }
969
970             if (_G.r1Pushed) {
971                 pic16_emitcode("pop","ar1");
972                 _G.r1Pushed--;
973             }       
974         }
975     }
976 #endif
977
978 dealloc:
979     /* all other cases just dealloc */
980     if (op ) {
981         op->aop = NULL;
982         if (IS_SYMOP(op)) {
983             OP_SYMBOL(op)->aop = NULL;    
984             /* if the symbol has a spill */
985             if (SPIL_LOC(op))
986                 SPIL_LOC(op)->aop = NULL;
987         }
988     }
989 }
990
991 /*-----------------------------------------------------------------*/
992 /* pic16_aopGet - for fetching value of the aop                          */
993 /*-----------------------------------------------------------------*/
994 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
995 {
996     char *s = buffer ;
997     char *rs;
998
999     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1000     /* offset is greater than
1001     size then zero */
1002     if (offset > (aop->size - 1) &&
1003         aop->type != AOP_LIT)
1004         return zero;
1005
1006     /* depending on type */
1007     switch (aop->type) {
1008         
1009     case AOP_R0:
1010     case AOP_R1:
1011         DEBUGpic16_emitcode(";","%d",__LINE__);
1012         /* if we need to increment it */       
1013         while (offset > aop->coff) {        
1014             pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1015             aop->coff++;
1016         }
1017         
1018         while (offset < aop->coff) {
1019             pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1020             aop->coff--;
1021         }
1022         
1023         aop->coff = offset ;
1024         if (aop->paged) {
1025             pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1026             return (dname ? "acc" : "a");
1027         }       
1028         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1029         rs = Safe_calloc(1,strlen(s)+1);
1030         strcpy(rs,s);   
1031         return rs;
1032         
1033     case AOP_DPTR:
1034     case AOP_DPTR2:
1035         DEBUGpic16_emitcode(";","%d",__LINE__);
1036     if (aop->type == AOP_DPTR2)
1037     {
1038         genSetDPTR(1);
1039     }
1040     
1041         while (offset > aop->coff) {
1042             pic16_emitcode ("inc","dptr");
1043             aop->coff++;
1044         }
1045         
1046         while (offset < aop->coff) {        
1047             pic16_emitcode("lcall","__decdptr");
1048             aop->coff--;
1049         }
1050         
1051         aop->coff = offset;
1052         if (aop->code) {
1053             pic16_emitcode("clr","a");
1054             pic16_emitcode("movc","a,@a+dptr");
1055         }
1056     else {
1057             pic16_emitcode("movx","a,@dptr");
1058     }
1059             
1060     if (aop->type == AOP_DPTR2)
1061     {
1062         genSetDPTR(0);
1063     }
1064             
1065     return (dname ? "acc" : "a");
1066         
1067         
1068     case AOP_IMMD:
1069         if (bit16) 
1070             sprintf (s,"%s",aop->aopu.aop_immd);
1071         else
1072             if (offset) 
1073                 sprintf(s,"(%s >> %d)",
1074                         aop->aopu.aop_immd,
1075                         offset*8);
1076             else
1077                 sprintf(s,"%s",
1078                         aop->aopu.aop_immd);
1079         DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1080         rs = Safe_calloc(1,strlen(s)+1);
1081         strcpy(rs,s);   
1082         return rs;
1083         
1084     case AOP_DIR:
1085       if (offset) {
1086         sprintf(s,"(%s + %d)",
1087                 aop->aopu.aop_dir,
1088                 offset);
1089         DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1090       } else
1091             sprintf(s,"%s",aop->aopu.aop_dir);
1092         rs = Safe_calloc(1,strlen(s)+1);
1093         strcpy(rs,s);   
1094         return rs;
1095         
1096     case AOP_REG:
1097       //if (dname) 
1098       //    return aop->aopu.aop_reg[offset]->dname;
1099       //else
1100             return aop->aopu.aop_reg[offset]->name;
1101         
1102     case AOP_CRY:
1103       //pic16_emitcode(";","%d",__LINE__);
1104       return aop->aopu.aop_dir;
1105         
1106     case AOP_ACC:
1107         DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1108         return "AOP_accumulator_bug";
1109
1110     case AOP_LIT:
1111         sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1112         rs = Safe_calloc(1,strlen(s)+1);
1113         strcpy(rs,s);   
1114         return rs;
1115         
1116     case AOP_STR:
1117         aop->coff = offset ;
1118         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1119             dname)
1120             return "acc";
1121         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1122         
1123         return aop->aopu.aop_str[offset];
1124         
1125     case AOP_PCODE:
1126       {
1127         pCodeOp *pcop = aop->aopu.pcop;
1128         DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1129         if(pcop->name) {
1130           DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1131           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1132           sprintf(s,"%s", pcop->name);
1133         } else
1134           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1135
1136       }
1137       rs = Safe_calloc(1,strlen(s)+1);
1138       strcpy(rs,s);   
1139       return rs;
1140
1141     }
1142
1143     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1144            "aopget got unsupported aop->type");
1145     exit(0);
1146 }
1147
1148
1149 /*-----------------------------------------------------------------*/
1150 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1151 /*-----------------------------------------------------------------*/
1152 pCodeOp *pic16_popGetTempReg(void)
1153 {
1154
1155   pCodeOp *pcop;
1156
1157   pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1158   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1159     PCOR(pcop)->r->wasUsed=1;
1160     PCOR(pcop)->r->isFree=0;
1161   }
1162
1163   return pcop;
1164 }
1165
1166 /*-----------------------------------------------------------------*/
1167 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1168 /*-----------------------------------------------------------------*/
1169 void pic16_popReleaseTempReg(pCodeOp *pcop)
1170 {
1171
1172   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1173     PCOR(pcop)->r->isFree = 1;
1174
1175 }
1176 /*-----------------------------------------------------------------*/
1177 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL             */
1178 /*-----------------------------------------------------------------*/
1179 pCodeOp *pic16_popGetLabel(unsigned int key)
1180 {
1181
1182   DEBUGpic16_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1183
1184   if(key>max_key)
1185     max_key = key;
1186
1187   return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1188 }
1189
1190 /*-----------------------------------------------------------------*/
1191 /* pic16_popCopyReg - copy a pcode operator                              */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1194 {
1195   pCodeOpReg *pcor;
1196
1197   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1198   pcor->pcop.type = pc->pcop.type;
1199   if(pc->pcop.name) {
1200     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1201       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1202   } else
1203     pcor->pcop.name = NULL;
1204
1205   pcor->r = pc->r;
1206   pcor->rIdx = pc->rIdx;
1207   pcor->r->wasUsed=1;
1208
1209   //DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1210
1211   return PCOP(pcor);
1212 }
1213 /*-----------------------------------------------------------------*/
1214 /* pic16_popGet - asm operator to pcode operator conversion              */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *pic16_popGetLit(unsigned int lit)
1217 {
1218
1219   return pic16_newpCodeOpLit(lit);
1220 }
1221
1222
1223 /*-----------------------------------------------------------------*/
1224 /* pic16_popGetImmd - asm operator to pcode immediate conversion         */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1227 {
1228
1229   return pic16_newpCodeOpImmd(name, offset,index, 0);
1230 }
1231
1232
1233 /*-----------------------------------------------------------------*/
1234 /* pic16_popGet - asm operator to pcode operator conversion              */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *pic16_popGetWithString(char *str)
1237 {
1238   pCodeOp *pcop;
1239
1240
1241   if(!str) {
1242     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1243     exit (1);
1244   }
1245
1246   pcop = pic16_newpCodeOp(str,PO_STR);
1247
1248   return pcop;
1249 }
1250
1251 /*-----------------------------------------------------------------*/
1252 /* popRegFromString -                                              */
1253 /*-----------------------------------------------------------------*/
1254 static pCodeOp *popRegFromString(char *str, int size, int offset)
1255 {
1256
1257   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1258   pcop->type = PO_DIR;
1259
1260   DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1261 //  fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1262
1263   if(!str)
1264     str = "BAD_STRING";
1265
1266   pcop->name = Safe_calloc(1,strlen(str)+1);
1267   strcpy(pcop->name,str);
1268
1269   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1270
1271   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1272   if(PCOR(pcop)->r == NULL) {
1273     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1275
1276         //fprintf(stderr, "allocating new register -> %s\n", str);
1277
1278     DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1279   } else {
1280     DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1281   }
1282   PCOR(pcop)->instance = offset;
1283
1284   return pcop;
1285 }
1286
1287 static pCodeOp *popRegFromIdx(int rIdx)
1288 {
1289   pCodeOp *pcop;
1290
1291   DEBUGpic16_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1292                        __FUNCTION__,__LINE__,rIdx);
1293
1294   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295
1296   PCOR(pcop)->rIdx = rIdx;
1297   PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1298   PCOR(pcop)->r->isFree = 0;
1299   PCOR(pcop)->r->wasUsed = 1;
1300
1301   pcop->type = PCOR(pcop)->r->pc_type;
1302
1303
1304   return pcop;
1305 }
1306
1307 /*---------------------------------------------------------------------------------*/
1308 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1309 /*                 VR 030601                                                       */
1310 /*---------------------------------------------------------------------------------*/
1311 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1312 {
1313   pCodeOpReg2 *pcop2;
1314   pCodeOp *temp;
1315   
1316         pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1317         temp = pic16_popGet(aop_dst, offset);
1318         pcop2->pcop2 = temp;
1319         
1320   return PCOP(pcop2);
1321 }
1322
1323
1324 /*-----------------------------------------------------------------*/
1325 /* pic16_popGet - asm operator to pcode operator conversion              */
1326 /*-----------------------------------------------------------------*/
1327 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1328 {
1329   //char *s = buffer ;
1330     //char *rs;
1331
1332     pCodeOp *pcop;
1333
1334     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1335     /* offset is greater than
1336     size then zero */
1337
1338     if (offset > (aop->size - 1) &&
1339         aop->type != AOP_LIT)
1340       return NULL;  //zero;
1341
1342     /* depending on type */
1343     switch (aop->type) {
1344         
1345     case AOP_R0:
1346     case AOP_R1:
1347     case AOP_DPTR:
1348     case AOP_DPTR2:
1349     case AOP_ACC:
1350         DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1351         return NULL;
1352         
1353     case AOP_IMMD:
1354       DEBUGpic16_emitcode(";","%d",__LINE__);
1355       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1356
1357     case AOP_DIR:
1358       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1359
1360 #if 0
1361         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1362         pcop->type = PO_DIR;
1363
1364         /*
1365         if (offset)
1366             sprintf(s,"(%s + %d)",
1367                     aop->aopu.aop_dir,
1368                     offset);
1369         else
1370             sprintf(s,"%s",aop->aopu.aop_dir);
1371         pcop->name = Safe_calloc(1,strlen(s)+1);
1372         strcpy(pcop->name,s);   
1373         */
1374         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1375         strcpy(pcop->name,aop->aopu.aop_dir);   
1376         PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1377         if(PCOR(pcop)->r == NULL) {
1378           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1379           PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1380           DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1381         } else {
1382           DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1383         }
1384         PCOR(pcop)->instance = offset;
1385
1386         return pcop;
1387 #endif
1388         
1389     case AOP_REG:
1390       {
1391         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1392
1393         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394         PCOR(pcop)->rIdx = rIdx;
1395         PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1396         PCOR(pcop)->r->wasUsed=1;
1397         PCOR(pcop)->r->isFree=0;
1398
1399         PCOR(pcop)->instance = offset;
1400         pcop->type = PCOR(pcop)->r->pc_type;
1401         //rs = aop->aopu.aop_reg[offset]->name;
1402         //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1403         return pcop;
1404       }
1405
1406     case AOP_CRY:
1407       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1408       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1409       //if(PCOR(pcop)->r == NULL)
1410       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1411       return pcop;
1412         
1413     case AOP_LIT:
1414       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1415
1416     case AOP_STR:
1417       DEBUGpic16_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1418       return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1419       /*
1420       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1421       PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1422       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1423       pcop->type = PCOR(pcop)->r->pc_type;
1424       pcop->name = PCOR(pcop)->r->name;
1425
1426       return pcop;
1427       */
1428
1429     case AOP_PCODE:
1430       DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1431                           __LINE__, 
1432                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1433       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1434       PCOI(pcop)->offset = offset;
1435       return pcop;
1436     }
1437
1438     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1439            "pic16_popGet got unsupported aop->type");
1440     exit(0);
1441 }
1442 /*-----------------------------------------------------------------*/
1443 /* pic16_aopPut - puts a string for a aop                                */
1444 /*-----------------------------------------------------------------*/
1445 void pic16_aopPut (asmop *aop, char *s, int offset)
1446 {
1447     char *d = buffer ;
1448     symbol *lbl ;
1449
1450     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1451
1452     if (aop->size && offset > ( aop->size - 1)) {
1453         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1454                "pic16_aopPut got offset > aop->size");
1455         exit(0);
1456     }
1457
1458     /* will assign value to value */
1459     /* depending on where it is ofcourse */
1460     switch (aop->type) {
1461     case AOP_DIR:
1462       if (offset) {
1463         sprintf(d,"(%s + %d)",
1464                 aop->aopu.aop_dir,offset);
1465         fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1466
1467       } else
1468             sprintf(d,"%s",aop->aopu.aop_dir);
1469         
1470         if (strcmp(d,s)) {
1471           DEBUGpic16_emitcode(";","%d",__LINE__);
1472           if(strcmp(s,"W"))
1473             pic16_emitcode("movf","%s,w",s);
1474           pic16_emitcode("movwf","%s",d);
1475
1476           if(strcmp(s,"W")) {
1477             pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1478             if(offset >= aop->size) {
1479               pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1480               break;
1481             } else
1482               pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1483           }
1484
1485           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1486
1487
1488         }
1489         break;
1490         
1491     case AOP_REG:
1492       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1493         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1494           /*
1495             if (*s == '@'           ||
1496                 strcmp(s,"r0") == 0 ||
1497                 strcmp(s,"r1") == 0 ||
1498                 strcmp(s,"r2") == 0 ||
1499                 strcmp(s,"r3") == 0 ||
1500                 strcmp(s,"r4") == 0 ||
1501                 strcmp(s,"r5") == 0 ||
1502                 strcmp(s,"r6") == 0 || 
1503                 strcmp(s,"r7") == 0 )
1504                 pic16_emitcode("mov","%s,%s  ; %d",
1505                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1506             else
1507           */
1508
1509           if(strcmp(s,"W")==0 )
1510             pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
1511
1512           pic16_emitcode("movwf","%s",
1513                    aop->aopu.aop_reg[offset]->name);
1514
1515           if(strcmp(s,zero)==0) {
1516             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1517
1518           } else if(strcmp(s,"W")==0) {
1519             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1520             pcop->type = PO_GPR_REGISTER;
1521
1522             PCOR(pcop)->rIdx = -1;
1523             PCOR(pcop)->r = NULL;
1524
1525             DEBUGpic16_emitcode(";","%d",__LINE__);
1526             pcop->name = Safe_strdup(s);
1527             pic16_emitpcode(POC_MOVFW,pcop);
1528             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1529           } else if(strcmp(s,one)==0) {
1530             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1531             pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1532           } else {
1533             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1534           }
1535         }
1536         break;
1537         
1538     case AOP_DPTR:
1539     case AOP_DPTR2:
1540     
1541     if (aop->type == AOP_DPTR2)
1542     {
1543         genSetDPTR(1);
1544     }
1545     
1546         if (aop->code) {
1547             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1548                    "pic16_aopPut writting to code space");
1549             exit(0);
1550         }
1551         
1552         while (offset > aop->coff) {
1553             aop->coff++;
1554             pic16_emitcode ("inc","dptr");
1555         }
1556         
1557         while (offset < aop->coff) {
1558             aop->coff-- ;
1559             pic16_emitcode("lcall","__decdptr");
1560         }
1561         
1562         aop->coff = offset;
1563         
1564         /* if not in accumulater */
1565         MOVA(s);        
1566         
1567         pic16_emitcode ("movx","@dptr,a");
1568         
1569     if (aop->type == AOP_DPTR2)
1570     {
1571         genSetDPTR(0);
1572     }
1573         break;
1574         
1575     case AOP_R0:
1576     case AOP_R1:
1577         while (offset > aop->coff) {
1578             aop->coff++;
1579             pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1580         }
1581         while (offset < aop->coff) {
1582             aop->coff-- ;
1583             pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1584         }
1585         aop->coff = offset;
1586         
1587         if (aop->paged) {
1588             MOVA(s);           
1589             pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1590             
1591         } else
1592             if (*s == '@') {
1593                 MOVA(s);
1594                 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1595             } else
1596                 if (strcmp(s,"r0") == 0 ||
1597                     strcmp(s,"r1") == 0 ||
1598                     strcmp(s,"r2") == 0 ||
1599                     strcmp(s,"r3") == 0 ||
1600                     strcmp(s,"r4") == 0 ||
1601                     strcmp(s,"r5") == 0 ||
1602                     strcmp(s,"r6") == 0 || 
1603                     strcmp(s,"r7") == 0 ) {
1604                     char buffer[10];
1605                     sprintf(buffer,"a%s",s);
1606                     pic16_emitcode("mov","@%s,%s",
1607                              aop->aopu.aop_ptr->name,buffer);
1608                 } else
1609                     pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1610         
1611         break;
1612         
1613     case AOP_STK:
1614         if (strcmp(s,"a") == 0)
1615             pic16_emitcode("push","acc");
1616         else
1617             pic16_emitcode("push","%s",s);
1618         
1619         break;
1620         
1621     case AOP_CRY:
1622         /* if bit variable */
1623         if (!aop->aopu.aop_dir) {
1624             pic16_emitcode("clr","a");
1625             pic16_emitcode("rlc","a");
1626         } else {
1627             if (s == zero) 
1628                 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1629             else
1630                 if (s == one)
1631                     pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1632                 else
1633                     if (!strcmp(s,"c"))
1634                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1635                     else {
1636                         lbl = newiTempLabel(NULL);
1637                         
1638                         if (strcmp(s,"a")) {
1639                             MOVA(s);
1640                         }
1641                         pic16_emitcode("clr","c");
1642                         pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1643                         pic16_emitcode("cpl","c");
1644                         pic16_emitcode("","%05d_DS_:",lbl->key+100);
1645                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1646                     }
1647         }
1648         break;
1649         
1650     case AOP_STR:
1651         aop->coff = offset;
1652         if (strcmp(aop->aopu.aop_str[offset],s))
1653             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1654         break;
1655         
1656     case AOP_ACC:
1657         aop->coff = offset;
1658         if (!offset && (strcmp(s,"acc") == 0))
1659             break;
1660         
1661         if (strcmp(aop->aopu.aop_str[offset],s))
1662             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1663         break;
1664
1665     default :
1666         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1667                "pic16_aopPut got unsupported aop->type");
1668         exit(0);    
1669     }    
1670
1671 }
1672
1673 /*-----------------------------------------------------------------*/
1674 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1675 /*-----------------------------------------------------------------*/
1676 static void mov2w (asmop *aop, int offset)
1677 {
1678
1679   if(!aop)
1680     return;
1681
1682   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1683
1684   if ( aop->type == AOP_PCODE ||
1685        aop->type == AOP_LIT )
1686     pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1687   else
1688     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1689
1690 }
1691
1692 /*-----------------------------------------------------------------*/
1693 /* reAdjustPreg - points a register back to where it should        */
1694 /*-----------------------------------------------------------------*/
1695 static void reAdjustPreg (asmop *aop)
1696 {
1697     int size ;
1698
1699     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1700     aop->coff = 0;
1701     if ((size = aop->size) <= 1)
1702         return ;
1703     size-- ;
1704     switch (aop->type) {
1705         case AOP_R0 :
1706         case AOP_R1 :
1707             while (size--)
1708                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1709             break;          
1710         case AOP_DPTR :
1711         case AOP_DPTR2:
1712             if (aop->type == AOP_DPTR2)
1713             {
1714                 genSetDPTR(1);
1715             } 
1716             while (size--)
1717             {
1718                 pic16_emitcode("lcall","__decdptr");
1719             }
1720                 
1721             if (aop->type == AOP_DPTR2)
1722             {
1723                 genSetDPTR(0);
1724             }                
1725             break;  
1726
1727     }   
1728
1729 }
1730
1731 /*-----------------------------------------------------------------*/
1732 /* genNotFloat - generates not for float operations              */
1733 /*-----------------------------------------------------------------*/
1734 static void genNotFloat (operand *op, operand *res)
1735 {
1736     int size, offset;
1737     char *l;
1738     symbol *tlbl ;
1739
1740     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1741     /* we will put 127 in the first byte of 
1742     the result */
1743     pic16_aopPut(AOP(res),"#127",0);
1744     size = AOP_SIZE(op) - 1;
1745     offset = 1;
1746
1747     l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1748     MOVA(l);    
1749
1750     while(size--) {
1751         pic16_emitcode("orl","a,%s",
1752                  pic16_aopGet(op->aop,
1753                         offset++,FALSE,FALSE));
1754     }
1755     tlbl = newiTempLabel(NULL);
1756
1757     tlbl = newiTempLabel(NULL);
1758     pic16_aopPut(res->aop,one,1);
1759     pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1760     pic16_aopPut(res->aop,zero,1);
1761     pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1762
1763     size = res->aop->size - 2;
1764     offset = 2;    
1765     /* put zeros in the rest */
1766     while (size--) 
1767         pic16_aopPut(res->aop,zero,offset++);
1768 }
1769
1770 #if 0
1771 /*-----------------------------------------------------------------*/
1772 /* opIsGptr: returns non-zero if the passed operand is             */   
1773 /* a generic pointer type.                                         */
1774 /*-----------------------------------------------------------------*/ 
1775 static int opIsGptr(operand *op)
1776 {
1777     sym_link *type = operandType(op);
1778     
1779     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1780     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1781     {
1782         return 1;
1783     }
1784     return 0;        
1785 }
1786 #endif
1787
1788 /*-----------------------------------------------------------------*/
1789 /* pic16_getDataSize - get the operand data size                         */
1790 /*-----------------------------------------------------------------*/
1791 int pic16_getDataSize(operand *op)
1792 {
1793     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1794
1795
1796     return AOP_SIZE(op);
1797
1798     // tsd- in the pic port, the genptr size is 1, so this code here
1799     // fails. ( in the 8051 port, the size was 4).
1800 #if 0
1801     int size;
1802     size = AOP_SIZE(op);
1803     if (size == GPTRSIZE)
1804     {
1805         sym_link *type = operandType(op);
1806         if (IS_GENPTR(type))
1807         {
1808             /* generic pointer; arithmetic operations
1809              * should ignore the high byte (pointer type).
1810              */
1811             size--;
1812     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1813         }
1814     }
1815     return size;
1816 #endif
1817 }
1818
1819 /*-----------------------------------------------------------------*/
1820 /* pic16_outAcc - output Acc                                             */
1821 /*-----------------------------------------------------------------*/
1822 void pic16_outAcc(operand *result)
1823 {
1824   int size,offset;
1825   DEBUGpic16_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1826   DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1827
1828
1829   size = pic16_getDataSize(result);
1830   if(size){
1831     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1832     size--;
1833     offset = 1;
1834     /* unsigned or positive */
1835     while(size--)
1836       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1837   }
1838
1839 }
1840
1841 /*-----------------------------------------------------------------*/
1842 /* pic16_outBitC - output a bit C                                        */
1843 /*-----------------------------------------------------------------*/
1844 void pic16_outBitC(operand *result)
1845 {
1846
1847     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1848     /* if the result is bit */
1849     if (AOP_TYPE(result) == AOP_CRY) 
1850         pic16_aopPut(AOP(result),"c",0);
1851     else {
1852         pic16_emitcode("clr","a  ; %d", __LINE__);
1853         pic16_emitcode("rlc","a");
1854         pic16_outAcc(result);
1855     }
1856 }
1857
1858 /*-----------------------------------------------------------------*/
1859 /* pic16_toBoolean - emit code for orl a,operator(sizeop)                */
1860 /*-----------------------------------------------------------------*/
1861 void pic16_toBoolean(operand *oper)
1862 {
1863     int size = AOP_SIZE(oper) - 1;
1864     int offset = 1;
1865
1866     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1867
1868     if ( AOP_TYPE(oper) != AOP_ACC) {
1869       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1870     }
1871     while (size--) {
1872       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1873     }
1874 }
1875
1876
1877 /*-----------------------------------------------------------------*/
1878 /* genNot - generate code for ! operation                          */
1879 /*-----------------------------------------------------------------*/
1880 static void genNot (iCode *ic)
1881 {
1882   symbol *tlbl;
1883   sym_link *optype = operandType(IC_LEFT(ic));
1884   int size;
1885
1886   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1887   /* assign asmOps to operand & result */
1888   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1889   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1890
1891   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1892   /* if in bit space then a special case */
1893   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1894     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1895       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1896       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1897     } else {
1898       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1899       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1900       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1901     }
1902     goto release;
1903   }
1904
1905   /* if type float then do float */
1906   if (IS_FLOAT(optype)) {
1907     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1908     goto release;
1909   }
1910
1911   size = AOP_SIZE(IC_RESULT(ic));
1912   if(size == 1) {
1913     pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1914     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1915     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1916     goto release;
1917   }
1918   pic16_toBoolean(IC_LEFT(ic));
1919
1920   tlbl = newiTempLabel(NULL);
1921   pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1922   pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1923   pic16_outBitC(IC_RESULT(ic));
1924
1925  release:    
1926   /* release the aops */
1927   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1928   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1929 }
1930
1931
1932 /*-----------------------------------------------------------------*/
1933 /* genCpl - generate code for complement                           */
1934 /*-----------------------------------------------------------------*/
1935 static void genCpl (iCode *ic)
1936 {
1937     int offset = 0;
1938     int size ;
1939
1940
1941     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1942     /* assign asmOps to operand & result */
1943     pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1944     pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1945
1946     /* if both are in bit space then 
1947     a special case */
1948     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1949         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1950
1951         pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1952         pic16_emitcode("cpl","c"); 
1953         pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1954         goto release; 
1955     } 
1956
1957     size = AOP_SIZE(IC_RESULT(ic));
1958     while (size--) {
1959 /*
1960         char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1961         MOVA(l);       
1962         pic16_emitcode("cpl","a");
1963         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1964 */
1965         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1966               pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
1967         } else {
1968                 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1969                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1970         }
1971         offset++;
1972
1973     }
1974
1975
1976 release:
1977     /* release the aops */
1978     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1979     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1980 }
1981
1982 /*-----------------------------------------------------------------*/
1983 /* genUminusFloat - unary minus for floating points                */
1984 /*-----------------------------------------------------------------*/
1985 static void genUminusFloat(operand *op,operand *result)
1986 {
1987     int size ,offset =0 ;
1988     char *l;
1989
1990     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1991     /* for this we just need to flip the 
1992     first it then copy the rest in place */
1993     size = AOP_SIZE(op) - 1;
1994     l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1995
1996     MOVA(l);    
1997
1998     pic16_emitcode("cpl","acc.7");
1999     pic16_aopPut(AOP(result),"a",3);    
2000
2001     while(size--) {
2002         pic16_aopPut(AOP(result),
2003                pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2004                offset);
2005         offset++;
2006     }          
2007 }
2008
2009 /*-----------------------------------------------------------------*/
2010 /* genUminus - unary minus code generation                         */
2011 /*-----------------------------------------------------------------*/
2012 static void genUminus (iCode *ic)
2013 {
2014   int size, i;
2015   sym_link *optype, *rtype;
2016
2017
2018   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2019   /* assign asmops */
2020   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2021   pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2022
2023   /* if both in bit space then special
2024      case */
2025   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2026       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
2027
2028     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
2029     pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2030     pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
2031
2032     goto release; 
2033   } 
2034
2035   optype = operandType(IC_LEFT(ic));
2036   rtype = operandType(IC_RESULT(ic));
2037
2038   /* if float then do float stuff */
2039   if (IS_FLOAT(optype)) {
2040     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2041     goto release;
2042   }
2043
2044   /* otherwise subtract from zero by taking the 2's complement */
2045   size = AOP_SIZE(IC_LEFT(ic));
2046
2047   for(i=0; i<size; i++) {
2048     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2049       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
2050     else {
2051       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2052       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2053     }
2054   }
2055
2056   pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
2057   for(i=1; i<size; i++) {
2058     emitSKPNZ;
2059     pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
2060   }
2061
2062  release:
2063   /* release the aops */
2064   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2065   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2066 }
2067
2068 /*-----------------------------------------------------------------*/
2069 /* saveRegisters - will look for a call and save the registers     */
2070 /*-----------------------------------------------------------------*/
2071 static void saveRegisters(iCode *lic) 
2072 {
2073     int i;
2074     iCode *ic;
2075     bitVect *rsave;
2076     sym_link *dtype;
2077
2078     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2079     /* look for call */
2080     for (ic = lic ; ic ; ic = ic->next) 
2081         if (ic->op == CALL || ic->op == PCALL)
2082             break;
2083
2084     if (!ic) {
2085         fprintf(stderr,"found parameter push with no function call\n");
2086         return ;
2087     }
2088
2089     /* if the registers have been saved already then
2090     do nothing */
2091     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2092         return ;
2093
2094     /* find the registers in use at this time 
2095     and push them away to safety */
2096     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2097                           ic->rUsed);
2098
2099     ic->regsSaved = 1;
2100     if (options.useXstack) {
2101         if (bitVectBitValue(rsave,R0_IDX))
2102             pic16_emitcode("mov","b,r0");
2103         pic16_emitcode("mov","r0,%s",spname);
2104         for (i = 0 ; i < pic16_nRegs ; i++) {
2105             if (bitVectBitValue(rsave,i)) {
2106                 if (i == R0_IDX)
2107                     pic16_emitcode("mov","a,b");
2108                 else
2109                     pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2110                 pic16_emitcode("movx","@r0,a");
2111                 pic16_emitcode("inc","r0");
2112             }
2113         }
2114         pic16_emitcode("mov","%s,r0",spname);
2115         if (bitVectBitValue(rsave,R0_IDX))
2116             pic16_emitcode("mov","r0,b");           
2117     }// else
2118     //for (i = 0 ; i < pic16_nRegs ; i++) {
2119     //    if (bitVectBitValue(rsave,i))
2120     //  pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2121     //}
2122
2123     dtype = operandType(IC_LEFT(ic));
2124     if (currFunc && dtype && 
2125         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2126         IFFUNC_ISISR(currFunc->type) &&
2127         !ic->bankSaved) 
2128
2129         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2130
2131 }
2132 /*-----------------------------------------------------------------*/
2133 /* unsaveRegisters - pop the pushed registers                      */
2134 /*-----------------------------------------------------------------*/
2135 static void unsaveRegisters (iCode *ic)
2136 {
2137     int i;
2138     bitVect *rsave;
2139
2140     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2141     /* find the registers in use at this time 
2142     and push them away to safety */
2143     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2144                           ic->rUsed);
2145     
2146     if (options.useXstack) {
2147         pic16_emitcode("mov","r0,%s",spname);   
2148         for (i =  pic16_nRegs ; i >= 0 ; i--) {
2149             if (bitVectBitValue(rsave,i)) {
2150                 pic16_emitcode("dec","r0");
2151                 pic16_emitcode("movx","a,@r0");
2152                 if (i == R0_IDX)
2153                     pic16_emitcode("mov","b,a");
2154                 else
2155                     pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2156             }       
2157
2158         }
2159         pic16_emitcode("mov","%s,r0",spname);
2160         if (bitVectBitValue(rsave,R0_IDX))
2161             pic16_emitcode("mov","r0,b");
2162     } //else
2163     //for (i =  pic16_nRegs ; i >= 0 ; i--) {
2164     //    if (bitVectBitValue(rsave,i))
2165     //  pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2166     //}
2167
2168 }  
2169
2170
2171 /*-----------------------------------------------------------------*/
2172 /* pushSide -                                                      */
2173 /*-----------------------------------------------------------------*/
2174 static void pushSide(operand * oper, int size)
2175 {
2176 #if 0
2177         int offset = 0;
2178     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2179         while (size--) {
2180                 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2181                 if (AOP_TYPE(oper) != AOP_REG &&
2182                     AOP_TYPE(oper) != AOP_DIR &&
2183                     strcmp(l,"a") ) {
2184                         pic16_emitcode("mov","a,%s",l);
2185                         pic16_emitcode("push","acc");
2186                 } else
2187                         pic16_emitcode("push","%s",l);
2188         }
2189 #endif
2190 }
2191
2192 /*-----------------------------------------------------------------*/
2193 /* assignResultValue -                                             */
2194 /*-----------------------------------------------------------------*/
2195 static void assignResultValue(operand * oper)
2196 {
2197   int size = AOP_SIZE(oper);
2198
2199   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2200
2201   DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2202
2203   if(!GpsuedoStkPtr) {
2204     /* The last byte in the assignment is in W */
2205     size--;
2206     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2207     GpsuedoStkPtr++;
2208   }
2209
2210   while (size--) {
2211     pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2212     GpsuedoStkPtr++;
2213     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2214   }
2215 }
2216
2217
2218 /*-----------------------------------------------------------------*/
2219 /* genIpush - genrate code for pushing this gets a little complex  */
2220 /*-----------------------------------------------------------------*/
2221 static void genIpush (iCode *ic)
2222 {
2223
2224   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2225 #if 0
2226     int size, offset = 0 ;
2227     char *l;
2228
2229
2230     /* if this is not a parm push : ie. it is spill push 
2231     and spill push is always done on the local stack */
2232     if (!ic->parmPush) {
2233
2234         /* and the item is spilt then do nothing */
2235         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2236             return ;
2237
2238         pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2239         size = AOP_SIZE(IC_LEFT(ic));
2240         /* push it on the stack */
2241         while(size--) {
2242             l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2243             if (*l == '#') {
2244                 MOVA(l);
2245                 l = "acc";
2246             }
2247             pic16_emitcode("push","%s",l);
2248         }
2249         return ;        
2250     }
2251
2252     /* this is a paramter push: in this case we call
2253     the routine to find the call and save those
2254     registers that need to be saved */   
2255     saveRegisters(ic);
2256
2257     /* then do the push */
2258     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2259
2260
2261         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2262     size = AOP_SIZE(IC_LEFT(ic));
2263
2264     while (size--) {
2265         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2266         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2267             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2268             strcmp(l,"a") ) {
2269             pic16_emitcode("mov","a,%s",l);
2270             pic16_emitcode("push","acc");
2271         } else
2272             pic16_emitcode("push","%s",l);
2273     }       
2274
2275     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2276 #endif
2277 }
2278
2279 /*-----------------------------------------------------------------*/
2280 /* genIpop - recover the registers: can happen only for spilling   */
2281 /*-----------------------------------------------------------------*/
2282 static void genIpop (iCode *ic)
2283 {
2284   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2285 #if 0
2286     int size,offset ;
2287
2288
2289     /* if the temp was not pushed then */
2290     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2291         return ;
2292
2293     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2294     size = AOP_SIZE(IC_LEFT(ic));
2295     offset = (size-1);
2296     while (size--) 
2297         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2298                                    FALSE,TRUE));
2299
2300     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2301 #endif
2302 }
2303
2304 /*-----------------------------------------------------------------*/
2305 /* unsaverbank - restores the resgister bank from stack            */
2306 /*-----------------------------------------------------------------*/
2307 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2308 {
2309   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2310 #if 0
2311     int i;
2312     asmop *aop ;
2313     regs *r = NULL;
2314
2315     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2316     if (popPsw) {
2317         if (options.useXstack) {
2318             aop = newAsmop(0);
2319             r = getFreePtr(ic,&aop,FALSE);
2320             
2321             
2322             pic16_emitcode("mov","%s,_spx",r->name);
2323             pic16_emitcode("movx","a,@%s",r->name);
2324             pic16_emitcode("mov","psw,a");
2325             pic16_emitcode("dec","%s",r->name);
2326             
2327         }else
2328             pic16_emitcode ("pop","psw");
2329     }
2330
2331     for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2332         if (options.useXstack) {       
2333             pic16_emitcode("movx","a,@%s",r->name);
2334             //pic16_emitcode("mov","(%s+%d),a",
2335             //       regspic16[i].base,8*bank+regspic16[i].offset);
2336             pic16_emitcode("dec","%s",r->name);
2337
2338         } else 
2339           pic16_emitcode("pop",""); //"(%s+%d)",
2340         //regspic16[i].base,8*bank); //+regspic16[i].offset);
2341     }
2342
2343     if (options.useXstack) {
2344
2345         pic16_emitcode("mov","_spx,%s",r->name);
2346         pic16_freeAsmop(NULL,aop,ic,TRUE);
2347
2348     }
2349 #endif 
2350 }
2351
2352 /*-----------------------------------------------------------------*/
2353 /* saverbank - saves an entire register bank on the stack          */
2354 /*-----------------------------------------------------------------*/
2355 static void saverbank (int bank, iCode *ic, bool pushPsw)
2356 {
2357   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2358 #if 0
2359     int i;
2360     asmop *aop ;
2361     regs *r = NULL;
2362
2363     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2364     if (options.useXstack) {
2365
2366         aop = newAsmop(0);
2367         r = getFreePtr(ic,&aop,FALSE);  
2368         pic16_emitcode("mov","%s,_spx",r->name);
2369
2370     }
2371
2372     for (i = 0 ; i < pic16_nRegs ;i++) {
2373         if (options.useXstack) {
2374             pic16_emitcode("inc","%s",r->name);
2375             //pic16_emitcode("mov","a,(%s+%d)",
2376             //         regspic16[i].base,8*bank+regspic16[i].offset);
2377             pic16_emitcode("movx","@%s,a",r->name);           
2378         } else 
2379           pic16_emitcode("push","");// "(%s+%d)",
2380                      //regspic16[i].base,8*bank+regspic16[i].offset);
2381     }
2382     
2383     if (pushPsw) {
2384         if (options.useXstack) {
2385             pic16_emitcode("mov","a,psw");
2386             pic16_emitcode("movx","@%s,a",r->name);     
2387             pic16_emitcode("inc","%s",r->name);
2388             pic16_emitcode("mov","_spx,%s",r->name);       
2389             pic16_freeAsmop (NULL,aop,ic,TRUE);
2390             
2391         } else
2392             pic16_emitcode("push","psw");
2393         
2394         pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2395     }
2396     ic->bankSaved = 1;
2397 #endif
2398 }
2399
2400 /*-----------------------------------------------------------------*/
2401 /* genCall - generates a call statement                            */
2402 /*-----------------------------------------------------------------*/
2403 static void genCall (iCode *ic)
2404 {
2405   sym_link *dtype;   
2406
2407   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2408
2409   /* if caller saves & we have not saved then */
2410   if (!ic->regsSaved)
2411     saveRegisters(ic);
2412
2413   /* if we are calling a function that is not using
2414      the same register bank then we need to save the
2415      destination registers on the stack */
2416   dtype = operandType(IC_LEFT(ic));
2417   if (currFunc && dtype && 
2418       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2419       IFFUNC_ISISR(currFunc->type) &&
2420       !ic->bankSaved) 
2421
2422     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2423
2424   /* if send set is not empty the assign */
2425   if (_G.sendSet) {
2426     iCode *sic;
2427     /* For the Pic port, there is no data stack.
2428      * So parameters passed to functions are stored
2429      * in registers. (The pCode optimizer will get
2430      * rid of most of these :).
2431      */
2432     int psuedoStkPtr=-1; 
2433     int firstTimeThruLoop = 1;
2434
2435     _G.sendSet = reverseSet(_G.sendSet);
2436
2437     /* First figure how many parameters are getting passed */
2438     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2439          sic = setNextItem(_G.sendSet)) {
2440
2441       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2442       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2443       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2444     }
2445
2446     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2447          sic = setNextItem(_G.sendSet)) {
2448       int size, offset = 0;
2449
2450       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2451       size = AOP_SIZE(IC_LEFT(sic));
2452
2453       while (size--) {
2454         DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2455                              pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2456
2457         if(!firstTimeThruLoop) {
2458           /* If this is not the first time we've been through the loop
2459            * then we need to save the parameter in a temporary
2460            * register. The last byte of the last parameter is
2461            * passed in W. */
2462           pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2463
2464         }
2465         firstTimeThruLoop=0;
2466
2467         //if (strcmp(l,fReturn[offset])) {
2468         mov2w (AOP(IC_LEFT(sic)),  offset);
2469 /*
2470         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2471              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2472           pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2473         else
2474           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2475 */
2476         //}
2477         offset++;
2478       }
2479       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2480     }
2481     _G.sendSet = NULL;
2482   }
2483   /* make the call */
2484   pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2485                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2486                                       OP_SYMBOL(IC_LEFT(ic))->name));
2487
2488   GpsuedoStkPtr=0;
2489   /* if we need assign a result value */
2490   if ((IS_ITEMP(IC_RESULT(ic)) && 
2491        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2492         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2493       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2494
2495     _G.accInUse++;
2496     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2497     _G.accInUse--;
2498
2499     assignResultValue(IC_RESULT(ic));
2500
2501     DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2502                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2503                 
2504     pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2505   }
2506
2507   /* adjust the stack for parameters if 
2508      required */
2509   if (ic->parmBytes) {
2510     int i;
2511     if (ic->parmBytes > 3) {
2512       pic16_emitcode("mov","a,%s",spname);
2513       pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2514       pic16_emitcode("mov","%s,a",spname);
2515     } else 
2516       for ( i = 0 ; i <  ic->parmBytes ;i++)
2517         pic16_emitcode("dec","%s",spname);
2518
2519   }
2520
2521   /* if register bank was saved then pop them */
2522   if (ic->bankSaved)
2523     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2524
2525   /* if we hade saved some registers then unsave them */
2526   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2527     unsaveRegisters (ic);
2528
2529
2530 }
2531
2532 /*-----------------------------------------------------------------*/
2533 /* genPcall - generates a call by pointer statement                */
2534 /*-----------------------------------------------------------------*/
2535 static void genPcall (iCode *ic)
2536 {
2537     sym_link *dtype;
2538     symbol *rlbl = newiTempLabel(NULL);
2539
2540
2541     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2542     /* if caller saves & we have not saved then */
2543     if (!ic->regsSaved)
2544         saveRegisters(ic);
2545
2546     /* if we are calling a function that is not using
2547     the same register bank then we need to save the
2548     destination registers on the stack */
2549     dtype = operandType(IC_LEFT(ic));
2550     if (currFunc && dtype && 
2551         IFFUNC_ISISR(currFunc->type) &&
2552         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2553         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2554
2555
2556     /* push the return address on to the stack */
2557     pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2558     pic16_emitcode("push","acc");    
2559     pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2560     pic16_emitcode("push","acc");
2561     
2562     if (options.model == MODEL_FLAT24)
2563     {
2564         pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2565         pic16_emitcode("push","acc");    
2566     }
2567
2568     /* now push the calling address */
2569     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2570
2571     pushSide(IC_LEFT(ic), FPTRSIZE);
2572
2573     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2574
2575     /* if send set is not empty the assign */
2576     if (_G.sendSet) {
2577         iCode *sic ;
2578
2579         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2580              sic = setNextItem(_G.sendSet)) {
2581             int size, offset = 0;
2582             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2583             size = AOP_SIZE(IC_LEFT(sic));
2584             while (size--) {
2585                 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2586                                 FALSE,FALSE);
2587                 if (strcmp(l,fReturn[offset]))
2588                     pic16_emitcode("mov","%s,%s",
2589                              fReturn[offset],
2590                              l);
2591                 offset++;
2592             }
2593             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2594         }
2595         _G.sendSet = NULL;
2596     }
2597
2598     pic16_emitcode("ret","");
2599     pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2600
2601
2602     /* if we need assign a result value */
2603     if ((IS_ITEMP(IC_RESULT(ic)) &&
2604          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2605           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2606         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2607
2608         _G.accInUse++;
2609         pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2610         _G.accInUse--;
2611         
2612         assignResultValue(IC_RESULT(ic));
2613
2614         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2615     }
2616
2617     /* adjust the stack for parameters if 
2618     required */
2619     if (ic->parmBytes) {
2620         int i;
2621         if (ic->parmBytes > 3) {
2622             pic16_emitcode("mov","a,%s",spname);
2623             pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2624             pic16_emitcode("mov","%s,a",spname);
2625         } else 
2626             for ( i = 0 ; i <  ic->parmBytes ;i++)
2627                 pic16_emitcode("dec","%s",spname);
2628
2629     }
2630
2631     /* if register bank was saved then unsave them */
2632     if (currFunc && dtype && 
2633         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2634         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2635
2636     /* if we hade saved some registers then
2637     unsave them */
2638     if (ic->regsSaved)
2639         unsaveRegisters (ic);
2640
2641 }
2642
2643 /*-----------------------------------------------------------------*/
2644 /* resultRemat - result  is rematerializable                       */
2645 /*-----------------------------------------------------------------*/
2646 static int resultRemat (iCode *ic)
2647 {
2648   //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2649   if (SKIP_IC(ic) || ic->op == IFX)
2650     return 0;
2651
2652   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2653     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2654     if (sym->remat && !POINTER_SET(ic)) 
2655       return 1;
2656   }
2657
2658   return 0;
2659 }
2660
2661 #if defined(__BORLANDC__) || defined(_MSC_VER)
2662 #define STRCASECMP stricmp
2663 #else
2664 #define STRCASECMP strcasecmp
2665 #endif
2666
2667 #if 0
2668 /*-----------------------------------------------------------------*/
2669 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2670 /*-----------------------------------------------------------------*/
2671 static bool inExcludeList(char *s)
2672 {
2673   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2674     int i =0;
2675     
2676     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2677     if (options.excludeRegs[i] &&
2678     STRCASECMP(options.excludeRegs[i],"none") == 0)
2679         return FALSE ;
2680
2681     for ( i = 0 ; options.excludeRegs[i]; i++) {
2682         if (options.excludeRegs[i] &&
2683         STRCASECMP(s,options.excludeRegs[i]) == 0)
2684             return TRUE;
2685     }
2686     return FALSE ;
2687 }
2688 #endif
2689
2690 /*-----------------------------------------------------------------*/
2691 /* genFunction - generated code for function entry                 */
2692 /*-----------------------------------------------------------------*/
2693 static void genFunction (iCode *ic)
2694 {
2695     symbol *sym;
2696     sym_link *ftype;
2697
2698     DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2699
2700     labelOffset += (max_key+4);
2701     max_key=0;
2702     GpsuedoStkPtr=0;
2703     _G.nRegsSaved = 0;
2704     /* create the function header */
2705     pic16_emitcode(";","-----------------------------------------");
2706     pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2707     pic16_emitcode(";","-----------------------------------------");
2708
2709     pic16_emitcode("","%s:",sym->rname);
2710     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2711
2712     ftype = operandType(IC_LEFT(ic));
2713
2714     /* if critical function then turn interrupts off */
2715     if (IFFUNC_ISCRITICAL(ftype))
2716         pic16_emitcode("clr","ea");
2717
2718     /* here we need to generate the equates for the
2719        register bank if required */
2720 #if 0
2721     if (FUNC_REGBANK(ftype) != rbank) {
2722         int i ;
2723
2724         rbank = FUNC_REGBANK(ftype);
2725         for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2726             if (strcmp(regspic16[i].base,"0") == 0)
2727                 pic16_emitcode("","%s = 0x%02x",
2728                          regspic16[i].dname,
2729                          8*rbank+regspic16[i].offset);
2730             else
2731                 pic16_emitcode ("","%s = %s + 0x%02x",
2732                           regspic16[i].dname,
2733                           regspic16[i].base,
2734                           8*rbank+regspic16[i].offset);
2735         }
2736     }
2737 #endif
2738
2739     /* if this is an interrupt service routine then
2740     save acc, b, dpl, dph  */
2741     if (IFFUNC_ISISR(sym->type)) {
2742
2743 #if 0
2744         pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2745         
2746         /* what is the reason of having these 3 NOPS? VR - 030701 */
2747         pic16_emitpcodeNULLop(POC_NOP);
2748         pic16_emitpcodeNULLop(POC_NOP);
2749         pic16_emitpcodeNULLop(POC_NOP);
2750 #endif
2751
2752       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
2753       pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2754       pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2755       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
2756
2757       pic16_pBlockConvert2ISR(pb);
2758 #if 0  
2759         if (!inExcludeList("acc"))          
2760             pic16_emitcode ("push","acc");      
2761         if (!inExcludeList("b"))
2762             pic16_emitcode ("push","b");
2763         if (!inExcludeList("dpl"))
2764             pic16_emitcode ("push","dpl");
2765         if (!inExcludeList("dph"))
2766             pic16_emitcode ("push","dph");
2767         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2768         {
2769             pic16_emitcode ("push", "dpx");
2770             /* Make sure we're using standard DPTR */
2771             pic16_emitcode ("push", "dps");
2772             pic16_emitcode ("mov", "dps, #0x00");
2773             if (options.stack10bit)
2774             {   
2775                 /* This ISR could conceivably use DPTR2. Better save it. */
2776                 pic16_emitcode ("push", "dpl1");
2777                 pic16_emitcode ("push", "dph1");
2778                 pic16_emitcode ("push", "dpx1");
2779             }
2780         }
2781         /* if this isr has no bank i.e. is going to
2782            run with bank 0 , then we need to save more
2783            registers :-) */
2784         if (!FUNC_REGBANK(sym->type)) {
2785
2786             /* if this function does not call any other
2787                function then we can be economical and
2788                save only those registers that are used */
2789             if (! IFFUNC_HASFCALL(sym->type)) {
2790                 int i;
2791
2792                 /* if any registers used */
2793                 if (sym->regsUsed) {
2794                     /* save the registers used */
2795                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2796                         if (bitVectBitValue(sym->regsUsed,i) ||
2797                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2798                           pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                         
2799                     }
2800                 }
2801                 
2802             } else {
2803                 /* this function has  a function call cannot
2804                    determines register usage so we will have the
2805                    entire bank */
2806                 saverbank(0,ic,FALSE);
2807             }       
2808         }
2809 #endif
2810     } else {
2811         /* if callee-save to be used for this function
2812            then save the registers being used in this function */
2813         if (IFFUNC_CALLEESAVES(sym->type)) {
2814             int i;
2815             
2816             /* if any registers used */
2817             if (sym->regsUsed) {
2818                 /* save the registers used */
2819                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2820                     if (bitVectBitValue(sym->regsUsed,i) ||
2821                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2822                       //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2823                         _G.nRegsSaved++;
2824                     }
2825                 }
2826             }
2827         }
2828     }
2829
2830     /* set the register bank to the desired value */
2831     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2832         pic16_emitcode("push","psw");
2833         pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2834     }
2835
2836     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2837
2838         if (options.useXstack) {
2839             pic16_emitcode("mov","r0,%s",spname);
2840             pic16_emitcode("mov","a,_bp");
2841             pic16_emitcode("movx","@r0,a");
2842             pic16_emitcode("inc","%s",spname);
2843         }
2844         else
2845         {
2846             /* set up the stack */
2847             pic16_emitcode ("push","_bp");     /* save the callers stack  */
2848         }
2849         pic16_emitcode ("mov","_bp,%s",spname);
2850     }
2851
2852     /* adjust the stack for the function */
2853     if (sym->stack) {
2854
2855         int i = sym->stack;
2856         if (i > 256 ) 
2857             werror(W_STACK_OVERFLOW,sym->name);
2858
2859         if (i > 3 && sym->recvSize < 4) {              
2860
2861             pic16_emitcode ("mov","a,sp");
2862             pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2863             pic16_emitcode ("mov","sp,a");
2864            
2865         }
2866         else
2867             while(i--)
2868                 pic16_emitcode("inc","sp");
2869     }
2870
2871      if (sym->xstack) {
2872
2873         pic16_emitcode ("mov","a,_spx");
2874         pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2875         pic16_emitcode ("mov","_spx,a");
2876     }    
2877
2878 }
2879
2880 /*-----------------------------------------------------------------*/
2881 /* genEndFunction - generates epilogue for functions               */
2882 /*-----------------------------------------------------------------*/
2883 static void genEndFunction (iCode *ic)
2884 {
2885     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2886
2887     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2888
2889     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2890     {
2891         pic16_emitcode ("mov","%s,_bp",spname);
2892     }
2893
2894     /* if use external stack but some variables were
2895     added to the local stack then decrement the
2896     local stack */
2897     if (options.useXstack && sym->stack) {      
2898         pic16_emitcode("mov","a,sp");
2899         pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2900         pic16_emitcode("mov","sp,a");
2901     }
2902
2903
2904     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2905         if (options.useXstack) {
2906             pic16_emitcode("mov","r0,%s",spname);
2907             pic16_emitcode("movx","a,@r0");
2908             pic16_emitcode("mov","_bp,a");
2909             pic16_emitcode("dec","%s",spname);
2910         }
2911         else
2912         {
2913             pic16_emitcode ("pop","_bp");
2914         }
2915     }
2916
2917     /* restore the register bank  */    
2918     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2919         pic16_emitcode ("pop","psw");
2920
2921     if (IFFUNC_ISISR(sym->type)) {
2922
2923         /* now we need to restore the registers */
2924         /* if this isr has no bank i.e. is going to
2925            run with bank 0 , then we need to save more
2926            registers :-) */
2927         if (!FUNC_REGBANK(sym->type)) {
2928             
2929             /* if this function does not call any other
2930                function then we can be economical and
2931                save only those registers that are used */
2932             if (! IFFUNC_HASFCALL(sym->type)) {
2933                 int i;
2934                 
2935                 /* if any registers used */
2936                 if (sym->regsUsed) {
2937                     /* save the registers used */
2938                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2939                         if (bitVectBitValue(sym->regsUsed,i) ||
2940                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2941                           pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2942                     }
2943                 }
2944                 
2945             } else {
2946                 /* this function has  a function call cannot
2947                    determines register usage so we will have the
2948                    entire bank */
2949                 unsaverbank(0,ic,FALSE);
2950             }       
2951         }
2952 #if 0
2953         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2954         {
2955             if (options.stack10bit)
2956             {
2957                 pic16_emitcode ("pop", "dpx1");
2958                 pic16_emitcode ("pop", "dph1");
2959                 pic16_emitcode ("pop", "dpl1");
2960             }   
2961             pic16_emitcode ("pop", "dps");
2962             pic16_emitcode ("pop", "dpx");
2963         }
2964         if (!inExcludeList("dph"))
2965             pic16_emitcode ("pop","dph");
2966         if (!inExcludeList("dpl"))
2967             pic16_emitcode ("pop","dpl");
2968         if (!inExcludeList("b"))
2969             pic16_emitcode ("pop","b");
2970         if (!inExcludeList("acc"))
2971             pic16_emitcode ("pop","acc");
2972
2973         if (IFFUNC_ISCRITICAL(sym->type))
2974             pic16_emitcode("setb","ea");
2975 #endif
2976
2977         /* if debug then send end of function */
2978 /*      if (options.debug && currFunc) { */
2979         if (currFunc) {
2980             _G.debugLine = 1;
2981             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2982                      FileBaseName(ic->filename),currFunc->lastLine,
2983                      ic->level,ic->block); 
2984             if (IS_STATIC(currFunc->etype))         
2985                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2986             else
2987                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2988             _G.debugLine = 0;
2989         }
2990         
2991 //      pic16_emitcode ("reti","");
2992
2993         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2994         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2995         pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
2996         pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
2997         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2998
2999 #if 0
3000         pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3001 #endif
3002
3003         pic16_emitpcodeNULLop(POC_RETFIE);
3004
3005     }
3006     else {
3007         if (IFFUNC_ISCRITICAL(sym->type))
3008             pic16_emitcode("setb","ea");
3009         
3010         if (IFFUNC_CALLEESAVES(sym->type)) {
3011             int i;
3012             
3013             /* if any registers used */
3014             if (sym->regsUsed) {
3015                 /* save the registers used */
3016                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3017                     if (bitVectBitValue(sym->regsUsed,i) ||
3018                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3019                       pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3020                 }
3021             }
3022             
3023         }
3024
3025         /* if debug then send end of function */
3026         if (currFunc) {
3027             _G.debugLine = 1;
3028             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3029                      FileBaseName(ic->filename),currFunc->lastLine,
3030                      ic->level,ic->block); 
3031             if (IS_STATIC(currFunc->etype))         
3032                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
3033             else
3034                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3035             _G.debugLine = 0;
3036         }
3037
3038         pic16_emitcode ("return","");
3039         pic16_emitpcodeNULLop(POC_RETURN);
3040
3041         /* Mark the end of a function */
3042         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3043     }
3044
3045 }
3046
3047 /*-----------------------------------------------------------------*/
3048 /* genRet - generate code for return statement                     */
3049 /*-----------------------------------------------------------------*/
3050 static void genRet (iCode *ic)
3051 {
3052   int size,offset = 0 , pushed = 0;
3053     
3054   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3055   /* if we have no return value then
3056      just generate the "ret" */
3057   if (!IC_LEFT(ic)) 
3058     goto jumpret;       
3059     
3060   /* we have something to return then
3061      move the return value into place */
3062   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3063   size = AOP_SIZE(IC_LEFT(ic));
3064     
3065   while (size--) {
3066     char *l ;
3067     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3068       /* #NOCHANGE */
3069       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3070                  FALSE,TRUE);
3071       pic16_emitcode("push","%s",l);
3072       pushed++;
3073     } else {
3074       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3075                  FALSE,FALSE);
3076       if (strcmp(fReturn[offset],l)) {
3077         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3078             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3079           pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3080         }else {
3081           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3082         }
3083         if(size) {
3084           pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3085         }
3086         offset++;
3087       }
3088     }
3089   }    
3090
3091   if (pushed) {
3092     while(pushed) {
3093       pushed--;
3094       if (strcmp(fReturn[pushed],"a"))
3095         pic16_emitcode("pop",fReturn[pushed]);
3096       else
3097         pic16_emitcode("pop","acc");
3098     }
3099   }
3100   pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3101     
3102  jumpret:
3103   /* generate a jump to the return label
3104      if the next is not the return statement */
3105   if (!(ic->next && ic->next->op == LABEL &&
3106         IC_LABEL(ic->next) == returnLabel)) {
3107         
3108     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3109     pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3110   }
3111     
3112 }
3113
3114 /*-----------------------------------------------------------------*/
3115 /* genLabel - generates a label                                    */
3116 /*-----------------------------------------------------------------*/
3117 static void genLabel (iCode *ic)
3118 {
3119     /* special case never generate */
3120     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3121     if (IC_LABEL(ic) == entryLabel)
3122         return ;
3123
3124     pic16_emitpLabel(IC_LABEL(ic)->key);
3125     pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3126 }
3127
3128 /*-----------------------------------------------------------------*/
3129 /* genGoto - generates a goto                                      */
3130 /*-----------------------------------------------------------------*/
3131 //tsd
3132 static void genGoto (iCode *ic)
3133 {
3134   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3135   pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3136 }
3137
3138
3139 /*-----------------------------------------------------------------*/
3140 /* genMultbits :- multiplication of bits                           */
3141 /*-----------------------------------------------------------------*/
3142 static void genMultbits (operand *left, 
3143                          operand *right, 
3144                          operand *result)
3145 {
3146   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3147
3148   if(!pic16_sameRegs(AOP(result),AOP(right)))
3149     pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),0));
3150
3151   pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3152   pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3153   pic16_emitpcode(POC_BCF,  pic16_popGet(AOP(result),0));
3154
3155 }
3156
3157
3158 /*-----------------------------------------------------------------*/
3159 /* genMultOneByte : 8 bit multiplication & division                */
3160 /*-----------------------------------------------------------------*/
3161 static void genMultOneByte (operand *left,
3162                             operand *right,
3163                             operand *result)
3164 {
3165   sym_link *opetype = operandType(result);
3166
3167   // symbol *lbl ;
3168   int size,offset;
3169
3170   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3171   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3172   DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3173
3174   /* (if two literals, the value is computed before) */
3175   /* if one literal, literal on the right */
3176   if (AOP_TYPE(left) == AOP_LIT){
3177     operand *t = right;
3178     right = left;
3179     left = t;
3180   }
3181
3182   size = AOP_SIZE(result);
3183   if(size == 1) {
3184
3185     if (AOP_TYPE(right) == AOP_LIT){
3186       pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3187                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3188                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3189                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3190       pic16_emitcode("call","genMultLit");
3191     } else {
3192       pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3193                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3194                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3195                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3196       pic16_emitcode("call","pic16_genMult8X8_8");
3197
3198     }
3199     pic16_genMult8X8_8 (left, right,result);
3200
3201
3202     /* signed or unsigned */
3203     //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3204     //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3205     //MOVA(l);       
3206     //pic16_emitcode("mul","ab");
3207     /* if result size = 1, mul signed = mul unsigned */
3208     //pic16_aopPut(AOP(result),"a",0);
3209
3210   } else {  // (size > 1)
3211
3212     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3213                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3214                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3215                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
3216
3217     if (SPEC_USIGN(opetype)){
3218       pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3219       pic16_genUMult8X8_16 (left, right, result, NULL);
3220
3221       if (size > 2) {
3222         /* for filling the MSBs */
3223         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),2));
3224         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),3));
3225       }
3226     }
3227     else{
3228       pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3229
3230       pic16_emitcode("mov","a,b");
3231
3232       /* adjust the MSB if left or right neg */
3233
3234       /* if one literal */
3235       if (AOP_TYPE(right) == AOP_LIT){
3236         pic16_emitcode("multiply ","right is a lit");
3237         /* AND literal negative */
3238         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3239           /* adjust MSB (c==0 after mul) */
3240           pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3241         }
3242       }
3243       else{
3244         pic16_genSMult8X8_16 (left, right, result, NULL);
3245       }
3246
3247       if(size > 2){
3248         pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3249         /* get the sign */
3250         pic16_emitcode("rlc","a");
3251         pic16_emitcode("subb","a,acc");
3252       }
3253     }
3254
3255     size -= 2;   
3256     offset = 2;
3257     if (size > 0)
3258       while (size--)
3259         pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3260     //pic16_aopPut(AOP(result),"a",offset++);
3261   }
3262 }
3263
3264 /*-----------------------------------------------------------------*/
3265 /* genMult - generates code for multiplication                     */
3266 /*-----------------------------------------------------------------*/
3267 static void genMult (iCode *ic)
3268 {
3269     operand *left = IC_LEFT(ic);
3270     operand *right = IC_RIGHT(ic);
3271     operand *result= IC_RESULT(ic);   
3272
3273     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3274     /* assign the amsops */
3275     pic16_aopOp (left,ic,FALSE);
3276     pic16_aopOp (right,ic,FALSE);
3277     pic16_aopOp (result,ic,TRUE);
3278
3279   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3280
3281     /* special cases first */
3282     /* both are bits */
3283     if (AOP_TYPE(left) == AOP_CRY &&
3284         AOP_TYPE(right)== AOP_CRY) {
3285         genMultbits(left,right,result);
3286         goto release ;
3287     }
3288
3289     /* if both are of size == 1 */
3290     if (AOP_SIZE(left) == 1 &&
3291         AOP_SIZE(right) == 1 ) {
3292         genMultOneByte(left,right,result);
3293         goto release ;
3294     }
3295
3296     pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3297
3298     /* should have been converted to function call */
3299     //assert(0) ;
3300
3301 release :
3302     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3303     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3304     pic16_freeAsmop(result,NULL,ic,TRUE); 
3305 }
3306
3307 /*-----------------------------------------------------------------*/
3308 /* genDivbits :- division of bits                                  */
3309 /*-----------------------------------------------------------------*/
3310 static void genDivbits (operand *left, 
3311                         operand *right, 
3312                         operand *result)
3313 {
3314
3315     char *l;
3316
3317     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3318     /* the result must be bit */    
3319     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3320     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3321
3322     MOVA(l);    
3323
3324     pic16_emitcode("div","ab");
3325     pic16_emitcode("rrc","a");
3326     pic16_aopPut(AOP(result),"c",0);
3327 }
3328
3329 /*-----------------------------------------------------------------*/
3330 /* genDivOneByte : 8 bit division                                  */
3331 /*-----------------------------------------------------------------*/
3332 static void genDivOneByte (operand *left,
3333                            operand *right,
3334                            operand *result)
3335 {
3336     sym_link *opetype = operandType(result);
3337     char *l ;
3338     symbol *lbl ;
3339     int size,offset;
3340
3341     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3342     size = AOP_SIZE(result) - 1;
3343     offset = 1;
3344     /* signed or unsigned */
3345     if (SPEC_USIGN(opetype)) {
3346         /* unsigned is easy */
3347         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3348         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3349         MOVA(l);        
3350         pic16_emitcode("div","ab");
3351         pic16_aopPut(AOP(result),"a",0);
3352         while (size--)
3353             pic16_aopPut(AOP(result),zero,offset++);
3354         return ;
3355     }
3356
3357     /* signed is a little bit more difficult */
3358
3359     /* save the signs of the operands */
3360     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3361     MOVA(l);    
3362     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3363     pic16_emitcode("push","acc"); /* save it on the stack */
3364
3365     /* now sign adjust for both left & right */
3366     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3367     MOVA(l);       
3368     lbl = newiTempLabel(NULL);
3369     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3370     pic16_emitcode("cpl","a");   
3371     pic16_emitcode("inc","a");
3372     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3373     pic16_emitcode("mov","b,a");
3374
3375     /* sign adjust left side */
3376     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3377     MOVA(l);
3378
3379     lbl = newiTempLabel(NULL);
3380     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3381     pic16_emitcode("cpl","a");
3382     pic16_emitcode("inc","a");
3383     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3384
3385     /* now the division */
3386     pic16_emitcode("div","ab");
3387     /* we are interested in the lower order
3388     only */
3389     pic16_emitcode("mov","b,a");
3390     lbl = newiTempLabel(NULL);
3391     pic16_emitcode("pop","acc");   
3392     /* if there was an over flow we don't 
3393     adjust the sign of the result */
3394     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3395     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3396     CLRC;
3397     pic16_emitcode("clr","a");
3398     pic16_emitcode("subb","a,b");
3399     pic16_emitcode("mov","b,a");
3400     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3401
3402     /* now we are done */
3403     pic16_aopPut(AOP(result),"b",0);
3404     if(size > 0){
3405         pic16_emitcode("mov","c,b.7");
3406         pic16_emitcode("subb","a,acc");   
3407     }
3408     while (size--)
3409         pic16_aopPut(AOP(result),"a",offset++);
3410
3411 }
3412
3413 /*-----------------------------------------------------------------*/
3414 /* genDiv - generates code for division                            */
3415 /*-----------------------------------------------------------------*/
3416 static void genDiv (iCode *ic)
3417 {
3418     operand *left = IC_LEFT(ic);
3419     operand *right = IC_RIGHT(ic);
3420     operand *result= IC_RESULT(ic);   
3421
3422     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3423     /* assign the amsops */
3424     pic16_aopOp (left,ic,FALSE);
3425     pic16_aopOp (right,ic,FALSE);
3426     pic16_aopOp (result,ic,TRUE);
3427
3428     /* special cases first */
3429     /* both are bits */
3430     if (AOP_TYPE(left) == AOP_CRY &&
3431         AOP_TYPE(right)== AOP_CRY) {
3432         genDivbits(left,right,result);
3433         goto release ;
3434     }
3435
3436     /* if both are of size == 1 */
3437     if (AOP_SIZE(left) == 1 &&
3438         AOP_SIZE(right) == 1 ) {
3439         genDivOneByte(left,right,result);
3440         goto release ;
3441     }
3442
3443     /* should have been converted to function call */
3444     assert(0);
3445 release :
3446     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3447     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3448     pic16_freeAsmop(result,NULL,ic,TRUE); 
3449 }
3450
3451 /*-----------------------------------------------------------------*/
3452 /* genModbits :- modulus of bits                                   */
3453 /*-----------------------------------------------------------------*/
3454 static void genModbits (operand *left, 
3455                         operand *right, 
3456                         operand *result)
3457 {
3458
3459     char *l;
3460
3461     /* the result must be bit */    
3462     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3463     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3464
3465     MOVA(l);       
3466
3467     pic16_emitcode("div","ab");
3468     pic16_emitcode("mov","a,b");
3469     pic16_emitcode("rrc","a");
3470     pic16_aopPut(AOP(result),"c",0);
3471 }
3472
3473 /*-----------------------------------------------------------------*/
3474 /* genModOneByte : 8 bit modulus                                   */
3475 /*-----------------------------------------------------------------*/
3476 static void genModOneByte (operand *left,
3477                            operand *right,
3478                            operand *result)
3479 {
3480     sym_link *opetype = operandType(result);
3481     char *l ;
3482     symbol *lbl ;
3483
3484     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3485     /* signed or unsigned */
3486     if (SPEC_USIGN(opetype)) {
3487         /* unsigned is easy */
3488         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3489         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3490         MOVA(l);    
3491         pic16_emitcode("div","ab");
3492         pic16_aopPut(AOP(result),"b",0);
3493         return ;
3494     }
3495
3496     /* signed is a little bit more difficult */
3497
3498     /* save the signs of the operands */
3499     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3500     MOVA(l);
3501
3502     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3503     pic16_emitcode("push","acc"); /* save it on the stack */
3504
3505     /* now sign adjust for both left & right */
3506     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3507     MOVA(l);
3508
3509     lbl = newiTempLabel(NULL);
3510     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3511     pic16_emitcode("cpl","a");   
3512     pic16_emitcode("inc","a");
3513     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3514     pic16_emitcode("mov","b,a"); 
3515
3516     /* sign adjust left side */
3517     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3518     MOVA(l);
3519
3520     lbl = newiTempLabel(NULL);
3521     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3522     pic16_emitcode("cpl","a");   
3523     pic16_emitcode("inc","a");
3524     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3525
3526     /* now the multiplication */
3527     pic16_emitcode("div","ab");
3528     /* we are interested in the lower order
3529     only */
3530     lbl = newiTempLabel(NULL);
3531     pic16_emitcode("pop","acc");   
3532     /* if there was an over flow we don't 
3533     adjust the sign of the result */
3534     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3535     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3536     CLRC ;
3537     pic16_emitcode("clr","a");
3538     pic16_emitcode("subb","a,b");
3539     pic16_emitcode("mov","b,a");
3540     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3541
3542     /* now we are done */
3543     pic16_aopPut(AOP(result),"b",0);
3544
3545 }
3546
3547 /*-----------------------------------------------------------------*/
3548 /* genMod - generates code for division                            */
3549 /*-----------------------------------------------------------------*/
3550 static void genMod (iCode *ic)
3551 {
3552     operand *left = IC_LEFT(ic);
3553     operand *right = IC_RIGHT(ic);
3554     operand *result= IC_RESULT(ic);  
3555
3556     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3557     /* assign the amsops */
3558     pic16_aopOp (left,ic,FALSE);
3559     pic16_aopOp (right,ic,FALSE);
3560     pic16_aopOp (result,ic,TRUE);
3561
3562     /* special cases first */
3563     /* both are bits */
3564     if (AOP_TYPE(left) == AOP_CRY &&
3565         AOP_TYPE(right)== AOP_CRY) {
3566         genModbits(left,right,result);
3567         goto release ;
3568     }
3569
3570     /* if both are of size == 1 */
3571     if (AOP_SIZE(left) == 1 &&
3572         AOP_SIZE(right) == 1 ) {
3573         genModOneByte(left,right,result);
3574         goto release ;
3575     }
3576
3577     /* should have been converted to function call */
3578     assert(0);
3579
3580 release :
3581     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3582     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3583     pic16_freeAsmop(result,NULL,ic,TRUE); 
3584 }
3585
3586 /*-----------------------------------------------------------------*/
3587 /* genIfxJump :- will create a jump depending on the ifx           */
3588 /*-----------------------------------------------------------------*/
3589 /*
3590   note: May need to add parameter to indicate when a variable is in bit space.
3591 */
3592 static void genIfxJump (iCode *ic, char *jval)
3593 {
3594
3595     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3596     /* if true label then we jump if condition
3597     supplied is true */
3598     if ( IC_TRUE(ic) ) {
3599
3600         if(strcmp(jval,"a") == 0)
3601           emitSKPZ;
3602         else if (strcmp(jval,"c") == 0)
3603           emitSKPC;
3604         else {
3605           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3606           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1));
3607         }
3608
3609         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3610         pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3611
3612     }
3613     else {
3614         /* false label is present */
3615         if(strcmp(jval,"a") == 0)
3616           emitSKPNZ;
3617         else if (strcmp(jval,"c") == 0)
3618           emitSKPNC;
3619         else {
3620           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3621           pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1));
3622         }
3623
3624         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3625         pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3626
3627     }
3628
3629
3630     /* mark the icode as generated */
3631     ic->generated = 1;
3632 }
3633
3634 /*-----------------------------------------------------------------*/
3635 /* genSkip                                                         */
3636 /*-----------------------------------------------------------------*/
3637 static void genSkip(iCode *ifx,int status_bit)
3638 {
3639   if(!ifx)
3640     return;
3641
3642   if ( IC_TRUE(ifx) ) {
3643     switch(status_bit) {
3644     case 'z':
3645       emitSKPNZ;
3646       break;
3647
3648     case 'c':
3649       emitSKPNC;
3650       break;
3651
3652     case 'd':
3653       emitSKPDC;
3654       break;
3655
3656     }
3657
3658     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3659     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3660
3661   } else {
3662
3663     switch(status_bit) {
3664
3665     case 'z':
3666       emitSKPZ;
3667       break;
3668
3669     case 'c':
3670       emitSKPC;
3671       break;
3672
3673     case 'd':
3674       emitSKPDC;
3675       break;
3676     }
3677     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3678     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3679
3680   }
3681
3682 }
3683
3684 /*-----------------------------------------------------------------*/
3685 /* genSkipc                                                        */
3686 /*-----------------------------------------------------------------*/
3687 static void genSkipc(resolvedIfx *rifx)
3688 {
3689   if(!rifx)
3690     return;
3691
3692   if(rifx->condition)
3693     emitSKPC;
3694   else
3695     emitSKPNC;
3696
3697   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3698   rifx->generated = 1;
3699 }
3700
3701 /*-----------------------------------------------------------------*/
3702 /* genSkipz2                                                       */
3703 /*-----------------------------------------------------------------*/
3704 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3705 {
3706   if(!rifx)
3707     return;
3708
3709   if( (rifx->condition ^ invert_condition) & 1)
3710     emitSKPZ;
3711   else
3712     emitSKPNZ;
3713
3714   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3715   rifx->generated = 1;
3716 }
3717
3718 /*-----------------------------------------------------------------*/
3719 /* genSkipz                                                        */
3720 /*-----------------------------------------------------------------*/
3721 static void genSkipz(iCode *ifx, int condition)
3722 {
3723   if(!ifx)
3724     return;
3725
3726   if(condition)
3727     emitSKPNZ;
3728   else
3729     emitSKPZ;
3730
3731   if ( IC_TRUE(ifx) )
3732     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3733   else
3734     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3735
3736   if ( IC_TRUE(ifx) )
3737     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3738   else
3739     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3740
3741 }
3742 /*-----------------------------------------------------------------*/
3743 /* genSkipCond                                                     */
3744 /*-----------------------------------------------------------------*/
3745 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3746 {
3747   if(!rifx)
3748     return;
3749
3750   if(rifx->condition)
3751     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3752   else
3753     pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3754
3755
3756   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3757   rifx->generated = 1;
3758 }
3759
3760 #if 0
3761 /*-----------------------------------------------------------------*/
3762 /* genChkZeroes :- greater or less than comparison                 */
3763 /*     For each byte in a literal that is zero, inclusive or the   */
3764 /*     the corresponding byte in the operand with W                */
3765 /*     returns true if any of the bytes are zero                   */
3766 /*-----------------------------------------------------------------*/
3767 static int genChkZeroes(operand *op, int lit,  int size)
3768 {
3769
3770   int i;
3771   int flag =1;
3772
3773   while(size--) {
3774     i = (lit >> (size*8)) & 0xff;
3775
3776     if(i==0) {
3777       if(flag) 
3778         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3779       else
3780         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3781       flag = 0;
3782     }
3783   }
3784
3785   return (flag==0);
3786 }
3787 #endif
3788
3789 /*-----------------------------------------------------------------*/
3790 /* genCmp :- greater or less than comparison                       */
3791 /*-----------------------------------------------------------------*/
3792 static void genCmp (operand *left,operand *right,
3793                     operand *result, iCode *ifx, int sign)
3794 {
3795   int size; //, offset = 0 ;
3796   unsigned long lit = 0L,i = 0;
3797   resolvedIfx rFalseIfx;
3798   //  resolvedIfx rTrueIfx;
3799   symbol *truelbl;
3800   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3801 /*
3802   if(ifx) {
3803     DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3804     DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3805   }
3806 */
3807
3808   resolveIfx(&rFalseIfx,ifx);
3809   truelbl  = newiTempLabel(NULL);
3810   size = max(AOP_SIZE(left),AOP_SIZE(right));
3811
3812   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3813
3814 #define _swapp
3815
3816   /* if literal is on the right then swap with left */
3817   if ((AOP_TYPE(right) == AOP_LIT)) {
3818     operand *tmp = right ;
3819     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3820     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3821 #ifdef _swapp
3822
3823     lit = (lit - 1) & mask;
3824     right = left;
3825     left = tmp;
3826     rFalseIfx.condition ^= 1;
3827 #endif
3828
3829   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3830     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3831   }
3832
3833
3834   //if(IC_TRUE(ifx) == NULL)
3835   /* if left & right are bit variables */
3836   if (AOP_TYPE(left) == AOP_CRY &&
3837       AOP_TYPE(right) == AOP_CRY ) {
3838     pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3839     pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3840   } else {
3841     /* subtract right from left if at the
3842        end the carry flag is set then we know that
3843        left is greater than right */
3844
3845     //    {
3846
3847     symbol *lbl  = newiTempLabel(NULL);
3848
3849 #ifndef _swapp
3850     if(AOP_TYPE(right) == AOP_LIT) {
3851
3852       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3853
3854       DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3855
3856       /* special cases */
3857
3858       if(lit == 0) {
3859
3860         if(sign != 0) 
3861           genSkipCond(&rFalseIfx,left,size-1,7);
3862         else 
3863           /* no need to compare to 0...*/
3864           /* NOTE: this is a de-generate compare that most certainly 
3865            *       creates some dead code. */
3866           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3867
3868         if(ifx) ifx->generated = 1;
3869         return;
3870
3871       }
3872       size--;
3873
3874       if(size == 0) {
3875         //i = (lit >> (size*8)) & 0xff;
3876         DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3877         
3878         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3879
3880         i = ((0-lit) & 0xff);
3881         if(sign) {
3882           if( i == 0x81) { 
3883             /* lit is 0x7f, all signed chars are less than
3884              * this except for 0x7f itself */
3885             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3886             genSkipz2(&rFalseIfx,0);
3887           } else {
3888             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3889             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3890             genSkipc(&rFalseIfx);
3891           }
3892
3893         } else {
3894           if(lit == 1) {
3895             genSkipz2(&rFalseIfx,1);
3896           } else {
3897             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3898             genSkipc(&rFalseIfx);
3899           }
3900         }
3901
3902         if(ifx) ifx->generated = 1;
3903         return;
3904       }
3905
3906       /* chars are out of the way. now do ints and longs */
3907
3908
3909       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3910         
3911       /* special cases */
3912
3913       if(sign) {
3914
3915         if(lit == 0) {
3916           genSkipCond(&rFalseIfx,left,size,7);
3917           if(ifx) ifx->generated = 1;
3918           return;
3919         }
3920
3921         if(lit <0x100) {
3922           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3923
3924           //rFalseIfx.condition ^= 1;
3925           //genSkipCond(&rFalseIfx,left,size,7);
3926           //rFalseIfx.condition ^= 1;
3927
3928           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3929           if(rFalseIfx.condition)
3930             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3931           else
3932             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3933
3934           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3935           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3936           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3937
3938           while(size > 1)
3939             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3940
3941           if(rFalseIfx.condition) {
3942             emitSKPZ;
3943             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3944
3945           } else {
3946             emitSKPNZ;
3947           }
3948
3949           genSkipc(&rFalseIfx);
3950           pic16_emitpLabel(truelbl->key);
3951           if(ifx) ifx->generated = 1;
3952           return;
3953
3954         }
3955
3956         if(size == 1) {
3957
3958           if( (lit & 0xff) == 0) {
3959             /* lower byte is zero */
3960             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3961             i = ((lit >> 8) & 0xff) ^0x80;
3962             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3963             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3964             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3965             genSkipc(&rFalseIfx);
3966
3967
3968             if(ifx) ifx->generated = 1;
3969             return;
3970
3971           }
3972         } else {
3973           /* Special cases for signed longs */
3974           if( (lit & 0xffffff) == 0) {
3975             /* lower byte is zero */
3976             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3977             i = ((lit >> 8*3) & 0xff) ^0x80;
3978             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3979             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3980             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3981             genSkipc(&rFalseIfx);
3982
3983
3984             if(ifx) ifx->generated = 1;
3985             return;
3986
3987           }
3988
3989         }
3990
3991
3992         if(lit & (0x80 << (size*8))) {
3993           /* lit is negative */
3994           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3995
3996           //genSkipCond(&rFalseIfx,left,size,7);
3997
3998           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3999
4000           if(rFalseIfx.condition)
4001             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4002           else
4003             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4004
4005
4006         } else {
4007           /* lit is positive */
4008           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4009           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4010           if(rFalseIfx.condition)
4011             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4012           else
4013             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4014
4015         }
4016
4017         /*
4018           This works, but is only good for ints.
4019           It also requires a "known zero" register.
4020           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4021           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4022           pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
4023           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4024           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4025           genSkipc(&rFalseIfx);
4026
4027           pic16_emitpLabel(truelbl->key);
4028           if(ifx) ifx->generated = 1;
4029           return;
4030         **/
4031           
4032         /* There are no more special cases, so perform a general compare */
4033   
4034         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4035         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4036
4037         while(size--) {
4038
4039           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4040           emitSKPNZ;
4041           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4042         }
4043         //rFalseIfx.condition ^= 1;
4044         genSkipc(&rFalseIfx);
4045
4046         pic16_emitpLabel(truelbl->key);
4047
4048         if(ifx) ifx->generated = 1;
4049         return;
4050
4051
4052       }
4053
4054
4055       /* sign is out of the way. So now do an unsigned compare */
4056       DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4057
4058
4059       /* General case - compare to an unsigned literal on the right.*/
4060
4061       i = (lit >> (size*8)) & 0xff;
4062       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4063       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4064       while(size--) {
4065         i = (lit >> (size*8)) & 0xff;
4066
4067         if(i) {
4068           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4069           emitSKPNZ;
4070           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4071         } else {
4072           /* this byte of the lit is zero, 
4073            *if it's not the last then OR in the variable */
4074           if(size)
4075             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4076         }
4077       }
4078
4079
4080       pic16_emitpLabel(lbl->key);
4081       //if(emitFinalCheck)
4082       genSkipc(&rFalseIfx);
4083       if(sign)
4084         pic16_emitpLabel(truelbl->key);
4085
4086       if(ifx) ifx->generated = 1;
4087       return;
4088
4089
4090     }
4091 #endif  // _swapp
4092
4093     if(AOP_TYPE(left) == AOP_LIT) {
4094       //symbol *lbl = newiTempLabel(NULL);
4095
4096       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4097
4098
4099       DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4100
4101       /* Special cases */
4102       if((lit == 0) && (sign == 0)){
4103
4104         size--;
4105         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4106         while(size) 
4107           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4108
4109         genSkipz2(&rFalseIfx,0);
4110         if(ifx) ifx->generated = 1;
4111         return;
4112       }
4113
4114       if(size==1) {
4115         /* Special cases */
4116         lit &= 0xff;
4117         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4118           /* degenerate compare can never be true */
4119           if(rFalseIfx.condition == 0)
4120             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4121
4122           if(ifx) ifx->generated = 1;
4123           return;
4124         }
4125
4126         if(sign) {
4127           /* signed comparisons to a literal byte */
4128
4129           int lp1 = (lit+1) & 0xff;
4130
4131           DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4132           switch (lp1) {
4133           case 0:
4134             rFalseIfx.condition ^= 1;
4135             genSkipCond(&rFalseIfx,right,0,7);
4136             break;
4137           case 0x7f:
4138             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4139             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4140             genSkipz2(&rFalseIfx,1);
4141             break;
4142           default:
4143             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4144             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4145             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4146             rFalseIfx.condition ^= 1;
4147             genSkipc(&rFalseIfx);
4148             break;
4149           }
4150         } else {
4151           /* unsigned comparisons to a literal byte */
4152
4153           switch(lit & 0xff ) {
4154           case 0:
4155             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4156             genSkipz2(&rFalseIfx,0);
4157             break;
4158           case 0x7f:
4159             rFalseIfx.condition ^= 1;
4160             genSkipCond(&rFalseIfx,right,0,7);
4161             break;
4162
4163           default:
4164             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4165             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4166             DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4167             rFalseIfx.condition ^= 1;
4168             if (AOP_TYPE(result) == AOP_CRY)
4169               genSkipc(&rFalseIfx);
4170             else {
4171               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4172               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4173             }         
4174             break;
4175           }
4176         }
4177
4178         if(ifx) ifx->generated = 1;
4179         //goto check_carry;
4180         return;
4181
4182       } else {
4183
4184         /* Size is greater than 1 */
4185
4186         if(sign) {
4187           int lp1 = lit+1;
4188
4189           size--;
4190
4191           if(lp1 == 0) {
4192             /* this means lit = 0xffffffff, or -1 */
4193
4194
4195             DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4196             rFalseIfx.condition ^= 1;
4197             genSkipCond(&rFalseIfx,right,size,7);
4198             if(ifx) ifx->generated = 1;
4199             return;
4200           }
4201
4202           if(lit == 0) {
4203             int s = size;
4204
4205             if(rFalseIfx.condition) {
4206               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4207               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4208             }
4209
4210             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4211             while(size--)
4212               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4213
4214
4215             emitSKPZ;
4216             if(rFalseIfx.condition) {
4217               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4218               pic16_emitpLabel(truelbl->key);
4219             }else {
4220               rFalseIfx.condition ^= 1;
4221               genSkipCond(&rFalseIfx,right,s,7);
4222             }
4223
4224             if(ifx) ifx->generated = 1;
4225             return;
4226           }
4227
4228           if((size == 1) &&  (0 == (lp1&0xff))) {
4229             /* lower byte of signed word is zero */
4230             DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4231             i = ((lp1 >> 8) & 0xff) ^0x80;
4232             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4233             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4234             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4235             rFalseIfx.condition ^= 1;
4236             genSkipc(&rFalseIfx);
4237
4238
4239             if(ifx) ifx->generated = 1;
4240             return;
4241           }
4242
4243           if(lit & (0x80 << (size*8))) {
4244             /* Lit is less than zero */
4245             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4246             //rFalseIfx.condition ^= 1;
4247             //genSkipCond(&rFalseIfx,left,size,7);
4248             //rFalseIfx.condition ^= 1;
4249             pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4250             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4251
4252             if(rFalseIfx.condition)
4253               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4254             else
4255               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4256
4257
4258           } else {
4259             /* Lit is greater than or equal to zero */
4260             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4261             //rFalseIfx.condition ^= 1;
4262             //genSkipCond(&rFalseIfx,right,size,7);
4263             //rFalseIfx.condition ^= 1;
4264
4265             //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4266             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4267
4268             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4269             if(rFalseIfx.condition)
4270               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4271             else
4272               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4273
4274           }
4275
4276
4277           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4278           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4279
4280           while(size--) {
4281
4282             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4283             emitSKPNZ;
4284             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4285           }
4286           rFalseIfx.condition ^= 1;
4287           //rFalseIfx.condition = 1;
4288           genSkipc(&rFalseIfx);
4289
4290           pic16_emitpLabel(truelbl->key);
4291
4292           if(ifx) ifx->generated = 1;
4293           return;
4294           // end of if (sign)
4295         } else {
4296
4297           /* compare word or long to an unsigned literal on the right.*/
4298
4299
4300           size--;
4301           if(lit < 0xff) {
4302             DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4303             switch (lit) {
4304             case 0:
4305               break; /* handled above */
4306 /*
4307             case 0xff:
4308               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4309               while(size--)
4310                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4311               genSkipz2(&rFalseIfx,0);
4312               break;
4313 */
4314             default:
4315               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4316               while(--size)
4317                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4318
4319               emitSKPZ;
4320               if(rFalseIfx.condition)
4321                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4322               else
4323                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4324
4325
4326               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4327               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4328
4329               rFalseIfx.condition ^= 1;
4330               genSkipc(&rFalseIfx);
4331             }
4332
4333             pic16_emitpLabel(truelbl->key);
4334
4335             if(ifx) ifx->generated = 1;
4336             return;
4337           }
4338
4339
4340           lit++;
4341           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4342           i = (lit >> (size*8)) & 0xff;
4343
4344           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4345           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4346
4347           while(size--) {
4348             i = (lit >> (size*8)) & 0xff;
4349
4350             if(i) {
4351               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4352               emitSKPNZ;
4353               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4354             } else {
4355               /* this byte of the lit is zero, 
4356                *if it's not the last then OR in the variable */
4357               if(size)
4358                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4359             }
4360           }
4361
4362
4363           pic16_emitpLabel(lbl->key);
4364
4365           rFalseIfx.condition ^= 1;
4366           genSkipc(&rFalseIfx);
4367         }
4368
4369         if(sign)
4370           pic16_emitpLabel(truelbl->key);
4371         if(ifx) ifx->generated = 1;
4372         return;
4373       }
4374     }
4375     /* Compare two variables */
4376
4377     DEBUGpic16_emitcode(";sign","%d",sign);
4378
4379     size--;
4380     if(sign) {
4381       /* Sigh. thus sucks... */
4382       if(size) {
4383         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4384         pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4385         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4386         pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4387         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4388         pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4389       } else {
4390         /* Signed char comparison */
4391         /* Special thanks to Nikolai Golovchenko for this snippet */
4392         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4393         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4394         pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
4395         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4396         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4397         pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4398
4399         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4400         genSkipc(&rFalseIfx);
4401           
4402         if(ifx) ifx->generated = 1;
4403         return;
4404       }
4405
4406     } else {
4407
4408       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4409       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4410     }
4411
4412
4413     /* The rest of the bytes of a multi-byte compare */
4414     while (size) {
4415
4416       emitSKPZ;
4417       pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
4418       size--;
4419
4420       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4421       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4422
4423
4424     }
4425
4426     pic16_emitpLabel(lbl->key);
4427
4428     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4429     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4430         (AOP_TYPE(result) == AOP_REG)) {
4431       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4432       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4433     } else {
4434       genSkipc(&rFalseIfx);
4435     }         
4436     //genSkipc(&rFalseIfx);
4437     if(ifx) ifx->generated = 1;
4438
4439     return;
4440
4441   }
4442
4443   // check_carry:
4444   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4445     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4446     pic16_outBitC(result);
4447   } else {
4448     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4449     /* if the result is used in the next
4450        ifx conditional branch then generate
4451        code a little differently */
4452     if (ifx )
4453       genIfxJump (ifx,"c");
4454     else
4455       pic16_outBitC(result);
4456     /* leave the result in acc */
4457   }
4458
4459 }
4460
4461 /*-----------------------------------------------------------------*/
4462 /* genCmpGt :- greater than comparison                             */
4463 /*-----------------------------------------------------------------*/
4464 static void genCmpGt (iCode *ic, iCode *ifx)
4465 {
4466     operand *left, *right, *result;
4467     sym_link *letype , *retype;
4468     int sign ;
4469
4470     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4471     left = IC_LEFT(ic);
4472     right= IC_RIGHT(ic);
4473     result = IC_RESULT(ic);
4474
4475     letype = getSpec(operandType(left));
4476     retype =getSpec(operandType(right));
4477     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4478     /* assign the amsops */
4479     pic16_aopOp (left,ic,FALSE);
4480     pic16_aopOp (right,ic,FALSE);
4481     pic16_aopOp (result,ic,TRUE);
4482
4483     genCmp(right, left, result, ifx, sign);
4484
4485     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4486     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4487     pic16_freeAsmop(result,NULL,ic,TRUE); 
4488 }
4489
4490 /*-----------------------------------------------------------------*/
4491 /* genCmpLt - less than comparisons                                */
4492 /*-----------------------------------------------------------------*/
4493 static void genCmpLt (iCode *ic, iCode *ifx)
4494 {
4495     operand *left, *right, *result;
4496     sym_link *letype , *retype;
4497     int sign ;
4498
4499     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4500     left = IC_LEFT(ic);
4501     right= IC_RIGHT(ic);
4502     result = IC_RESULT(ic);
4503
4504     letype = getSpec(operandType(left));
4505     retype =getSpec(operandType(right));
4506     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4507
4508     /* assign the amsops */
4509     pic16_aopOp (left,ic,FALSE);
4510     pic16_aopOp (right,ic,FALSE);
4511     pic16_aopOp (result,ic,TRUE);
4512
4513     genCmp(left, right, result, ifx, sign);
4514
4515     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4516     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4517     pic16_freeAsmop(result,NULL,ic,TRUE); 
4518 }
4519
4520 /*-----------------------------------------------------------------*/
4521 /* genc16bit2lit - compare a 16 bit value to a literal             */
4522 /*-----------------------------------------------------------------*/
4523 static void genc16bit2lit(operand *op, int lit, int offset)
4524 {
4525   int i;
4526
4527   DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4528   if( (lit&0xff) == 0) 
4529     i=1;
4530   else
4531     i=0;
4532
4533   switch( BYTEofLONG(lit,i)) { 
4534   case 0:
4535     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4536     break;
4537   case 1:
4538     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4539     break;
4540   case 0xff:
4541     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4542     break;
4543   default:
4544     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4545     pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4546   }
4547
4548   i ^= 1;
4549
4550   switch( BYTEofLONG(lit,i)) { 
4551   case 0:
4552     pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4553     break;
4554   case 1:
4555     emitSKPNZ;
4556     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4557     break;
4558   case 0xff:
4559     emitSKPNZ;
4560     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4561     break;
4562   default:
4563     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4564     emitSKPNZ;
4565     pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4566
4567   }
4568
4569 }
4570
4571 /*-----------------------------------------------------------------*/
4572 /* gencjneshort - compare and jump if not equal                    */
4573 /*-----------------------------------------------------------------*/
4574 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4575 {
4576   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4577   int offset = 0;
4578   int res_offset = 0;  /* the result may be a different size then left or right */
4579   int res_size = AOP_SIZE(result);
4580   resolvedIfx rIfx;
4581   symbol *lbl;
4582
4583   unsigned long lit = 0L;
4584   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4585   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4586   if(result)
4587     DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4588   resolveIfx(&rIfx,ifx);
4589   lbl =  newiTempLabel(NULL);
4590
4591
4592   /* if the left side is a literal or 
4593      if the right is in a pointer register and left 
4594      is not */
4595   if ((AOP_TYPE(left) == AOP_LIT) || 
4596       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4597     operand *t = right;
4598     right = left;
4599     left = t;
4600   }
4601   if(AOP_TYPE(right) == AOP_LIT)
4602     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4603
4604   /* if the right side is a literal then anything goes */
4605   if (AOP_TYPE(right) == AOP_LIT &&
4606       AOP_TYPE(left) != AOP_DIR ) {
4607     switch(size) {
4608     case 2:
4609       genc16bit2lit(left, lit, 0);
4610       emitSKPNZ;
4611       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4612       break;
4613     default:
4614       while (size--) {
4615         if(lit & 0xff) {
4616           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4617           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4618         } else {
4619           pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4620         }
4621
4622         emitSKPNZ;
4623         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4624         offset++;
4625         if(res_offset < res_size-1)
4626           res_offset++;
4627         lit >>= 8;
4628       }
4629       break;
4630     }
4631   }
4632
4633   /* if the right side is in a register or in direct space or
4634      if the left is a pointer register & right is not */    
4635   else if (AOP_TYPE(right) == AOP_REG ||
4636            AOP_TYPE(right) == AOP_DIR || 
4637            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4638            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4639     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4640     int lbl_key = lbl->key;
4641
4642     if(result) {
4643       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4644       //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4645     }else {
4646       DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4647       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4648               __FUNCTION__,__LINE__);
4649       return;
4650     }
4651
4652 /*     switch(size) { */
4653 /*     case 2: */
4654 /*       genc16bit2lit(left, lit, 0); */
4655 /*       emitSKPNZ; */
4656 /*       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4657 /*       break; */
4658 /*     default: */
4659     while (size--) {
4660       int emit_skip=1;
4661       if((AOP_TYPE(left) == AOP_DIR) && 
4662          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4663
4664         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4665         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4666
4667       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4668             
4669         switch (lit & 0xff) {
4670         case 0:
4671           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4672           break;
4673         case 1:
4674           pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4675           pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4676           //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4677           emit_skip=0;
4678           break;
4679         case 0xff:
4680           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4681           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4682           //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4683           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4684           emit_skip=0;
4685           break;
4686         default:
4687           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4688           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4689         }
4690         lit >>= 8;
4691
4692       } else {
4693         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4694       }
4695       if(emit_skip) {
4696         if(AOP_TYPE(result) == AOP_CRY) {
4697           pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4698           if(rIfx.condition)
4699             emitSKPNZ;
4700           else
4701             emitSKPZ;
4702           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4703         } else {
4704           /* fix me. probably need to check result size too */
4705           //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4706           if(rIfx.condition)
4707             emitSKPZ;
4708           else
4709             emitSKPNZ;
4710           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4711           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4712         }
4713         if(ifx)
4714           ifx->generated=1;
4715       }
4716       emit_skip++;
4717       offset++;
4718       if(res_offset < res_size-1)
4719         res_offset++;
4720     }
4721 /*       break; */
4722 /*     } */
4723   } else if(AOP_TYPE(right) == AOP_REG &&
4724             AOP_TYPE(left) != AOP_DIR){
4725
4726     while(size--) {
4727       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4728       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4729       pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4730       if(rIfx.condition)
4731         emitSKPNZ;
4732       else
4733         emitSKPZ;
4734       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4735       offset++;
4736       if(res_offset < res_size-1)
4737         res_offset++;
4738     }
4739       
4740   }else{
4741     /* right is a pointer reg need both a & b */
4742     while(size--) {
4743       char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4744       if(strcmp(l,"b"))
4745         pic16_emitcode("mov","b,%s",l);
4746       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4747       pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4748       offset++;
4749     }
4750   }
4751
4752   pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4753   if(!rIfx.condition)
4754     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4755
4756   pic16_emitpLabel(lbl->key);
4757
4758   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4759
4760   if(ifx)
4761     ifx->generated = 1;
4762 }
4763
4764 #if 0
4765 /*-----------------------------------------------------------------*/
4766 /* gencjne - compare and jump if not equal                         */
4767 /*-----------------------------------------------------------------*/
4768 static void gencjne(operand *left, operand *right, iCode *ifx)
4769 {
4770     symbol *tlbl  = newiTempLabel(NULL);
4771
4772     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4773     gencjneshort(left, right, lbl);
4774
4775     pic16_emitcode("mov","a,%s",one);
4776     pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4777     pic16_emitcode("","%05d_DS_:",lbl->key+100);
4778     pic16_emitcode("clr","a");
4779     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4780
4781     pic16_emitpLabel(lbl->key);
4782     pic16_emitpLabel(tlbl->key);
4783
4784 }
4785 #endif
4786
4787 /*-----------------------------------------------------------------*/
4788 /* genCmpEq - generates code for equal to                          */
4789 /*-----------------------------------------------------------------*/
4790 static void genCmpEq (iCode *ic, iCode *ifx)
4791 {
4792     operand *left, *right, *result;
4793     unsigned long lit = 0L;
4794     int size,offset=0;
4795
4796     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4797
4798     if(ifx)
4799       DEBUGpic16_emitcode ("; ifx is non-null","");
4800     else
4801       DEBUGpic16_emitcode ("; ifx is null","");
4802
4803     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4804     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4805     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4806
4807     size = max(AOP_SIZE(left),AOP_SIZE(right));
4808
4809     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4810
4811     /* if literal, literal on the right or 
4812     if the right is in a pointer register and left 
4813     is not */
4814     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4815         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4816       operand *tmp = right ;
4817       right = left;
4818       left = tmp;
4819     }
4820
4821
4822     if(ifx && !AOP_SIZE(result)){
4823         symbol *tlbl;
4824         /* if they are both bit variables */
4825         if (AOP_TYPE(left) == AOP_CRY &&
4826             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4827             if(AOP_TYPE(right) == AOP_LIT){
4828                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4829                 if(lit == 0L){
4830                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4831                     pic16_emitcode("cpl","c");
4832                 } else if(lit == 1L) {
4833                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4834                 } else {
4835                     pic16_emitcode("clr","c");
4836                 }
4837                 /* AOP_TYPE(right) == AOP_CRY */
4838             } else {
4839                 symbol *lbl = newiTempLabel(NULL);
4840                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4841                 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4842                 pic16_emitcode("cpl","c");
4843                 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4844             }
4845             /* if true label then we jump if condition
4846             supplied is true */
4847             tlbl = newiTempLabel(NULL);
4848             if ( IC_TRUE(ifx) ) {
4849                 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4850                 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4851             } else {
4852                 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4853                 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4854             }
4855             pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4856
4857             {
4858               /* left and right are both bit variables, result is carry */
4859               resolvedIfx rIfx;
4860               
4861               resolveIfx(&rIfx,ifx);
4862
4863               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4864               pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4865               pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4866               pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4867               genSkipz2(&rIfx,0);
4868             }
4869         } else {
4870
4871           /* They're not both bit variables. Is the right a literal? */
4872           if(AOP_TYPE(right) == AOP_LIT) {
4873             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4874             
4875             switch(size) {
4876
4877             case 1:
4878               switch(lit & 0xff) {
4879               case 1:
4880                 if ( IC_TRUE(ifx) ) {
4881                   pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4882                   emitSKPNZ;
4883                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4884                 } else {
4885                   pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4886                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4887                 }
4888                 break;
4889               case 0xff:
4890                 if ( IC_TRUE(ifx) ) {
4891                   pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4892                   emitSKPNZ;
4893                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4894                 } else {
4895                   pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4896                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4897                 }
4898                 break;
4899               default:
4900                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4901                 if(lit)
4902                   pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4903                 genSkip(ifx,'z');
4904               }
4905
4906
4907               /* end of size == 1 */
4908               break;
4909               
4910             case 2:
4911               genc16bit2lit(left,lit,offset);
4912               genSkip(ifx,'z');
4913               break;
4914               /* end of size == 2 */
4915
4916             default:
4917               /* size is 4 */
4918               if(lit==0) {
4919                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4920                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4921                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4922                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4923
4924               } else {
4925
4926                 /* search for patterns that can be optimized */
4927
4928                 genc16bit2lit(left,lit,0);
4929                 lit >>= 16;
4930                 if(lit) {
4931                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4932                   //genSkip(ifx,'z');
4933                   genc16bit2lit(left,lit,2);
4934                 } else {
4935                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4936                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4937
4938                 }
4939                 
4940               }
4941
4942               genSkip(ifx,'z');
4943             }
4944           
4945             ifx->generated = 1;
4946             goto release ;
4947             
4948
4949           } else if(AOP_TYPE(right) == AOP_CRY ) {
4950             /* we know the left is not a bit, but that the right is */
4951             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4952             pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4953                       pic16_popGet(AOP(right),offset));
4954             pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4955
4956             /* if the two are equal, then W will be 0 and the Z bit is set
4957              * we could test Z now, or go ahead and check the high order bytes if
4958              * the variable we're comparing is larger than a byte. */
4959
4960             while(--size)
4961               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4962
4963             if ( IC_TRUE(ifx) ) {
4964               emitSKPNZ;
4965               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4966               pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4967             } else {
4968               emitSKPZ;
4969               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4970               pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4971             }
4972
4973           } else {
4974             /* They're both variables that are larger than bits */
4975             int s = size;
4976
4977             tlbl = newiTempLabel(NULL);
4978
4979             while(size--) {
4980               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4981               pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4982
4983               if ( IC_TRUE(ifx) ) {
4984                 if(size) {
4985                   emitSKPZ;
4986                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4987                   pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4988                 } else {
4989                   emitSKPNZ;
4990                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4991                   pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4992                 }
4993               } else {
4994                 emitSKPZ;
4995                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4996                 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4997               }
4998               offset++;
4999             }
5000             if(s>1 && IC_TRUE(ifx)) {
5001               pic16_emitpLabel(tlbl->key);
5002               pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
5003             }
5004           }
5005         }
5006         /* mark the icode as generated */
5007         ifx->generated = 1;
5008         goto release ;
5009     }
5010
5011     /* if they are both bit variables */
5012     if (AOP_TYPE(left) == AOP_CRY &&
5013         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5014         if(AOP_TYPE(right) == AOP_LIT){
5015             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5016             if(lit == 0L){
5017                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5018                 pic16_emitcode("cpl","c");
5019             } else if(lit == 1L) {
5020                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5021             } else {
5022                 pic16_emitcode("clr","c");
5023             }
5024             /* AOP_TYPE(right) == AOP_CRY */
5025         } else {
5026             symbol *lbl = newiTempLabel(NULL);
5027             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5028             pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5029             pic16_emitcode("cpl","c");
5030             pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5031         }
5032         /* c = 1 if egal */
5033         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5034             pic16_outBitC(result);
5035             goto release ;
5036         }
5037         if (ifx) {
5038             genIfxJump (ifx,"c");
5039             goto release ;
5040         }
5041         /* if the result is used in an arithmetic operation
5042         then put the result in place */
5043         pic16_outBitC(result);
5044     } else {
5045       
5046       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5047       gencjne(left,right,result,ifx);
5048 /*
5049       if(ifx) 
5050         gencjne(left,right,newiTempLabel(NULL));
5051       else {
5052         if(IC_TRUE(ifx)->key)
5053           gencjne(left,right,IC_TRUE(ifx)->key);
5054         else
5055           gencjne(left,right,IC_FALSE(ifx)->key);
5056         ifx->generated = 1;
5057         goto release ;
5058       }
5059       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5060         pic16_aopPut(AOP(result),"a",0);
5061         goto release ;
5062       }
5063
5064       if (ifx) {
5065         genIfxJump (ifx,"a");
5066         goto release ;
5067       }
5068 */
5069       /* if the result is used in an arithmetic operation
5070          then put the result in place */
5071 /*
5072       if (AOP_TYPE(result) != AOP_CRY) 
5073         pic16_outAcc(result);
5074 */
5075       /* leave the result in acc */
5076     }
5077
5078 release:
5079     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081     pic16_freeAsmop(result,NULL,ic,TRUE);
5082 }
5083
5084 /*-----------------------------------------------------------------*/
5085 /* ifxForOp - returns the icode containing the ifx for operand     */
5086 /*-----------------------------------------------------------------*/
5087 static iCode *ifxForOp ( operand *op, iCode *ic )
5088 {
5089     /* if true symbol then needs to be assigned */
5090     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5091     if (IS_TRUE_SYMOP(op))
5092         return NULL ;
5093
5094     /* if this has register type condition and
5095     the next instruction is ifx with the same operand
5096     and live to of the operand is upto the ifx only then */
5097     if (ic->next &&
5098         ic->next->op == IFX &&
5099         IC_COND(ic->next)->key == op->key &&
5100         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5101         return ic->next;
5102
5103     if (ic->next &&
5104         ic->next->op == IFX &&
5105         IC_COND(ic->next)->key == op->key) {
5106       DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5107       return ic->next;
5108     }
5109
5110     DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5111     if (ic->next &&
5112         ic->next->op == IFX)
5113       DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5114
5115     if (ic->next &&
5116         ic->next->op == IFX &&
5117         IC_COND(ic->next)->key == op->key) {
5118       DEBUGpic16_emitcode ("; "," key is okay");
5119       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5120                            OP_SYMBOL(op)->liveTo,
5121                            ic->next->seq);
5122     }
5123
5124
5125     return NULL;
5126 }
5127 /*-----------------------------------------------------------------*/
5128 /* genAndOp - for && operation                                     */
5129 /*-----------------------------------------------------------------*/
5130 static void genAndOp (iCode *ic)
5131 {
5132     operand *left,*right, *result;
5133 /*     symbol *tlbl; */
5134
5135     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5136     /* note here that && operations that are in an
5137     if statement are taken away by backPatchLabels
5138     only those used in arthmetic operations remain */
5139     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5140     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5141     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5142
5143     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5144
5145     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5146     pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5147     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5148
5149     /* if both are bit variables */
5150 /*     if (AOP_TYPE(left) == AOP_CRY && */
5151 /*         AOP_TYPE(right) == AOP_CRY ) { */
5152 /*         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5153 /*         pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5154 /*         pic16_outBitC(result); */
5155 /*     } else { */
5156 /*         tlbl = newiTempLabel(NULL); */
5157 /*         pic16_toBoolean(left);     */
5158 /*         pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5159 /*         pic16_toBoolean(right); */
5160 /*         pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5161 /*         pic16_outBitAcc(result); */
5162 /*     } */
5163
5164     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5165     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5166     pic16_freeAsmop(result,NULL,ic,TRUE);
5167 }
5168
5169
5170 /*-----------------------------------------------------------------*/
5171 /* genOrOp - for || operation                                      */
5172 /*-----------------------------------------------------------------*/
5173 /*
5174   tsd pic port -
5175   modified this code, but it doesn't appear to ever get called
5176 */
5177
5178 static void genOrOp (iCode *ic)
5179 {
5180     operand *left,*right, *result;
5181     symbol *tlbl;
5182
5183     /* note here that || operations that are in an
5184     if statement are taken away by backPatchLabels
5185     only those used in arthmetic operations remain */
5186     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5187     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5188     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5189     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5190
5191     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5192
5193     /* if both are bit variables */
5194     if (AOP_TYPE(left) == AOP_CRY &&
5195         AOP_TYPE(right) == AOP_CRY ) {
5196       pic16_emitcode("clrc","");
5197       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5198                AOP(left)->aopu.aop_dir,
5199                AOP(left)->aopu.aop_dir);
5200       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5201                AOP(right)->aopu.aop_dir,
5202                AOP(right)->aopu.aop_dir);
5203       pic16_emitcode("setc","");
5204
5205     } else {
5206         tlbl = newiTempLabel(NULL);
5207         pic16_toBoolean(left);
5208         emitSKPZ;
5209         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5210         pic16_toBoolean(right);
5211         pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5212
5213         pic16_outBitAcc(result);
5214     }
5215
5216     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5217     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5218     pic16_freeAsmop(result,NULL,ic,TRUE);            
5219 }
5220
5221 /*-----------------------------------------------------------------*/
5222 /* isLiteralBit - test if lit == 2^n                               */
5223 /*-----------------------------------------------------------------*/
5224 static int isLiteralBit(unsigned long lit)
5225 {
5226     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5227     0x100L,0x200L,0x400L,0x800L,
5228     0x1000L,0x2000L,0x4000L,0x8000L,
5229     0x10000L,0x20000L,0x40000L,0x80000L,
5230     0x100000L,0x200000L,0x400000L,0x800000L,
5231     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5232     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5233     int idx;
5234     
5235     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5236     for(idx = 0; idx < 32; idx++)
5237         if(lit == pw[idx])
5238             return idx+1;
5239     return 0;
5240 }
5241
5242 /*-----------------------------------------------------------------*/
5243 /* continueIfTrue -                                                */
5244 /*-----------------------------------------------------------------*/
5245 static void continueIfTrue (iCode *ic)
5246 {
5247     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5248     if(IC_TRUE(ic))
5249         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5250     ic->generated = 1;
5251 }
5252
5253 /*-----------------------------------------------------------------*/
5254 /* jmpIfTrue -                                                     */
5255 /*-----------------------------------------------------------------*/
5256 static void jumpIfTrue (iCode *ic)
5257 {
5258     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5259     if(!IC_TRUE(ic))
5260         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5261     ic->generated = 1;
5262 }
5263
5264 /*-----------------------------------------------------------------*/
5265 /* jmpTrueOrFalse -                                                */
5266 /*-----------------------------------------------------------------*/
5267 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5268 {
5269     // ugly but optimized by peephole
5270     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5271     if(IC_TRUE(ic)){
5272         symbol *nlbl = newiTempLabel(NULL);
5273         pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5274         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5275         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5276         pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5277     }
5278     else{
5279         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5280         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5281     }
5282     ic->generated = 1;
5283 }
5284
5285 /*-----------------------------------------------------------------*/
5286 /* genAnd  - code for and                                          */
5287 /*-----------------------------------------------------------------*/
5288 static void genAnd (iCode *ic, iCode *ifx)
5289 {
5290   operand *left, *right, *result;
5291   int size, offset=0;  
5292   unsigned long lit = 0L;
5293   int bytelit = 0;
5294   resolvedIfx rIfx;
5295
5296
5297   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5298   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5299   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5300   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5301
5302   resolveIfx(&rIfx,ifx);
5303
5304   /* if left is a literal & right is not then exchange them */
5305   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5306       AOP_NEEDSACC(left)) {
5307     operand *tmp = right ;
5308     right = left;
5309     left = tmp;
5310   }
5311
5312   /* if result = right then exchange them */
5313   if(pic16_sameRegs(AOP(result),AOP(right))){
5314     operand *tmp = right ;
5315     right = left;
5316     left = tmp;
5317   }
5318
5319   /* if right is bit then exchange them */
5320   if (AOP_TYPE(right) == AOP_CRY &&
5321       AOP_TYPE(left) != AOP_CRY){
5322     operand *tmp = right ;
5323     right = left;
5324     left = tmp;
5325   }
5326   if(AOP_TYPE(right) == AOP_LIT)
5327     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5328
5329   size = AOP_SIZE(result);
5330
5331   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5332
5333   // if(bit & yy)
5334   // result = bit & yy;
5335   if (AOP_TYPE(left) == AOP_CRY){
5336     // c = bit & literal;
5337     if(AOP_TYPE(right) == AOP_LIT){
5338       if(lit & 1) {
5339         if(size && pic16_sameRegs(AOP(result),AOP(left)))
5340           // no change
5341           goto release;
5342         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5343       } else {
5344         // bit(result) = 0;
5345         if(size && (AOP_TYPE(result) == AOP_CRY)){
5346           pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5347           goto release;
5348         }
5349         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5350           jumpIfTrue(ifx);
5351           goto release;
5352         }
5353         pic16_emitcode("clr","c");
5354       }
5355     } else {
5356       if (AOP_TYPE(right) == AOP_CRY){
5357         // c = bit & bit;
5358         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5359         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5360       } else {
5361         // c = bit & val;
5362         MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5363         // c = lsb
5364         pic16_emitcode("rrc","a");
5365         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5366       }
5367     }
5368     // bit = c
5369     // val = c
5370     if(size)
5371       pic16_outBitC(result);
5372     // if(bit & ...)
5373     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5374       genIfxJump(ifx, "c");           
5375     goto release ;
5376   }
5377
5378   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5379   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5380   if((AOP_TYPE(right) == AOP_LIT) &&
5381      (AOP_TYPE(result) == AOP_CRY) &&
5382      (AOP_TYPE(left) != AOP_CRY)){
5383     int posbit = isLiteralBit(lit);
5384     /* left &  2^n */
5385     if(posbit){
5386       posbit--;
5387       //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5388       // bit = left & 2^n
5389       if(size)
5390         pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5391       // if(left &  2^n)
5392       else{
5393         if(ifx){
5394 /*
5395           if(IC_TRUE(ifx)) {
5396             pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5397             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5398           } else {
5399             pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5400             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5401           }
5402 */
5403           pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5404                     pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5405           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5406           
5407           ifx->generated = 1;
5408         }
5409         goto release;
5410       }
5411     } else {
5412       symbol *tlbl = newiTempLabel(NULL);
5413       int sizel = AOP_SIZE(left);
5414       if(size)
5415         pic16_emitcode("setb","c");
5416       while(sizel--){
5417         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5418           MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5419           // byte ==  2^n ?
5420           if((posbit = isLiteralBit(bytelit)) != 0)
5421             pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5422           else{
5423             if(bytelit != 0x0FFL)
5424               pic16_emitcode("anl","a,%s",
5425                              pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5426             pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5427           }
5428         }
5429         offset++;
5430       }
5431       // bit = left & literal
5432       if(size){
5433         pic16_emitcode("clr","c");
5434         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5435       }
5436       // if(left & literal)
5437       else{
5438         if(ifx)
5439           jmpTrueOrFalse(ifx, tlbl);
5440         goto release ;
5441       }
5442     }
5443     pic16_outBitC(result);
5444     goto release ;
5445   }
5446
5447   /* if left is same as result */
5448   if(pic16_sameRegs(AOP(result),AOP(left))){
5449     int know_W = -1;
5450     for(;size--; offset++,lit>>=8) {
5451       if(AOP_TYPE(right) == AOP_LIT){
5452         switch(lit & 0xff) {
5453         case 0x00:
5454           /*  and'ing with 0 has clears the result */
5455 //        pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5456           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5457           break;
5458         case 0xff:
5459           /* and'ing with 0xff is a nop when the result and left are the same */
5460           break;
5461
5462         default:
5463           {
5464             int p = my_powof2( (~lit) & 0xff );
5465             if(p>=0) {
5466               /* only one bit is set in the literal, so use a bcf instruction */
5467 //            pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5468               pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5469
5470             } else {
5471               pic16_emitcode("movlw","0x%x", (lit & 0xff));
5472               pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5473               if(know_W != (lit&0xff))
5474                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5475               know_W = lit &0xff;
5476               pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5477             }
5478           }    
5479         }
5480       } else {
5481         if (AOP_TYPE(left) == AOP_ACC) {
5482           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5483         } else {                    
5484           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5485           pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5486
5487         }
5488       }
5489     }
5490
5491   } else {
5492     // left & result in different registers
5493     if(AOP_TYPE(result) == AOP_CRY){
5494       // result = bit
5495       // if(size), result in bit
5496       // if(!size && ifx), conditional oper: if(left & right)
5497       symbol *tlbl = newiTempLabel(NULL);
5498       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5499       if(size)
5500         pic16_emitcode("setb","c");
5501       while(sizer--){
5502         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5503         pic16_emitcode("anl","a,%s",
5504                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5505         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5506         offset++;
5507       }
5508       if(size){
5509         CLRC;
5510         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5511         pic16_outBitC(result);
5512       } else if(ifx)
5513         jmpTrueOrFalse(ifx, tlbl);
5514     } else {
5515       for(;(size--);offset++) {
5516         // normal case
5517         // result = left & right
5518         if(AOP_TYPE(right) == AOP_LIT){
5519           int t = (lit >> (offset*8)) & 0x0FFL;
5520           switch(t) { 
5521           case 0x00:
5522             pic16_emitcode("clrf","%s",
5523                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5524             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5525             break;
5526           case 0xff:
5527             pic16_emitcode("movf","%s,w",
5528                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5529             pic16_emitcode("movwf","%s",
5530                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5531             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5532             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5533             break;
5534           default:
5535             pic16_emitcode("movlw","0x%x",t);
5536             pic16_emitcode("andwf","%s,w",
5537                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5538             pic16_emitcode("movwf","%s",
5539                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5540               
5541             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5542             pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5543             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5544           }
5545           continue;
5546         }
5547
5548         if (AOP_TYPE(left) == AOP_ACC) {
5549           pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5550           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5551         } else {
5552           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5553           pic16_emitcode("andwf","%s,w",
5554                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5555           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5556           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5557         }
5558         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5559         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5560       }
5561     }
5562   }
5563
5564   release :
5565     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5566   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5567   pic16_freeAsmop(result,NULL,ic,TRUE);     
5568 }
5569
5570 /*-----------------------------------------------------------------*/
5571 /* genOr  - code for or                                            */
5572 /*-----------------------------------------------------------------*/
5573 static void genOr (iCode *ic, iCode *ifx)
5574 {
5575     operand *left, *right, *result;
5576     int size, offset=0;
5577     unsigned long lit = 0L;
5578
5579     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5580
5581     pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5582     pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5583     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5584
5585     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5586
5587     /* if left is a literal & right is not then exchange them */
5588     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5589         AOP_NEEDSACC(left)) {
5590         operand *tmp = right ;
5591         right = left;
5592         left = tmp;
5593     }
5594
5595     /* if result = right then exchange them */
5596     if(pic16_sameRegs(AOP(result),AOP(right))){
5597         operand *tmp = right ;
5598         right = left;
5599         left = tmp;
5600     }
5601
5602     /* if right is bit then exchange them */
5603     if (AOP_TYPE(right) == AOP_CRY &&
5604         AOP_TYPE(left) != AOP_CRY){
5605         operand *tmp = right ;
5606         right = left;
5607         left = tmp;
5608     }
5609
5610     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5611
5612     if(AOP_TYPE(right) == AOP_LIT)
5613         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5614
5615     size = AOP_SIZE(result);
5616
5617     // if(bit | yy)
5618     // xx = bit | yy;
5619     if (AOP_TYPE(left) == AOP_CRY){
5620         if(AOP_TYPE(right) == AOP_LIT){
5621             // c = bit & literal;
5622             if(lit){
5623                 // lit != 0 => result = 1
5624                 if(AOP_TYPE(result) == AOP_CRY){
5625                   if(size)
5626                     pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5627                   //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5628                   //     AOP(result)->aopu.aop_dir,
5629                   //     AOP(result)->aopu.aop_dir);
5630                     else if(ifx)
5631                         continueIfTrue(ifx);
5632                     goto release;
5633                 }
5634             } else {
5635                 // lit == 0 => result = left
5636                 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5637                     goto release;
5638                 pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5639             }
5640         } else {
5641             if (AOP_TYPE(right) == AOP_CRY){
5642               if(pic16_sameRegs(AOP(result),AOP(left))){
5643                 // c = bit | bit;
5644                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5645                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5646                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5647
5648                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5649                          AOP(result)->aopu.aop_dir,
5650                          AOP(result)->aopu.aop_dir);
5651                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5652                          AOP(right)->aopu.aop_dir,
5653                          AOP(right)->aopu.aop_dir);
5654                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5655                          AOP(result)->aopu.aop_dir,
5656                          AOP(result)->aopu.aop_dir);
5657               } else {
5658                 if( AOP_TYPE(result) == AOP_ACC) {
5659                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5660                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5661                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5662                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5663
5664                 } else {
5665
5666                   pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5667                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5668                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5669                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5670
5671                   pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5672                                  AOP(result)->aopu.aop_dir,
5673                                  AOP(result)->aopu.aop_dir);
5674                   pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5675                                  AOP(right)->aopu.aop_dir,
5676                                  AOP(right)->aopu.aop_dir);
5677                   pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5678                                  AOP(left)->aopu.aop_dir,
5679                                  AOP(left)->aopu.aop_dir);
5680                   pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5681                                  AOP(result)->aopu.aop_dir,
5682                                  AOP(result)->aopu.aop_dir);
5683                 }
5684               }
5685             } else {
5686                 // c = bit | val;
5687                 symbol *tlbl = newiTempLabel(NULL);
5688                 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689
5690
5691                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5692                 if( AOP_TYPE(right) == AOP_ACC) {
5693                   pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5694                   emitSKPNZ;
5695                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5696                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5697                 }
5698
5699
5700
5701                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5702                     pic16_emitcode(";XXX setb","c");
5703                 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5704                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5705                 pic16_toBoolean(right);
5706                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5707                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5708                     jmpTrueOrFalse(ifx, tlbl);
5709                     goto release;
5710                 } else {
5711                     CLRC;
5712                     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5713                 }
5714             }
5715         }
5716         // bit = c
5717         // val = c
5718         if(size)
5719             pic16_outBitC(result);
5720         // if(bit | ...)
5721         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5722             genIfxJump(ifx, "c");           
5723         goto release ;
5724     }
5725
5726     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5727     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5728     if((AOP_TYPE(right) == AOP_LIT) &&
5729        (AOP_TYPE(result) == AOP_CRY) &&
5730        (AOP_TYPE(left) != AOP_CRY)){
5731         if(lit){
5732           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5733             // result = 1
5734             if(size)
5735                 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5736             else 
5737                 continueIfTrue(ifx);
5738             goto release;
5739         } else {
5740           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5741             // lit = 0, result = boolean(left)
5742             if(size)
5743                 pic16_emitcode(";XXX setb","c");
5744             pic16_toBoolean(right);
5745             if(size){
5746                 symbol *tlbl = newiTempLabel(NULL);
5747                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5748                 CLRC;
5749                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5750             } else {
5751                 genIfxJump (ifx,"a");
5752                 goto release;
5753             }
5754         }
5755         pic16_outBitC(result);
5756         goto release ;
5757     }
5758
5759     /* if left is same as result */
5760     if(pic16_sameRegs(AOP(result),AOP(left))){
5761       int know_W = -1;
5762       for(;size--; offset++,lit>>=8) {
5763         if(AOP_TYPE(right) == AOP_LIT){
5764           if((lit & 0xff) == 0)
5765             /*  or'ing with 0 has no effect */
5766             continue;
5767           else {
5768             int p = my_powof2(lit & 0xff);
5769             if(p>=0) {
5770               /* only one bit is set in the literal, so use a bsf instruction */
5771               pic16_emitpcode(POC_BSF,
5772                         pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5773             } else {
5774               if(know_W != (lit & 0xff))
5775                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5776               know_W = lit & 0xff;
5777               pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5778             }
5779                     
5780           }
5781         } else {
5782           if (AOP_TYPE(left) == AOP_ACC) {
5783             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
5784             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5785           } else {                  
5786             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5787             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
5788
5789             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5790             pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5791
5792           }
5793         }
5794       }
5795     } else {
5796         // left & result in different registers
5797         if(AOP_TYPE(result) == AOP_CRY){
5798             // result = bit
5799             // if(size), result in bit
5800             // if(!size && ifx), conditional oper: if(left | right)
5801             symbol *tlbl = newiTempLabel(NULL);
5802             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5803             pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5804
5805
5806             if(size)
5807                 pic16_emitcode(";XXX setb","c");
5808             while(sizer--){
5809                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5810                 pic16_emitcode(";XXX orl","a,%s",
5811                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5812                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5813                 offset++;
5814             }
5815             if(size){
5816                 CLRC;
5817                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5818                 pic16_outBitC(result);
5819             } else if(ifx)
5820                 jmpTrueOrFalse(ifx, tlbl);
5821         } else for(;(size--);offset++){
5822           // normal case
5823           // result = left & right
5824           if(AOP_TYPE(right) == AOP_LIT){
5825             int t = (lit >> (offset*8)) & 0x0FFL;
5826             switch(t) { 
5827             case 0x00:
5828               pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
5829               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5830
5831               pic16_emitcode("movf","%s,w",
5832                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5833               pic16_emitcode("movwf","%s",
5834                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5835               break;
5836             default:
5837               pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
5838               pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5839               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5840
5841               pic16_emitcode("movlw","0x%x",t);
5842               pic16_emitcode("iorwf","%s,w",
5843                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5844               pic16_emitcode("movwf","%s",
5845                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5846               
5847             }
5848             continue;
5849           }
5850
5851           // faster than result <- left, anl result,right
5852           // and better if result is SFR
5853           if (AOP_TYPE(left) == AOP_ACC) {
5854             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
5855             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5856           } else {
5857             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5858             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5859
5860             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5861             pic16_emitcode("iorwf","%s,w",
5862                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5863           }
5864           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5865           pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5866         }
5867     }
5868
5869 release :
5870     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5871     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5872     pic16_freeAsmop(result,NULL,ic,TRUE);     
5873 }
5874
5875 /*-----------------------------------------------------------------*/
5876 /* genXor - code for xclusive or                                   */
5877 /*-----------------------------------------------------------------*/
5878 static void genXor (iCode *ic, iCode *ifx)
5879 {
5880   operand *left, *right, *result;
5881   int size, offset=0;
5882   unsigned long lit = 0L;
5883
5884   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5885
5886   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5887   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5888   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5889
5890   /* if left is a literal & right is not ||
5891      if left needs acc & right does not */
5892   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5893       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5894     operand *tmp = right ;
5895     right = left;
5896     left = tmp;
5897   }
5898
5899   /* if result = right then exchange them */
5900   if(pic16_sameRegs(AOP(result),AOP(right))){
5901     operand *tmp = right ;
5902     right = left;
5903     left = tmp;
5904   }
5905
5906   /* if right is bit then exchange them */
5907   if (AOP_TYPE(right) == AOP_CRY &&
5908       AOP_TYPE(left) != AOP_CRY){
5909     operand *tmp = right ;
5910     right = left;
5911     left = tmp;
5912   }
5913   if(AOP_TYPE(right) == AOP_LIT)
5914     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5915
5916   size = AOP_SIZE(result);
5917
5918   // if(bit ^ yy)
5919   // xx = bit ^ yy;
5920   if (AOP_TYPE(left) == AOP_CRY){
5921     if(AOP_TYPE(right) == AOP_LIT){
5922       // c = bit & literal;
5923       if(lit>>1){
5924         // lit>>1  != 0 => result = 1
5925         if(AOP_TYPE(result) == AOP_CRY){
5926           if(size)
5927             {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
5928             pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5929           else if(ifx)
5930             continueIfTrue(ifx);
5931           goto release;
5932         }
5933         pic16_emitcode("setb","c");
5934       } else{
5935         // lit == (0 or 1)
5936         if(lit == 0){
5937           // lit == 0, result = left
5938           if(size && pic16_sameRegs(AOP(result),AOP(left)))
5939             goto release;
5940           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5941         } else{
5942           // lit == 1, result = not(left)
5943           if(size && pic16_sameRegs(AOP(result),AOP(left))){
5944             pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
5945             pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
5946             pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5947             goto release;
5948           } else {
5949             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5950             pic16_emitcode("cpl","c");
5951           }
5952         }
5953       }
5954
5955     } else {
5956       // right != literal
5957       symbol *tlbl = newiTempLabel(NULL);
5958       if (AOP_TYPE(right) == AOP_CRY){
5959         // c = bit ^ bit;
5960         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5961       }
5962       else{
5963         int sizer = AOP_SIZE(right);
5964         // c = bit ^ val
5965         // if val>>1 != 0, result = 1
5966         pic16_emitcode("setb","c");
5967         while(sizer){
5968           MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5969           if(sizer == 1)
5970             // test the msb of the lsb
5971             pic16_emitcode("anl","a,#0xfe");
5972           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5973           sizer--;
5974         }
5975         // val = (0,1)
5976         pic16_emitcode("rrc","a");
5977       }
5978       pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5979       pic16_emitcode("cpl","c");
5980       pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5981     }
5982     // bit = c
5983     // val = c
5984     if(size)
5985       pic16_outBitC(result);
5986     // if(bit | ...)
5987     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5988       genIfxJump(ifx, "c");           
5989     goto release ;
5990   }
5991
5992   if(pic16_sameRegs(AOP(result),AOP(left))){
5993     /* if left is same as result */
5994     for(;size--; offset++) {
5995       if(AOP_TYPE(right) == AOP_LIT){
5996         int t  = (lit >> (offset*8)) & 0x0FFL;
5997         if(t == 0x00L)
5998           continue;
5999         else
6000           if (IS_AOP_PREG(left)) {
6001             MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6002             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6003             pic16_aopPut(AOP(result),"a",offset);
6004           } else {
6005             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6006             pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6007             pic16_emitcode("xrl","%s,%s",
6008                            pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6009                            pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6010           }
6011       } else {
6012         if (AOP_TYPE(left) == AOP_ACC)
6013           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6014         else {
6015           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6016           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6017 /*
6018           if (IS_AOP_PREG(left)) {
6019             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6020             pic16_aopPut(AOP(result),"a",offset);
6021           } else
6022             pic16_emitcode("xrl","%s,a",
6023                            pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6024 */
6025         }
6026       }
6027     }
6028   } else {
6029     // left & result in different registers
6030     if(AOP_TYPE(result) == AOP_CRY){
6031       // result = bit
6032       // if(size), result in bit
6033       // if(!size && ifx), conditional oper: if(left ^ right)
6034       symbol *tlbl = newiTempLabel(NULL);
6035       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6036       if(size)
6037         pic16_emitcode("setb","c");
6038       while(sizer--){
6039         if((AOP_TYPE(right) == AOP_LIT) &&
6040            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6041           MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6042         } else {
6043           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6044           pic16_emitcode("xrl","a,%s",
6045                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6046         }
6047         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6048         offset++;
6049       }
6050       if(size){
6051         CLRC;
6052         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6053         pic16_outBitC(result);
6054       } else if(ifx)
6055         jmpTrueOrFalse(ifx, tlbl);
6056     } else for(;(size--);offset++){
6057       // normal case
6058       // result = left & right
6059       if(AOP_TYPE(right) == AOP_LIT){
6060         int t = (lit >> (offset*8)) & 0x0FFL;
6061         switch(t) { 
6062         case 0x00:
6063           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6064           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6065           pic16_emitcode("movf","%s,w",
6066                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6067           pic16_emitcode("movwf","%s",
6068                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6069           break;
6070         case 0xff:
6071           pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6072           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6073           pic16_emitcode("comf","%s,w",
6074                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6075           pic16_emitcode("movwf","%s",
6076                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6077           break;
6078         default:
6079           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6080           pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6081           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6082           pic16_emitcode("movlw","0x%x",t);
6083           pic16_emitcode("xorwf","%s,w",
6084                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6085           pic16_emitcode("movwf","%s",
6086                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6087
6088         }
6089         continue;
6090       }
6091
6092       // faster than result <- left, anl result,right
6093       // and better if result is SFR
6094       if (AOP_TYPE(left) == AOP_ACC) {
6095         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6096         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6097       } else {
6098         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6099         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6100         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6101         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6102       }
6103       if ( AOP_TYPE(result) != AOP_ACC){
6104         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6105         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6106       }
6107     }
6108   }
6109
6110   release :
6111     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6112   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6113   pic16_freeAsmop(result,NULL,ic,TRUE);     
6114 }
6115
6116 /*-----------------------------------------------------------------*/
6117 /* genInline - write the inline code out                           */
6118 /*-----------------------------------------------------------------*/
6119 static void genInline (iCode *ic)
6120 {
6121     char *buffer, *bp, *bp1;
6122     
6123     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6124
6125     _G.inLine += (!options.asmpeep);
6126
6127     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6128     strcpy(buffer,IC_INLINE(ic));
6129
6130     /* emit each line as a code */
6131     while (*bp) {
6132         if (*bp == '\n') {
6133             *bp++ = '\0';
6134
6135             if(*bp1)
6136               pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6137             bp1 = bp;
6138         } else {
6139             if (*bp == ':') {
6140                 bp++;
6141                 *bp = '\0';
6142                 bp++;
6143                 pic16_emitcode(bp1,"");
6144                 bp1 = bp;
6145             } else
6146                 bp++;
6147         }
6148     }
6149     if ((bp1 != bp) && *bp1)
6150       pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6151
6152     Safe_free(buffer);
6153
6154     _G.inLine -= (!options.asmpeep);
6155 }
6156
6157 /*-----------------------------------------------------------------*/
6158 /* genRRC - rotate right with carry                                */
6159 /*-----------------------------------------------------------------*/
6160 static void genRRC (iCode *ic)
6161 {
6162   operand *left , *result ;
6163   int size, offset = 0, same;
6164
6165   /* rotate right with carry */
6166   left = IC_LEFT(ic);
6167   result=IC_RESULT(ic);
6168   pic16_aopOp (left,ic,FALSE);
6169   pic16_aopOp (result,ic,FALSE);
6170
6171   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6172
6173   same = pic16_sameRegs(AOP(result),AOP(left));
6174
6175   size = AOP_SIZE(result);    
6176
6177   /* get the lsb and put it into the carry */
6178   pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6179
6180   offset = 0 ;
6181
6182   while(size--) {
6183
6184     if(same) {
6185       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6186     } else {
6187       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6188       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6189     }
6190
6191     offset++;
6192   }
6193
6194   pic16_freeAsmop(left,NULL,ic,TRUE);
6195   pic16_freeAsmop(result,NULL,ic,TRUE);
6196 }
6197
6198 /*-----------------------------------------------------------------*/
6199 /* genRLC - generate code for rotate left with carry               */
6200 /*-----------------------------------------------------------------*/
6201 static void genRLC (iCode *ic)
6202 {    
6203   operand *left , *result ;
6204   int size, offset = 0;
6205   int same;
6206
6207   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6208   /* rotate right with carry */
6209   left = IC_LEFT(ic);
6210   result=IC_RESULT(ic);
6211   pic16_aopOp (left,ic,FALSE);
6212   pic16_aopOp (result,ic,FALSE);
6213
6214   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6215
6216   same = pic16_sameRegs(AOP(result),AOP(left));
6217
6218   /* move it to the result */
6219   size = AOP_SIZE(result);    
6220
6221   /* get the msb and put it into the carry */
6222   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6223
6224   offset = 0 ;
6225
6226   while(size--) {
6227
6228     if(same) {
6229       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6230     } else {
6231       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6232       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6233     }
6234
6235     offset++;
6236   }
6237
6238
6239   pic16_freeAsmop(left,NULL,ic,TRUE);
6240   pic16_freeAsmop(result,NULL,ic,TRUE);
6241 }
6242
6243 /*-----------------------------------------------------------------*/
6244 /* genGetHbit - generates code get highest order bit               */
6245 /*-----------------------------------------------------------------*/
6246 static void genGetHbit (iCode *ic)
6247 {
6248     operand *left, *result;
6249     left = IC_LEFT(ic);
6250     result=IC_RESULT(ic);
6251     pic16_aopOp (left,ic,FALSE);
6252     pic16_aopOp (result,ic,FALSE);
6253
6254     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6255     /* get the highest order byte into a */
6256     MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6257     if(AOP_TYPE(result) == AOP_CRY){
6258         pic16_emitcode("rlc","a");
6259         pic16_outBitC(result);
6260     }
6261     else{
6262         pic16_emitcode("rl","a");
6263         pic16_emitcode("anl","a,#0x01");
6264         pic16_outAcc(result);
6265     }
6266
6267
6268     pic16_freeAsmop(left,NULL,ic,TRUE);
6269     pic16_freeAsmop(result,NULL,ic,TRUE);
6270 }
6271
6272 /*-----------------------------------------------------------------*/
6273 /* AccRol - rotate left accumulator by known count                 */
6274 /*-----------------------------------------------------------------*/
6275 static void AccRol (int shCount)
6276 {
6277     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6278     shCount &= 0x0007;              // shCount : 0..7
6279     switch(shCount){
6280         case 0 :
6281             break;
6282         case 1 :
6283             pic16_emitcode("rl","a");
6284             break;
6285         case 2 :
6286             pic16_emitcode("rl","a");
6287             pic16_emitcode("rl","a");
6288             break;
6289         case 3 :
6290             pic16_emitcode("swap","a");
6291             pic16_emitcode("rr","a");
6292             break;
6293         case 4 :
6294             pic16_emitcode("swap","a");
6295             break;
6296         case 5 :
6297             pic16_emitcode("swap","a");
6298             pic16_emitcode("rl","a");
6299             break;
6300         case 6 :
6301             pic16_emitcode("rr","a");
6302             pic16_emitcode("rr","a");
6303             break;
6304         case 7 :
6305             pic16_emitcode("rr","a");
6306             break;
6307     }
6308 }
6309
6310 /*-----------------------------------------------------------------*/
6311 /* AccLsh - left shift accumulator by known count                  */
6312 /*-----------------------------------------------------------------*/
6313 static void AccLsh (int shCount)
6314 {
6315     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6316     if(shCount != 0){
6317         if(shCount == 1)
6318             pic16_emitcode("add","a,acc");
6319         else 
6320             if(shCount == 2) {
6321             pic16_emitcode("add","a,acc");
6322             pic16_emitcode("add","a,acc");
6323         } else {
6324             /* rotate left accumulator */
6325             AccRol(shCount);
6326             /* and kill the lower order bits */
6327             pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6328         }
6329     }
6330 }
6331
6332 /*-----------------------------------------------------------------*/
6333 /* AccRsh - right shift accumulator by known count                 */
6334 /*-----------------------------------------------------------------*/
6335 static void AccRsh (int shCount)
6336 {
6337     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6338     if(shCount != 0){
6339         if(shCount == 1){
6340             CLRC;
6341             pic16_emitcode("rrc","a");
6342         } else {
6343             /* rotate right accumulator */
6344             AccRol(8 - shCount);
6345             /* and kill the higher order bits */
6346             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6347         }
6348     }
6349 }
6350
6351 #if 0
6352 /*-----------------------------------------------------------------*/
6353 /* AccSRsh - signed right shift accumulator by known count                 */
6354 /*-----------------------------------------------------------------*/
6355 static void AccSRsh (int shCount)
6356 {
6357     symbol *tlbl ;
6358     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6359     if(shCount != 0){
6360         if(shCount == 1){
6361             pic16_emitcode("mov","c,acc.7");
6362             pic16_emitcode("rrc","a");
6363         } else if(shCount == 2){
6364             pic16_emitcode("mov","c,acc.7");
6365             pic16_emitcode("rrc","a");
6366             pic16_emitcode("mov","c,acc.7");
6367             pic16_emitcode("rrc","a");
6368         } else {
6369             tlbl = newiTempLabel(NULL);
6370             /* rotate right accumulator */
6371             AccRol(8 - shCount);
6372             /* and kill the higher order bits */
6373             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6374             pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6375             pic16_emitcode("orl","a,#0x%02x",
6376                      (unsigned char)~SRMask[shCount]);
6377             pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6378         }
6379     }
6380 }
6381 #endif
6382 /*-----------------------------------------------------------------*/
6383 /* shiftR1Left2Result - shift right one byte from left to result   */
6384 /*-----------------------------------------------------------------*/
6385 static void shiftR1Left2ResultSigned (operand *left, int offl,
6386                                 operand *result, int offr,
6387                                 int shCount)
6388 {
6389   int same;
6390
6391   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6392
6393   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6394
6395   switch(shCount) {
6396   case 1:
6397     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6398     if(same) 
6399       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6400     else {
6401       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6402       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6403     }
6404
6405     break;
6406   case 2:
6407
6408     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6409     if(same) 
6410       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6411     else {
6412       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6413       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6414     }
6415     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6416     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6417
6418     break;
6419
6420   case 3:
6421     if(same)
6422       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6423     else {
6424       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6425       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6426     }
6427
6428     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6429     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6430     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6431
6432     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6433     pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6434
6435     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6436     break;
6437
6438   case 4:
6439     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6440     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
6441     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6442     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
6443     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6444     break;
6445   case 5:
6446     if(same) {
6447       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
6448     } else {
6449       pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
6450       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6451     }
6452     pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
6453     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
6454     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6455     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
6456     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6457     break;
6458
6459   case 6:
6460     if(same) {
6461       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6462       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6463       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6464       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6465       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6466       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6467     } else {
6468       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6469       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6470       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6471       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6472       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6473     }
6474     break;
6475
6476   case 7:
6477     if(same) {
6478       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6479       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6480       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6481       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6482     } else {
6483       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6484       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6485       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6486     }
6487
6488   default:
6489     break;
6490   }
6491 }
6492
6493 /*-----------------------------------------------------------------*/
6494 /* shiftR1Left2Result - shift right one byte from left to result   */
6495 /*-----------------------------------------------------------------*/
6496 static void shiftR1Left2Result (operand *left, int offl,
6497                                 operand *result, int offr,
6498                                 int shCount, int sign)
6499 {
6500   int same;
6501
6502   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6503
6504   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6505
6506   /* Copy the msb into the carry if signed. */
6507   if(sign) {
6508     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6509     return;
6510   }
6511
6512
6513
6514   switch(shCount) {
6515   case 1:
6516     emitCLRC;
6517     if(same) 
6518       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6519     else {
6520       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6521       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6522     }
6523     break;
6524   case 2:
6525     emitCLRC;
6526     if(same) {
6527       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6528     } else {
6529       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6530       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6531     }
6532     emitCLRC;
6533     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6534
6535     break;
6536   case 3:
6537     if(same)
6538       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6539     else {
6540       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6541       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6542     }
6543
6544     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6545     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6546     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6547     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6548     break;
6549       
6550   case 4:
6551     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6552     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6553     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6554     break;
6555
6556   case 5:
6557     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6558     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6559     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6560     emitCLRC;
6561     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6562
6563     break;
6564   case 6:
6565
6566     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl));
6567     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6568     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6569     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6570     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6571     break;
6572
6573   case 7:
6574
6575     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6576     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6577     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6578
6579     break;
6580
6581   default:
6582     break;
6583   }
6584 }
6585
6586 /*-----------------------------------------------------------------*/
6587 /* shiftL1Left2Result - shift left one byte from left to result    */
6588 /*-----------------------------------------------------------------*/
6589 static void shiftL1Left2Result (operand *left, int offl,
6590                                 operand *result, int offr, int shCount)
6591 {
6592   int same;
6593
6594   //    char *l;
6595   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6596
6597   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6598   DEBUGpic16_emitcode ("; ***","same =  %d",same);
6599     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6600     //    MOVA(l);
6601     /* shift left accumulator */
6602     //AccLsh(shCount); // don't comment out just yet...
6603   //    pic16_aopPut(AOP(result),"a",offr);
6604
6605   switch(shCount) {
6606   case 1:
6607     /* Shift left 1 bit position */
6608     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6609     if(same) {
6610       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6611     } else {
6612       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6613       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6614     }
6615     break;
6616   case 2:
6617     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6618     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6619     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6620     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6621     break;
6622   case 3:
6623     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6624     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6625     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6626     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6627     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6628     break;
6629   case 4:
6630     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6631     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6632     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6633     break;
6634   case 5:
6635     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6636     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6637     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6638     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6639     break;
6640   case 6:
6641     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6642     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6643     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6644     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6645     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6646     break;
6647   case 7:
6648     pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6649     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6650     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6651     break;
6652
6653   default:
6654     DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6655   }
6656
6657 }
6658
6659 /*-----------------------------------------------------------------*/
6660 /* movLeft2Result - move byte from left to result                  */
6661 /*-----------------------------------------------------------------*/
6662 static void movLeft2Result (operand *left, int offl,
6663                             operand *result, int offr)
6664 {
6665   char *l;
6666   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6667   if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6668     l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6669
6670     if (*l == '@' && (IS_AOP_PREG(result))) {
6671       pic16_emitcode("mov","a,%s",l);
6672       pic16_aopPut(AOP(result),"a",offr);
6673     } else {
6674       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6675       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6676     }
6677   }
6678 }
6679
6680 /*-----------------------------------------------------------------*/
6681 /* shiftL2Left2Result - shift left two bytes from left to result   */
6682 /*-----------------------------------------------------------------*/
6683 static void shiftL2Left2Result (operand *left, int offl,
6684                                 operand *result, int offr, int shCount)
6685 {
6686
6687
6688   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6689
6690   if(pic16_sameRegs(AOP(result), AOP(left))) {
6691     switch(shCount) {
6692     case 0:
6693       break;
6694     case 1:
6695     case 2:
6696     case 3:
6697
6698       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6699       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6700       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6701
6702       while(--shCount) {
6703         emitCLRC;
6704         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6705         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6706       }
6707
6708       break;
6709     case 4:
6710     case 5:
6711       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6712       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6713       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6714       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6715       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6716       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6717       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6718       if(shCount >=5) {
6719         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6720         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6721       }
6722       break;
6723     case 6:
6724       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6725       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6726       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6727       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6728       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6729       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6730       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6731       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6732       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6733       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6734       break;
6735     case 7:
6736       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6737       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6738       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6739       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6740       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6741     }
6742
6743   } else {
6744     switch(shCount) {
6745     case 0:
6746       break;
6747     case 1:
6748     case 2:
6749     case 3:
6750       /* note, use a mov/add for the shift since the mov has a
6751          chance of getting optimized out */
6752       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6753       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6754       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6755       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl+MSB16));
6756       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6757
6758       while(--shCount) {
6759         emitCLRC;
6760         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6761         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6762       }
6763       break;
6764
6765     case 4:
6766     case 5:
6767       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6768       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6769       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6770       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6771       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6772       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6773       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6774       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6775
6776
6777       if(shCount == 5) {
6778         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6779         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6780       }
6781       break;
6782     case 6:
6783       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6784       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6785       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6786       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6787
6788       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6789       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6790       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6791       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6792       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6793       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6794       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6795       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6796       break;
6797     case 7:
6798       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6799       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6800       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6801       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6802       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6803     }
6804   }
6805
6806 }
6807 /*-----------------------------------------------------------------*/
6808 /* shiftR2Left2Result - shift right two bytes from left to result  */
6809 /*-----------------------------------------------------------------*/
6810 static void shiftR2Left2Result (operand *left, int offl,
6811                                 operand *result, int offr,
6812                                 int shCount, int sign)
6813 {
6814   int same=0;
6815
6816   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6817   same = pic16_sameRegs(AOP(result), AOP(left));
6818
6819   if(same && ((offl + MSB16) == offr)){
6820     same=1;
6821     /* don't crash result[offr] */
6822     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6823     pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6824   }
6825 /* else {
6826     movLeft2Result(left,offl, result, offr);
6827     MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6828   }
6829 */
6830   /* a:x >> shCount (x = lsb(result))*/
6831 /*
6832   if(sign)
6833     AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6834   else {
6835     AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6836 */
6837   switch(shCount) {
6838   case 0:
6839     break;
6840   case 1:
6841   case 2:
6842   case 3:
6843     if(sign)
6844       pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6845     else
6846       emitCLRC;
6847
6848     if(same) {
6849       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6850       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6851     } else {
6852       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6853       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6854       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6855       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6856     }
6857
6858     while(--shCount) {
6859       if(sign)
6860         pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6861       else
6862         emitCLRC;
6863       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6864       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6865     }
6866     break;
6867   case 4:
6868   case 5:
6869     if(same) {
6870
6871       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6872       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6873       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6874
6875       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6876       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6877       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6878       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6879     } else {
6880       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6881       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6882       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6883
6884       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6885       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6886       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6887       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6888       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6889     }
6890
6891     if(shCount >=5) {
6892       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6893       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6894     }
6895
6896     if(sign) {
6897       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6898       pic16_emitpcode(POC_BTFSC, 
6899                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6900       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6901     }
6902
6903     break;
6904
6905   case 6:
6906     if(same) {
6907
6908       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6909       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6910
6911       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6912       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6913       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6914       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6915       if(sign) {
6916         pic16_emitpcode(POC_BTFSC, 
6917                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6918         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6919       }
6920       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6921       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6922       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6923       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6924     } else {
6925       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6926       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6927       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6928       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6929       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6930       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6931       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6932       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6933       if(sign) {
6934         pic16_emitpcode(POC_BTFSC, 
6935                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6936         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6937       }
6938       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6939       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6940
6941         
6942     }
6943
6944     break;
6945   case 7:
6946     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6947     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6948     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6949     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6950     if(sign) {
6951       emitSKPNC;
6952       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6953     } else 
6954       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6955   }
6956 }
6957
6958
6959 /*-----------------------------------------------------------------*/
6960 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6961 /*-----------------------------------------------------------------*/
6962 static void shiftLLeftOrResult (operand *left, int offl,
6963                                 operand *result, int offr, int shCount)
6964 {
6965     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6966     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6967     /* shift left accumulator */
6968     AccLsh(shCount);
6969     /* or with result */
6970     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6971     /* back to result */
6972     pic16_aopPut(AOP(result),"a",offr);
6973 }
6974
6975 /*-----------------------------------------------------------------*/
6976 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6977 /*-----------------------------------------------------------------*/
6978 static void shiftRLeftOrResult (operand *left, int offl,
6979                                 operand *result, int offr, int shCount)
6980 {
6981     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6982     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6983     /* shift right accumulator */
6984     AccRsh(shCount);
6985     /* or with result */
6986     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6987     /* back to result */
6988     pic16_aopPut(AOP(result),"a",offr);
6989 }
6990
6991 /*-----------------------------------------------------------------*/
6992 /* genlshOne - left shift a one byte quantity by known count       */
6993 /*-----------------------------------------------------------------*/
6994 static void genlshOne (operand *result, operand *left, int shCount)
6995 {       
6996     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6997     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6998 }
6999
7000 /*-----------------------------------------------------------------*/
7001 /* genlshTwo - left shift two bytes by known amount != 0           */
7002 /*-----------------------------------------------------------------*/
7003 static void genlshTwo (operand *result,operand *left, int shCount)
7004 {
7005     int size;
7006     
7007     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7008     size = pic16_getDataSize(result);
7009
7010     /* if shCount >= 8 */
7011     if (shCount >= 8) {
7012         shCount -= 8 ;
7013
7014         if (size > 1){
7015             if (shCount)
7016                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7017             else 
7018                 movLeft2Result(left, LSB, result, MSB16);
7019         }
7020         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7021     }
7022
7023     /*  1 <= shCount <= 7 */
7024     else {  
7025         if(size == 1)
7026             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
7027         else 
7028             shiftL2Left2Result(left, LSB, result, LSB, shCount);
7029     }
7030 }
7031
7032 /*-----------------------------------------------------------------*/
7033 /* shiftLLong - shift left one long from left to result            */
7034 /* offl = LSB or MSB16                                             */
7035 /*-----------------------------------------------------------------*/
7036 static void shiftLLong (operand *left, operand *result, int offr )
7037 {
7038     char *l;
7039     int size = AOP_SIZE(result);
7040
7041     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7042     if(size >= LSB+offr){
7043         l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7044         MOVA(l);
7045         pic16_emitcode("add","a,acc");
7046         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7047             size >= MSB16+offr && offr != LSB )
7048             pic16_emitcode("xch","a,%s",
7049                      pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7050         else        
7051             pic16_aopPut(AOP(result),"a",LSB+offr);
7052     }
7053
7054     if(size >= MSB16+offr){
7055         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7056             l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7057             MOVA(l);
7058         }
7059         pic16_emitcode("rlc","a");
7060         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7061             size >= MSB24+offr && offr != LSB)
7062             pic16_emitcode("xch","a,%s",
7063                      pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7064         else        
7065             pic16_aopPut(AOP(result),"a",MSB16+offr);
7066     }
7067
7068     if(size >= MSB24+offr){
7069         if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7070             l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7071             MOVA(l);
7072         }
7073         pic16_emitcode("rlc","a");
7074         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7075             size >= MSB32+offr && offr != LSB )
7076             pic16_emitcode("xch","a,%s",
7077                      pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7078         else        
7079             pic16_aopPut(AOP(result),"a",MSB24+offr);
7080     }
7081
7082     if(size > MSB32+offr){
7083         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7084             l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7085             MOVA(l);    
7086         }
7087         pic16_emitcode("rlc","a");
7088         pic16_aopPut(AOP(result),"a",MSB32+offr);
7089     }
7090     if(offr != LSB)
7091         pic16_aopPut(AOP(result),zero,LSB);       
7092 }
7093
7094 /*-----------------------------------------------------------------*/
7095 /* genlshFour - shift four byte by a known amount != 0             */
7096 /*-----------------------------------------------------------------*/
7097 static void genlshFour (operand *result, operand *left, int shCount)
7098 {
7099     int size;
7100
7101     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7102     size = AOP_SIZE(result);
7103
7104     /* if shifting more that 3 bytes */
7105     if (shCount >= 24 ) {
7106         shCount -= 24;
7107         if (shCount)
7108             /* lowest order of left goes to the highest
7109             order of the destination */
7110             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7111         else
7112             movLeft2Result(left, LSB, result, MSB32);
7113         pic16_aopPut(AOP(result),zero,LSB);
7114         pic16_aopPut(AOP(result),zero,MSB16);
7115         pic16_aopPut(AOP(result),zero,MSB32);
7116         return;
7117     }
7118
7119     /* more than two bytes */
7120     else if ( shCount >= 16 ) {
7121         /* lower order two bytes goes to higher order two bytes */
7122         shCount -= 16;
7123         /* if some more remaining */
7124         if (shCount)
7125             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7126         else {
7127             movLeft2Result(left, MSB16, result, MSB32);
7128             movLeft2Result(left, LSB, result, MSB24);
7129         }
7130         pic16_aopPut(AOP(result),zero,MSB16);
7131         pic16_aopPut(AOP(result),zero,LSB);
7132         return;
7133     }    
7134
7135     /* if more than 1 byte */
7136     else if ( shCount >= 8 ) {
7137         /* lower order three bytes goes to higher order  three bytes */
7138         shCount -= 8;
7139         if(size == 2){
7140             if(shCount)
7141                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7142             else
7143                 movLeft2Result(left, LSB, result, MSB16);
7144         }
7145         else{   /* size = 4 */
7146             if(shCount == 0){
7147                 movLeft2Result(left, MSB24, result, MSB32);
7148                 movLeft2Result(left, MSB16, result, MSB24);
7149                 movLeft2Result(left, LSB, result, MSB16);
7150                 pic16_aopPut(AOP(result),zero,LSB);
7151             }
7152             else if(shCount == 1)
7153                 shiftLLong(left, result, MSB16);
7154             else{
7155                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7156                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7157                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7158                 pic16_aopPut(AOP(result),zero,LSB);
7159             }
7160         }
7161     }
7162
7163     /* 1 <= shCount <= 7 */
7164     else if(shCount <= 2){
7165         shiftLLong(left, result, LSB);
7166         if(shCount == 2)
7167             shiftLLong(result, result, LSB);
7168     }
7169     /* 3 <= shCount <= 7, optimize */
7170     else{
7171         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7172         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7173         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7174     }
7175 }
7176
7177 /*-----------------------------------------------------------------*/
7178 /* genLeftShiftLiteral - left shifting by known count              */
7179 /*-----------------------------------------------------------------*/
7180 static void genLeftShiftLiteral (operand *left,
7181                                  operand *right,
7182                                  operand *result,
7183                                  iCode *ic)
7184 {    
7185     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7186     int size;
7187
7188     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7189     pic16_freeAsmop(right,NULL,ic,TRUE);
7190
7191     pic16_aopOp(left,ic,FALSE);
7192     pic16_aopOp(result,ic,FALSE);
7193
7194     size = getSize(operandType(result));
7195
7196 #if VIEW_SIZE
7197     pic16_emitcode("; shift left ","result %d, left %d",size,
7198              AOP_SIZE(left));
7199 #endif
7200
7201     /* I suppose that the left size >= result size */
7202     if(shCount == 0){
7203         while(size--){
7204             movLeft2Result(left, size, result, size);
7205         }
7206     }
7207
7208     else if(shCount >= (size * 8))
7209         while(size--)
7210             pic16_aopPut(AOP(result),zero,size);
7211     else{
7212         switch (size) {
7213             case 1:
7214                 genlshOne (result,left,shCount);
7215                 break;
7216
7217             case 2:
7218             case 3:
7219                 genlshTwo (result,left,shCount);
7220                 break;
7221
7222             case 4:
7223                 genlshFour (result,left,shCount);
7224                 break;
7225         }
7226     }
7227     pic16_freeAsmop(left,NULL,ic,TRUE);
7228     pic16_freeAsmop(result,NULL,ic,TRUE);
7229 }
7230
7231 /*-----------------------------------------------------------------*
7232  * genMultiAsm - repeat assembly instruction for size of register.
7233  * if endian == 1, then the high byte (i.e base address + size of 
7234  * register) is used first else the low byte is used first;
7235  *-----------------------------------------------------------------*/
7236 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7237 {
7238
7239   int offset = 0;
7240
7241   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7242
7243   if(!reg)
7244     return;
7245
7246   if(!endian) {
7247     endian = 1;
7248   } else {
7249     endian = -1;
7250     offset = size-1;
7251   }
7252
7253   while(size--) {
7254     pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
7255     offset += endian;
7256   }
7257
7258 }
7259 /*-----------------------------------------------------------------*/
7260 /* genLeftShift - generates code for left shifting                 */
7261 /*-----------------------------------------------------------------*/
7262 static void genLeftShift (iCode *ic)
7263 {
7264   operand *left,*right, *result;
7265   int size, offset;
7266   char *l;
7267   symbol *tlbl , *tlbl1;
7268   pCodeOp *pctemp;
7269
7270   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7271
7272   right = IC_RIGHT(ic);
7273   left  = IC_LEFT(ic);
7274   result = IC_RESULT(ic);
7275
7276   pic16_aopOp(right,ic,FALSE);
7277
7278   /* if the shift count is known then do it 
7279      as efficiently as possible */
7280   if (AOP_TYPE(right) == AOP_LIT) {
7281     genLeftShiftLiteral (left,right,result,ic);
7282     return ;
7283   }
7284
7285   /* shift count is unknown then we have to form 
7286      a loop get the loop count in B : Note: we take
7287      only the lower order byte since shifting
7288      more that 32 bits make no sense anyway, ( the
7289      largest size of an object can be only 32 bits ) */  
7290
7291     
7292   pic16_aopOp(left,ic,FALSE);
7293   pic16_aopOp(result,ic,FALSE);
7294
7295   /* now move the left to the result if they are not the
7296      same */
7297   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7298       AOP_SIZE(result) > 1) {
7299
7300     size = AOP_SIZE(result);
7301     offset=0;
7302     while (size--) {
7303       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7304       if (*l == '@' && (IS_AOP_PREG(result))) {
7305
7306         pic16_emitcode("mov","a,%s",l);
7307         pic16_aopPut(AOP(result),"a",offset);
7308       } else {
7309         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7310         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7311         //pic16_aopPut(AOP(result),l,offset);
7312       }
7313       offset++;
7314     }
7315   }
7316
7317   size = AOP_SIZE(result);
7318
7319   /* if it is only one byte then */
7320   if (size == 1) {
7321     if(optimized_for_speed) {
7322       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7323       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
7324       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7325       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7326       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7327       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7328       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7329       pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
7330       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
7331       pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
7332       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7333       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7334     } else {
7335
7336       tlbl = newiTempLabel(NULL);
7337       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7338         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7339         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7340       }
7341
7342       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7343       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7344       pic16_emitpLabel(tlbl->key);
7345       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7346       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7347       emitSKPC;
7348       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7349     }
7350     goto release ;
7351   }
7352     
7353   if (pic16_sameRegs(AOP(left),AOP(result))) {
7354
7355     tlbl = newiTempLabel(NULL);
7356     pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7357     genMultiAsm(POC_RRCF, result, size,1);
7358     pic16_emitpLabel(tlbl->key);
7359     genMultiAsm(POC_RLCF, result, size,0);
7360     pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7361     emitSKPC;
7362     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7363     goto release;
7364   }
7365
7366   //tlbl = newiTempLabel(NULL);
7367   //offset = 0 ;   
7368   //tlbl1 = newiTempLabel(NULL);
7369
7370   //reAdjustPreg(AOP(result));    
7371     
7372   //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7373   //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7374   //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7375   //MOVA(l);
7376   //pic16_emitcode("add","a,acc");         
7377   //pic16_aopPut(AOP(result),"a",offset++);
7378   //while (--size) {
7379   //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7380   //  MOVA(l);
7381   //  pic16_emitcode("rlc","a");         
7382   //  pic16_aopPut(AOP(result),"a",offset++);
7383   //}
7384   //reAdjustPreg(AOP(result));
7385
7386   //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7387   //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7388
7389
7390   tlbl = newiTempLabel(NULL);
7391   tlbl1= newiTempLabel(NULL);
7392
7393   size = AOP_SIZE(result);
7394   offset = 1;
7395
7396   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7397
7398   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7399
7400   /* offset should be 0, 1 or 3 */
7401   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7402   emitSKPNZ;
7403   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7404
7405   pic16_emitpcode(POC_MOVWF, pctemp);
7406
7407
7408   pic16_emitpLabel(tlbl->key);
7409
7410   emitCLRC;
7411   pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
7412   while(--size)
7413     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
7414
7415   pic16_emitpcode(POC_DECFSZ,  pctemp);
7416   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7417   pic16_emitpLabel(tlbl1->key);
7418
7419   pic16_popReleaseTempReg(pctemp);
7420
7421
7422  release:
7423   pic16_freeAsmop (right,NULL,ic,TRUE);
7424   pic16_freeAsmop(left,NULL,ic,TRUE);
7425   pic16_freeAsmop(result,NULL,ic,TRUE);
7426 }
7427
7428 /*-----------------------------------------------------------------*/
7429 /* genrshOne - right shift a one byte quantity by known count      */
7430 /*-----------------------------------------------------------------*/
7431 static void genrshOne (operand *result, operand *left,
7432                        int shCount, int sign)
7433 {
7434     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7435     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7436 }
7437
7438 /*-----------------------------------------------------------------*/
7439 /* genrshTwo - right shift two bytes by known amount != 0          */
7440 /*-----------------------------------------------------------------*/
7441 static void genrshTwo (operand *result,operand *left,
7442                        int shCount, int sign)
7443 {
7444   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7445   /* if shCount >= 8 */
7446   if (shCount >= 8) {
7447     shCount -= 8 ;
7448     if (shCount)
7449       shiftR1Left2Result(left, MSB16, result, LSB,
7450                          shCount, sign);
7451     else
7452       movLeft2Result(left, MSB16, result, LSB);
7453
7454     pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7455
7456     if(sign) {
7457       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7458       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7459     }
7460   }
7461
7462   /*  1 <= shCount <= 7 */
7463   else
7464     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7465 }
7466
7467 /*-----------------------------------------------------------------*/
7468 /* shiftRLong - shift right one long from left to result           */
7469 /* offl = LSB or MSB16                                             */
7470 /*-----------------------------------------------------------------*/
7471 static void shiftRLong (operand *left, int offl,
7472                         operand *result, int sign)
7473 {
7474     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7475     if(!sign)
7476         pic16_emitcode("clr","c");
7477     MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7478     if(sign)
7479         pic16_emitcode("mov","c,acc.7");
7480     pic16_emitcode("rrc","a");
7481     pic16_aopPut(AOP(result),"a",MSB32-offl);
7482     if(offl == MSB16)
7483         /* add sign of "a" */
7484         pic16_addSign(result, MSB32, sign);
7485
7486     MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7487     pic16_emitcode("rrc","a");
7488     pic16_aopPut(AOP(result),"a",MSB24-offl);
7489
7490     MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7491     pic16_emitcode("rrc","a");
7492     pic16_aopPut(AOP(result),"a",MSB16-offl);
7493
7494     if(offl == LSB){
7495         MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7496         pic16_emitcode("rrc","a");
7497         pic16_aopPut(AOP(result),"a",LSB);
7498     }
7499 }
7500
7501 /*-----------------------------------------------------------------*/
7502 /* genrshFour - shift four byte by a known amount != 0             */
7503 /*-----------------------------------------------------------------*/
7504 static void genrshFour (operand *result, operand *left,
7505                         int shCount, int sign)
7506 {
7507   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7508   /* if shifting more that 3 bytes */
7509   if(shCount >= 24 ) {
7510     shCount -= 24;
7511     if(shCount)
7512       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7513     else
7514       movLeft2Result(left, MSB32, result, LSB);
7515
7516     pic16_addSign(result, MSB16, sign);
7517   }
7518   else if(shCount >= 16){
7519     shCount -= 16;
7520     if(shCount)
7521       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7522     else{
7523       movLeft2Result(left, MSB24, result, LSB);
7524       movLeft2Result(left, MSB32, result, MSB16);
7525     }
7526     pic16_addSign(result, MSB24, sign);
7527   }
7528   else if(shCount >= 8){
7529     shCount -= 8;
7530     if(shCount == 1)
7531       shiftRLong(left, MSB16, result, sign);
7532     else if(shCount == 0){
7533       movLeft2Result(left, MSB16, result, LSB);
7534       movLeft2Result(left, MSB24, result, MSB16);
7535       movLeft2Result(left, MSB32, result, MSB24);
7536       pic16_addSign(result, MSB32, sign);
7537     }
7538     else{
7539       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7540       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7541       /* the last shift is signed */
7542       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7543       pic16_addSign(result, MSB32, sign);
7544     }
7545   }
7546   else{   /* 1 <= shCount <= 7 */
7547     if(shCount <= 2){
7548       shiftRLong(left, LSB, result, sign);
7549       if(shCount == 2)
7550         shiftRLong(result, LSB, result, sign);
7551     }
7552     else{
7553       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7554       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7555       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7556     }
7557   }
7558 }
7559
7560 /*-----------------------------------------------------------------*/
7561 /* genRightShiftLiteral - right shifting by known count            */
7562 /*-----------------------------------------------------------------*/
7563 static void genRightShiftLiteral (operand *left,
7564                                   operand *right,
7565                                   operand *result,
7566                                   iCode *ic,
7567                                   int sign)
7568 {    
7569   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7570   int lsize,res_size;
7571
7572   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7573   pic16_freeAsmop(right,NULL,ic,TRUE);
7574
7575   pic16_aopOp(left,ic,FALSE);
7576   pic16_aopOp(result,ic,FALSE);
7577
7578 #if VIEW_SIZE
7579   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7580                  AOP_SIZE(left));
7581 #endif
7582
7583   lsize = pic16_getDataSize(left);
7584   res_size = pic16_getDataSize(result);
7585   /* test the LEFT size !!! */
7586
7587   /* I suppose that the left size >= result size */
7588   if(shCount == 0){
7589     while(res_size--)
7590       movLeft2Result(left, lsize, result, res_size);
7591   }
7592
7593   else if(shCount >= (lsize * 8)){
7594
7595     if(res_size == 1) {
7596       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7597       if(sign) {
7598         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7599         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7600       }
7601     } else {
7602
7603       if(sign) {
7604         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7605         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7606         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7607         while(res_size--)
7608           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7609
7610       } else {
7611
7612         while(res_size--)
7613           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7614       }
7615     }
7616   } else {
7617
7618     switch (res_size) {
7619     case 1:
7620       genrshOne (result,left,shCount,sign);
7621       break;
7622
7623     case 2:
7624       genrshTwo (result,left,shCount,sign);
7625       break;
7626
7627     case 4:
7628       genrshFour (result,left,shCount,sign);
7629       break;
7630     default :
7631       break;
7632     }
7633
7634   }
7635
7636   pic16_freeAsmop(left,NULL,ic,TRUE);
7637   pic16_freeAsmop(result,NULL,ic,TRUE);
7638 }
7639
7640 /*-----------------------------------------------------------------*/
7641 /* genSignedRightShift - right shift of signed number              */
7642 /*-----------------------------------------------------------------*/
7643 static void genSignedRightShift (iCode *ic)
7644 {
7645   operand *right, *left, *result;
7646   int size, offset;
7647   //  char *l;
7648   symbol *tlbl, *tlbl1 ;
7649   pCodeOp *pctemp;
7650
7651   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7652
7653   /* we do it the hard way put the shift count in b
7654      and loop thru preserving the sign */
7655   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7656
7657   right = IC_RIGHT(ic);
7658   left  = IC_LEFT(ic);
7659   result = IC_RESULT(ic);
7660
7661   pic16_aopOp(right,ic,FALSE);  
7662   pic16_aopOp(left,ic,FALSE);
7663   pic16_aopOp(result,ic,FALSE);
7664
7665
7666   if ( AOP_TYPE(right) == AOP_LIT) {
7667     genRightShiftLiteral (left,right,result,ic,1);
7668     return ;
7669   }
7670   /* shift count is unknown then we have to form 
7671      a loop get the loop count in B : Note: we take
7672      only the lower order byte since shifting
7673      more that 32 bits make no sense anyway, ( the
7674      largest size of an object can be only 32 bits ) */  
7675
7676   //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7677   //pic16_emitcode("inc","b");
7678   //pic16_freeAsmop (right,NULL,ic,TRUE);
7679   //pic16_aopOp(left,ic,FALSE);
7680   //pic16_aopOp(result,ic,FALSE);
7681
7682   /* now move the left to the result if they are not the
7683      same */
7684   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7685       AOP_SIZE(result) > 1) {
7686
7687     size = AOP_SIZE(result);
7688     offset=0;
7689     while (size--) { 
7690       /*
7691         l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7692         if (*l == '@' && IS_AOP_PREG(result)) {
7693
7694         pic16_emitcode("mov","a,%s",l);
7695         pic16_aopPut(AOP(result),"a",offset);
7696         } else
7697         pic16_aopPut(AOP(result),l,offset);
7698       */
7699       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7700       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7701
7702       offset++;
7703     }
7704   }
7705
7706   /* mov the highest order bit to OVR */    
7707   tlbl = newiTempLabel(NULL);
7708   tlbl1= newiTempLabel(NULL);
7709
7710   size = AOP_SIZE(result);
7711   offset = size - 1;
7712
7713   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7714
7715   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7716
7717   /* offset should be 0, 1 or 3 */
7718   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7719   emitSKPNZ;
7720   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7721
7722   pic16_emitpcode(POC_MOVWF, pctemp);
7723
7724
7725   pic16_emitpLabel(tlbl->key);
7726
7727   pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
7728   pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
7729
7730   while(--size) {
7731     pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
7732   }
7733
7734   pic16_emitpcode(POC_DECFSZ,  pctemp);
7735   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7736   pic16_emitpLabel(tlbl1->key);
7737
7738   pic16_popReleaseTempReg(pctemp);
7739 #if 0
7740   size = AOP_SIZE(result);
7741   offset = size - 1;
7742   pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7743   pic16_emitcode("rlc","a");
7744   pic16_emitcode("mov","ov,c");
7745   /* if it is only one byte then */
7746   if (size == 1) {
7747     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7748     MOVA(l);
7749     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7750     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7751     pic16_emitcode("mov","c,ov");
7752     pic16_emitcode("rrc","a");
7753     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7754     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7755     pic16_aopPut(AOP(result),"a",0);
7756     goto release ;
7757   }
7758
7759   reAdjustPreg(AOP(result));
7760   pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7761   pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7762   pic16_emitcode("mov","c,ov");
7763   while (size--) {
7764     l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7765     MOVA(l);
7766     pic16_emitcode("rrc","a");         
7767     pic16_aopPut(AOP(result),"a",offset--);
7768   }
7769   reAdjustPreg(AOP(result));
7770   pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7771   pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7772
7773  release:
7774 #endif
7775
7776   pic16_freeAsmop(left,NULL,ic,TRUE);
7777   pic16_freeAsmop(result,NULL,ic,TRUE);
7778   pic16_freeAsmop(right,NULL,ic,TRUE);
7779 }
7780
7781 /*-----------------------------------------------------------------*/
7782 /* genRightShift - generate code for right shifting                */
7783 /*-----------------------------------------------------------------*/
7784 static void genRightShift (iCode *ic)
7785 {
7786     operand *right, *left, *result;
7787     sym_link *retype ;
7788     int size, offset;
7789     char *l;
7790     symbol *tlbl, *tlbl1 ;
7791
7792     /* if signed then we do it the hard way preserve the
7793     sign bit moving it inwards */
7794     retype = getSpec(operandType(IC_RESULT(ic)));
7795     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7796
7797     if (!SPEC_USIGN(retype)) {
7798         genSignedRightShift (ic);
7799         return ;
7800     }
7801
7802     /* signed & unsigned types are treated the same : i.e. the
7803     signed is NOT propagated inwards : quoting from the
7804     ANSI - standard : "for E1 >> E2, is equivalent to division
7805     by 2**E2 if unsigned or if it has a non-negative value,
7806     otherwise the result is implementation defined ", MY definition
7807     is that the sign does not get propagated */
7808
7809     right = IC_RIGHT(ic);
7810     left  = IC_LEFT(ic);
7811     result = IC_RESULT(ic);
7812
7813     pic16_aopOp(right,ic,FALSE);
7814
7815     /* if the shift count is known then do it 
7816     as efficiently as possible */
7817     if (AOP_TYPE(right) == AOP_LIT) {
7818         genRightShiftLiteral (left,right,result,ic, 0);
7819         return ;
7820     }
7821
7822     /* shift count is unknown then we have to form 
7823     a loop get the loop count in B : Note: we take
7824     only the lower order byte since shifting
7825     more that 32 bits make no sense anyway, ( the
7826     largest size of an object can be only 32 bits ) */  
7827
7828     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7829     pic16_emitcode("inc","b");
7830     pic16_aopOp(left,ic,FALSE);
7831     pic16_aopOp(result,ic,FALSE);
7832
7833     /* now move the left to the result if they are not the
7834     same */
7835     if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7836         AOP_SIZE(result) > 1) {
7837
7838         size = AOP_SIZE(result);
7839         offset=0;
7840         while (size--) {
7841             l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7842             if (*l == '@' && IS_AOP_PREG(result)) {
7843
7844                 pic16_emitcode("mov","a,%s",l);
7845                 pic16_aopPut(AOP(result),"a",offset);
7846             } else
7847                 pic16_aopPut(AOP(result),l,offset);
7848             offset++;
7849         }
7850     }
7851
7852     tlbl = newiTempLabel(NULL);
7853     tlbl1= newiTempLabel(NULL);
7854     size = AOP_SIZE(result);
7855     offset = size - 1;
7856
7857     /* if it is only one byte then */
7858     if (size == 1) {
7859
7860       tlbl = newiTempLabel(NULL);
7861       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7862         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7863         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7864       }
7865
7866       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7867       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7868       pic16_emitpLabel(tlbl->key);
7869       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7870       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7871       emitSKPC;
7872       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7873
7874       goto release ;
7875     }
7876
7877     reAdjustPreg(AOP(result));
7878     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7879     pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7880     CLRC;
7881     while (size--) {
7882         l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7883         MOVA(l);
7884         pic16_emitcode("rrc","a");         
7885         pic16_aopPut(AOP(result),"a",offset--);
7886     }
7887     reAdjustPreg(AOP(result));
7888
7889     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7890     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7891
7892 release:
7893     pic16_freeAsmop(left,NULL,ic,TRUE);
7894     pic16_freeAsmop (right,NULL,ic,TRUE);
7895     pic16_freeAsmop(result,NULL,ic,TRUE);
7896 }
7897
7898 /*-----------------------------------------------------------------*/
7899 /* genUnpackBits - generates code for unpacking bits               */
7900 /*-----------------------------------------------------------------*/
7901 static void genUnpackBits (operand *result, char *rname, int ptype)
7902 {    
7903     int shCnt ;
7904     int rlen = 0 ;
7905     sym_link *etype;
7906     int offset = 0 ;
7907
7908     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7909     etype = getSpec(operandType(result));
7910
7911     /* read the first byte  */
7912     switch (ptype) {
7913
7914     case POINTER:
7915     case IPOINTER:
7916         pic16_emitcode("mov","a,@%s",rname);
7917         break;
7918         
7919     case PPOINTER:
7920         pic16_emitcode("movx","a,@%s",rname);
7921         break;
7922         
7923     case FPOINTER:
7924         pic16_emitcode("movx","a,@dptr");
7925         break;
7926
7927     case CPOINTER:
7928         pic16_emitcode("clr","a");
7929         pic16_emitcode("movc","a","@a+dptr");
7930         break;
7931
7932     case GPOINTER:
7933         pic16_emitcode("lcall","__gptrget");
7934         break;
7935     }
7936
7937     /* if we have bitdisplacement then it fits   */
7938     /* into this byte completely or if length is */
7939     /* less than a byte                          */
7940     if ((shCnt = SPEC_BSTR(etype)) || 
7941         (SPEC_BLEN(etype) <= 8))  {
7942
7943         /* shift right acc */
7944         AccRsh(shCnt);
7945
7946         pic16_emitcode("anl","a,#0x%02x",
7947                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7948         pic16_aopPut(AOP(result),"a",offset);
7949         return ;
7950     }
7951
7952     /* bit field did not fit in a byte  */
7953     rlen = SPEC_BLEN(etype) - 8;
7954     pic16_aopPut(AOP(result),"a",offset++);
7955
7956     while (1)  {
7957
7958         switch (ptype) {
7959         case POINTER:
7960         case IPOINTER:
7961             pic16_emitcode("inc","%s",rname);
7962             pic16_emitcode("mov","a,@%s",rname);
7963             break;
7964             
7965         case PPOINTER:
7966             pic16_emitcode("inc","%s",rname);
7967             pic16_emitcode("movx","a,@%s",rname);
7968             break;
7969
7970         case FPOINTER:
7971             pic16_emitcode("inc","dptr");
7972             pic16_emitcode("movx","a,@dptr");
7973             break;
7974             
7975         case CPOINTER:
7976             pic16_emitcode("clr","a");
7977             pic16_emitcode("inc","dptr");
7978             pic16_emitcode("movc","a","@a+dptr");
7979             break;
7980             
7981         case GPOINTER:
7982             pic16_emitcode("inc","dptr");
7983             pic16_emitcode("lcall","__gptrget");
7984             break;
7985         }
7986
7987         rlen -= 8;            
7988         /* if we are done */
7989         if ( rlen <= 0 )
7990             break ;
7991         
7992         pic16_aopPut(AOP(result),"a",offset++);
7993                               
7994     }
7995     
7996     if (rlen) {
7997         pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7998         pic16_aopPut(AOP(result),"a",offset);          
7999     }
8000     
8001     return ;
8002 }
8003
8004 #if 0
8005 /*-----------------------------------------------------------------*/
8006 /* genDataPointerGet - generates code when ptr offset is known     */
8007 /*-----------------------------------------------------------------*/
8008 static void genDataPointerGet (operand *left, 
8009                                operand *result, 
8010                                iCode *ic)
8011 {
8012   int size , offset = 0;
8013
8014
8015   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8016
8017
8018   /* optimization - most of the time, left and result are the same
8019    * address, but different types. for the pic code, we could omit
8020    * the following
8021    */
8022
8023   pic16_aopOp(result,ic,TRUE);
8024
8025   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8026
8027   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8028
8029   size = AOP_SIZE(result);
8030
8031   while (size--) {
8032     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8033     offset++;
8034   }
8035
8036   pic16_freeAsmop(left,NULL,ic,TRUE);
8037   pic16_freeAsmop(result,NULL,ic,TRUE);
8038 }
8039 #endif
8040 /*-----------------------------------------------------------------*/
8041 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
8042 /*-----------------------------------------------------------------*/
8043 static void genNearPointerGet (operand *left, 
8044                                operand *result, 
8045                                iCode *ic)
8046 {
8047     asmop *aop = NULL;
8048     //regs *preg = NULL ;
8049     char *rname ;
8050     sym_link *rtype, *retype;
8051     sym_link *ltype = operandType(left);    
8052     //char buffer[80];
8053
8054     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8055
8056     rtype = operandType(result);
8057     retype= getSpec(rtype);
8058     
8059     pic16_aopOp(left,ic,FALSE);
8060     
8061     /* if left is rematerialisable and
8062        result is not bit variable type and
8063        the left is pointer to data space i.e
8064        lower 128 bytes of space */
8065     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8066         !IS_BITVAR(retype)         &&
8067         DCL_TYPE(ltype) == POINTER) {
8068       //genDataPointerGet (left,result,ic);
8069         return ;
8070     }
8071     
8072     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8073
8074         /* if the value is already in a pointer register
8075        then don't need anything more */
8076     if (!AOP_INPREG(AOP(left))) {
8077         /* otherwise get a free pointer register */
8078     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8079 /*
8080         aop = newAsmop(0);
8081         preg = getFreePtr(ic,&aop,FALSE);
8082         pic16_emitcode("mov","%s,%s",
8083                 preg->name,
8084                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8085         rname = preg->name ;
8086 */
8087     rname ="BAD";
8088     } else
8089         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8090     
8091     pic16_aopOp (result,ic,FALSE);
8092     
8093       /* if bitfield then unpack the bits */
8094     if (IS_BITVAR(retype)) 
8095         genUnpackBits (result,rname,POINTER);
8096     else {
8097         /* we have can just get the values */
8098       int size = AOP_SIZE(result);
8099       int offset = 0 ;  
8100         
8101       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8102
8103       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8104       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8105       while(size--) {
8106         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8107         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8108         if(size)
8109           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8110       }
8111 /*
8112         while (size--) {
8113             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8114
8115                 pic16_emitcode("mov","a,@%s",rname);
8116                 pic16_aopPut(AOP(result),"a",offset);
8117             } else {
8118                 sprintf(buffer,"@%s",rname);
8119                 pic16_aopPut(AOP(result),buffer,offset);
8120             }
8121             offset++ ;
8122             if (size)
8123                 pic16_emitcode("inc","%s",rname);
8124         }
8125 */
8126     }
8127
8128     /* now some housekeeping stuff */
8129     if (aop) {
8130         /* we had to allocate for this iCode */
8131     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8132         pic16_freeAsmop(NULL,aop,ic,TRUE);
8133     } else { 
8134         /* we did not allocate which means left
8135            already in a pointer register, then
8136            if size > 0 && this could be used again
8137            we have to point it back to where it 
8138            belongs */
8139     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8140         if (AOP_SIZE(result) > 1 &&
8141             !OP_SYMBOL(left)->remat &&
8142             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8143               ic->depth )) {
8144             int size = AOP_SIZE(result) - 1;
8145             while (size--)
8146                 pic16_emitcode("dec","%s",rname);
8147         }
8148     }
8149
8150     /* done */
8151     pic16_freeAsmop(left,NULL,ic,TRUE);
8152     pic16_freeAsmop(result,NULL,ic,TRUE);
8153      
8154 }
8155
8156 /*-----------------------------------------------------------------*/
8157 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
8158 /*-----------------------------------------------------------------*/
8159 static void genPagedPointerGet (operand *left, 
8160                                operand *result, 
8161                                iCode *ic)
8162 {
8163     asmop *aop = NULL;
8164     regs *preg = NULL ;
8165     char *rname ;
8166     sym_link *rtype, *retype;    
8167
8168     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8169
8170     rtype = operandType(result);
8171     retype= getSpec(rtype);
8172     
8173     pic16_aopOp(left,ic,FALSE);
8174
8175   /* if the value is already in a pointer register
8176        then don't need anything more */
8177     if (!AOP_INPREG(AOP(left))) {
8178         /* otherwise get a free pointer register */
8179         aop = newAsmop(0);
8180         preg = getFreePtr(ic,&aop,FALSE);
8181         pic16_emitcode("mov","%s,%s",
8182                 preg->name,
8183                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8184         rname = preg->name ;
8185     } else
8186         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8187     
8188     pic16_freeAsmop(left,NULL,ic,TRUE);
8189     pic16_aopOp (result,ic,FALSE);
8190
8191     /* if bitfield then unpack the bits */
8192     if (IS_BITVAR(retype)) 
8193         genUnpackBits (result,rname,PPOINTER);
8194     else {
8195         /* we have can just get the values */
8196         int size = AOP_SIZE(result);
8197         int offset = 0 ;        
8198         
8199         while (size--) {
8200             
8201             pic16_emitcode("movx","a,@%s",rname);
8202             pic16_aopPut(AOP(result),"a",offset);
8203             
8204             offset++ ;
8205             
8206             if (size)
8207                 pic16_emitcode("inc","%s",rname);
8208         }
8209     }
8210
8211     /* now some housekeeping stuff */
8212     if (aop) {
8213         /* we had to allocate for this iCode */
8214         pic16_freeAsmop(NULL,aop,ic,TRUE);
8215     } else { 
8216         /* we did not allocate which means left
8217            already in a pointer register, then
8218            if size > 0 && this could be used again
8219            we have to point it back to where it 
8220            belongs */
8221         if (AOP_SIZE(result) > 1 &&
8222             !OP_SYMBOL(left)->remat &&
8223             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8224               ic->depth )) {
8225             int size = AOP_SIZE(result) - 1;
8226             while (size--)
8227                 pic16_emitcode("dec","%s",rname);
8228         }
8229     }
8230
8231     /* done */
8232     pic16_freeAsmop(result,NULL,ic,TRUE);
8233     
8234         
8235 }
8236
8237 /*-----------------------------------------------------------------*/
8238 /* genFarPointerGet - gget value from far space                    */
8239 /*-----------------------------------------------------------------*/
8240 static void genFarPointerGet (operand *left,
8241                               operand *result, iCode *ic)
8242 {
8243     int size, offset ;
8244     sym_link *retype = getSpec(operandType(result));
8245
8246     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8247
8248     pic16_aopOp(left,ic,FALSE);
8249
8250     /* if the operand is already in dptr 
8251     then we do nothing else we move the value to dptr */
8252     if (AOP_TYPE(left) != AOP_STR) {
8253         /* if this is remateriazable */
8254         if (AOP_TYPE(left) == AOP_IMMD)
8255             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8256         else { /* we need to get it byte by byte */
8257             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8258             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8259             if (options.model == MODEL_FLAT24)
8260             {
8261                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8262             }
8263         }
8264     }
8265     /* so dptr know contains the address */
8266     pic16_freeAsmop(left,NULL,ic,TRUE);
8267     pic16_aopOp(result,ic,FALSE);
8268
8269     /* if bit then unpack */
8270     if (IS_BITVAR(retype)) 
8271         genUnpackBits(result,"dptr",FPOINTER);
8272     else {
8273         size = AOP_SIZE(result);
8274         offset = 0 ;
8275
8276         while (size--) {
8277             pic16_emitcode("movx","a,@dptr");
8278             pic16_aopPut(AOP(result),"a",offset++);
8279             if (size)
8280                 pic16_emitcode("inc","dptr");
8281         }
8282     }
8283
8284     pic16_freeAsmop(result,NULL,ic,TRUE);
8285 }
8286 #if 0
8287 /*-----------------------------------------------------------------*/
8288 /* genCodePointerGet - get value from code space                  */
8289 /*-----------------------------------------------------------------*/
8290 static void genCodePointerGet (operand *left,
8291                                 operand *result, iCode *ic)
8292 {
8293     int size, offset ;
8294     sym_link *retype = getSpec(operandType(result));
8295
8296     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8297
8298     pic16_aopOp(left,ic,FALSE);
8299
8300     /* if the operand is already in dptr 
8301     then we do nothing else we move the value to dptr */
8302     if (AOP_TYPE(left) != AOP_STR) {
8303         /* if this is remateriazable */
8304         if (AOP_TYPE(left) == AOP_IMMD)
8305             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8306         else { /* we need to get it byte by byte */
8307             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8308             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8309             if (options.model == MODEL_FLAT24)
8310             {
8311                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8312             }
8313         }
8314     }
8315     /* so dptr know contains the address */
8316     pic16_freeAsmop(left,NULL,ic,TRUE);
8317     pic16_aopOp(result,ic,FALSE);
8318
8319     /* if bit then unpack */
8320     if (IS_BITVAR(retype)) 
8321         genUnpackBits(result,"dptr",CPOINTER);
8322     else {
8323         size = AOP_SIZE(result);
8324         offset = 0 ;
8325
8326         while (size--) {
8327             pic16_emitcode("clr","a");
8328             pic16_emitcode("movc","a,@a+dptr");
8329             pic16_aopPut(AOP(result),"a",offset++);
8330             if (size)
8331                 pic16_emitcode("inc","dptr");
8332         }
8333     }
8334
8335     pic16_freeAsmop(result,NULL,ic,TRUE);
8336 }
8337 #endif
8338 /*-----------------------------------------------------------------*/
8339 /* genGenPointerGet - gget value from generic pointer space        */
8340 /*-----------------------------------------------------------------*/
8341 static void genGenPointerGet (operand *left,
8342                               operand *result, iCode *ic)
8343 {
8344   int size, offset ;
8345   sym_link *retype = getSpec(operandType(result));
8346
8347   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8348   pic16_aopOp(left,ic,FALSE);
8349   pic16_aopOp(result,ic,FALSE);
8350
8351
8352   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8353
8354   /* if the operand is already in dptr 
8355      then we do nothing else we move the value to dptr */
8356   //  if (AOP_TYPE(left) != AOP_STR) {
8357     /* if this is remateriazable */
8358     if (AOP_TYPE(left) == AOP_IMMD) {
8359       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8360       pic16_emitcode("mov","b,#%d",pointerCode(retype));
8361     }
8362     else { /* we need to get it byte by byte */
8363
8364       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8365       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8366
8367       size = AOP_SIZE(result);
8368       offset = 0 ;
8369
8370       while(size--) {
8371         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8372         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8373         if(size)
8374           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8375       }
8376       goto release;
8377     }
8378     //}
8379   /* so dptr know contains the address */
8380
8381   /* if bit then unpack */
8382   //if (IS_BITVAR(retype)) 
8383   //  genUnpackBits(result,"dptr",GPOINTER);
8384
8385  release:
8386   pic16_freeAsmop(left,NULL,ic,TRUE);
8387   pic16_freeAsmop(result,NULL,ic,TRUE);
8388
8389 }
8390
8391 /*-----------------------------------------------------------------*/
8392 /* genConstPointerGet - get value from const generic pointer space */
8393 /*-----------------------------------------------------------------*/
8394 static void genConstPointerGet (operand *left,
8395                                 operand *result, iCode *ic)
8396 {
8397   //sym_link *retype = getSpec(operandType(result));
8398   symbol *albl = newiTempLabel(NULL);
8399   symbol *blbl = newiTempLabel(NULL);
8400   PIC_OPCODE poc;
8401
8402   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8403   pic16_aopOp(left,ic,FALSE);
8404   pic16_aopOp(result,ic,FALSE);
8405
8406
8407   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8408
8409   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8410
8411   pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8412   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8413   pic16_emitpLabel(albl->key);
8414
8415   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8416     
8417   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8418   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8419   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8420   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8421
8422   pic16_emitpLabel(blbl->key);
8423
8424   pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8425
8426
8427   pic16_freeAsmop(left,NULL,ic,TRUE);
8428   pic16_freeAsmop(result,NULL,ic,TRUE);
8429
8430 }
8431 /*-----------------------------------------------------------------*/
8432 /* genPointerGet - generate code for pointer get                   */
8433 /*-----------------------------------------------------------------*/
8434 static void genPointerGet (iCode *ic)
8435 {
8436     operand *left, *result ;
8437     sym_link *type, *etype;
8438     int p_type;
8439
8440     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8441
8442     left = IC_LEFT(ic);
8443     result = IC_RESULT(ic) ;
8444
8445     /* depending on the type of pointer we need to
8446     move it to the correct pointer register */
8447     type = operandType(left);
8448     etype = getSpec(type);
8449
8450     if (IS_PTR_CONST(type))
8451       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8452
8453     /* if left is of type of pointer then it is simple */
8454     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8455         p_type = DCL_TYPE(type);
8456     else {
8457         /* we have to go by the storage class */
8458         p_type = PTR_TYPE(SPEC_OCLS(etype));
8459
8460         DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8461
8462         if (SPEC_OCLS(etype)->codesp ) {
8463           DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8464           //p_type = CPOINTER ; 
8465         }
8466         else
8467             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8468               DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8469                /*p_type = FPOINTER ;*/ 
8470             else
8471                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8472                   DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8473 /*                  p_type = PPOINTER; */
8474                 else
8475                     if (SPEC_OCLS(etype) == idata )
8476                       DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8477 /*                      p_type = IPOINTER; */
8478                     else
8479                       DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8480 /*                      p_type = POINTER ; */
8481     }
8482
8483     /* now that we have the pointer type we assign
8484     the pointer values */
8485     switch (p_type) {
8486
8487     case POINTER:       
8488     case IPOINTER:
8489         genNearPointerGet (left,result,ic);
8490         break;
8491
8492     case PPOINTER:
8493         genPagedPointerGet(left,result,ic);
8494         break;
8495
8496     case FPOINTER:
8497         genFarPointerGet (left,result,ic);
8498         break;
8499
8500     case CPOINTER:
8501         genConstPointerGet (left,result,ic);
8502         //pic16_emitcodePointerGet (left,result,ic);
8503         break;
8504
8505     case GPOINTER:
8506       if (IS_PTR_CONST(type))
8507         genConstPointerGet (left,result,ic);
8508       else
8509         genGenPointerGet (left,result,ic);
8510       break;
8511     }
8512
8513 }
8514
8515 /*-----------------------------------------------------------------*/
8516 /* genPackBits - generates code for packed bit storage             */
8517 /*-----------------------------------------------------------------*/
8518 static void genPackBits (sym_link    *etype ,
8519                          operand *right ,
8520                          char *rname, int p_type)
8521 {
8522     int shCount = 0 ;
8523     int offset = 0  ;
8524     int rLen = 0 ;
8525     int blen, bstr ;   
8526     char *l ;
8527
8528     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8529     blen = SPEC_BLEN(etype);
8530     bstr = SPEC_BSTR(etype);
8531
8532     l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8533     MOVA(l);   
8534
8535     /* if the bit lenth is less than or    */
8536     /* it exactly fits a byte then         */
8537     if (SPEC_BLEN(etype) <= 8 )  {
8538         shCount = SPEC_BSTR(etype) ;
8539
8540         /* shift left acc */
8541         AccLsh(shCount);
8542
8543         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8544
8545
8546             switch (p_type) {
8547                 case POINTER:
8548                     pic16_emitcode ("mov","b,a");
8549                     pic16_emitcode("mov","a,@%s",rname);
8550                     break;
8551
8552                 case FPOINTER:
8553                     pic16_emitcode ("mov","b,a");
8554                     pic16_emitcode("movx","a,@dptr");
8555                     break;
8556
8557                 case GPOINTER:
8558                     pic16_emitcode ("push","b");
8559                     pic16_emitcode ("push","acc");
8560                     pic16_emitcode ("lcall","__gptrget");
8561                     pic16_emitcode ("pop","b");
8562                     break;
8563             }
8564
8565             pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8566                       ((unsigned char)(0xFF << (blen+bstr)) | 
8567                        (unsigned char)(0xFF >> (8-bstr)) ) );
8568             pic16_emitcode ("orl","a,b");
8569             if (p_type == GPOINTER)
8570                 pic16_emitcode("pop","b");
8571         }
8572     }
8573
8574     switch (p_type) {
8575         case POINTER:
8576             pic16_emitcode("mov","@%s,a",rname);
8577             break;
8578
8579         case FPOINTER:
8580             pic16_emitcode("movx","@dptr,a");
8581             break;
8582
8583         case GPOINTER:
8584             DEBUGpic16_emitcode(";lcall","__gptrput");
8585             break;
8586     }
8587
8588     /* if we r done */
8589     if ( SPEC_BLEN(etype) <= 8 )
8590         return ;
8591
8592     pic16_emitcode("inc","%s",rname);
8593     rLen = SPEC_BLEN(etype) ;     
8594
8595     /* now generate for lengths greater than one byte */
8596     while (1) {
8597
8598         l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8599
8600         rLen -= 8 ;
8601         if (rLen <= 0 )
8602             break ;
8603
8604         switch (p_type) {
8605             case POINTER:
8606                 if (*l == '@') {
8607                     MOVA(l);
8608                     pic16_emitcode("mov","@%s,a",rname);
8609                 } else
8610                     pic16_emitcode("mov","@%s,%s",rname,l);
8611                 break;
8612
8613             case FPOINTER:
8614                 MOVA(l);
8615                 pic16_emitcode("movx","@dptr,a");
8616                 break;
8617
8618             case GPOINTER:
8619                 MOVA(l);
8620                 DEBUGpic16_emitcode(";lcall","__gptrput");
8621                 break;  
8622         }   
8623         pic16_emitcode ("inc","%s",rname);
8624     }
8625
8626     MOVA(l);
8627
8628     /* last last was not complete */
8629     if (rLen)   {
8630         /* save the byte & read byte */
8631         switch (p_type) {
8632             case POINTER:
8633                 pic16_emitcode ("mov","b,a");
8634                 pic16_emitcode("mov","a,@%s",rname);
8635                 break;
8636
8637             case FPOINTER:
8638                 pic16_emitcode ("mov","b,a");
8639                 pic16_emitcode("movx","a,@dptr");
8640                 break;
8641
8642             case GPOINTER:
8643                 pic16_emitcode ("push","b");
8644                 pic16_emitcode ("push","acc");
8645                 pic16_emitcode ("lcall","__gptrget");
8646                 pic16_emitcode ("pop","b");
8647                 break;
8648         }
8649
8650         pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8651         pic16_emitcode ("orl","a,b");
8652     }
8653
8654     if (p_type == GPOINTER)
8655         pic16_emitcode("pop","b");
8656
8657     switch (p_type) {
8658
8659     case POINTER:
8660         pic16_emitcode("mov","@%s,a",rname);
8661         break;
8662         
8663     case FPOINTER:
8664         pic16_emitcode("movx","@dptr,a");
8665         break;
8666         
8667     case GPOINTER:
8668         DEBUGpic16_emitcode(";lcall","__gptrput");
8669         break;                  
8670     }
8671 }
8672 /*-----------------------------------------------------------------*/
8673 /* genDataPointerSet - remat pointer to data space                 */
8674 /*-----------------------------------------------------------------*/
8675 static void genDataPointerSet(operand *right,
8676                               operand *result,
8677                               iCode *ic)
8678 {
8679     int size, offset = 0 ;
8680     char *l, buffer[256];
8681
8682     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8683     pic16_aopOp(right,ic,FALSE);
8684     
8685     l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8686     size = AOP_SIZE(right);
8687 /*
8688     if ( AOP_TYPE(result) == AOP_PCODE) {
8689       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8690               AOP(result)->aopu.pcop->name,
8691               PCOI(AOP(result)->aopu.pcop)->offset);
8692     }
8693 */
8694
8695     // tsd, was l+1 - the underline `_' prefix was being stripped
8696     while (size--) {
8697       if (offset) {
8698         sprintf(buffer,"(%s + %d)",l,offset);
8699         fprintf(stderr,"oops  %s\n",buffer);
8700       } else
8701         sprintf(buffer,"%s",l);
8702
8703         if (AOP_TYPE(right) == AOP_LIT) {
8704           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8705           lit = lit >> (8*offset);
8706           if(lit&0xff) {
8707             pic16_emitcode("movlw","%d",lit);
8708             pic16_emitcode("movwf","%s",buffer);
8709
8710             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8711             //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8712             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8713
8714           } else {
8715             pic16_emitcode("clrf","%s",buffer);
8716             //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8717             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8718           }
8719         }else {
8720           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8721           pic16_emitcode("movwf","%s",buffer);
8722
8723           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8724           //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8725           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8726
8727         }
8728
8729         offset++;
8730     }
8731
8732     pic16_freeAsmop(right,NULL,ic,TRUE);
8733     pic16_freeAsmop(result,NULL,ic,TRUE);
8734 }
8735
8736 /*-----------------------------------------------------------------*/
8737 /* genNearPointerSet - pic16_emitcode for near pointer put                */
8738 /*-----------------------------------------------------------------*/
8739 static void genNearPointerSet (operand *right,
8740                                operand *result, 
8741                                iCode *ic)
8742 {
8743   asmop *aop = NULL;
8744   char *l;
8745   sym_link *retype;
8746   sym_link *ptype = operandType(result);
8747
8748     
8749   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8750   retype= getSpec(operandType(right));
8751
8752   pic16_aopOp(result,ic,FALSE);
8753
8754     
8755   /* if the result is rematerializable &
8756      in data space & not a bit variable */
8757   //if (AOP_TYPE(result) == AOP_IMMD &&
8758   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8759       DCL_TYPE(ptype) == POINTER   &&
8760       !IS_BITVAR(retype)) {
8761     genDataPointerSet (right,result,ic);
8762     pic16_freeAsmop(result,NULL,ic,TRUE);
8763     return;
8764   }
8765
8766   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8767   pic16_aopOp(right,ic,FALSE);
8768   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8769
8770   /* if the value is already in a pointer register
8771      then don't need anything more */
8772   if (!AOP_INPREG(AOP(result))) {
8773     /* otherwise get a free pointer register */
8774     //aop = newAsmop(0);
8775     //preg = getFreePtr(ic,&aop,FALSE);
8776     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8777     //pic16_emitcode("mov","%s,%s",
8778     //         preg->name,
8779     //         pic16_aopGet(AOP(result),0,FALSE,TRUE));
8780     //rname = preg->name ;
8781     //pic16_emitcode("movwf","fsr0");
8782     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8783     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8784     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8785     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8786     goto release;
8787
8788   }// else
8789   //   rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8790
8791
8792   /* if bitfield then unpack the bits */
8793   if (IS_BITVAR(retype)) {
8794     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8795            "The programmer is obviously confused");
8796     //genPackBits (retype,right,rname,POINTER);
8797     exit(1);
8798   }
8799   else {
8800     /* we have can just get the values */
8801     int size = AOP_SIZE(right);
8802     int offset = 0 ;    
8803
8804     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8805     while (size--) {
8806       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8807       if (*l == '@' ) {
8808         //MOVA(l);
8809         //pic16_emitcode("mov","@%s,a",rname);
8810         pic16_emitcode("movf","indf0,w ;1");
8811       } else {
8812
8813         if (AOP_TYPE(right) == AOP_LIT) {
8814           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8815           if(lit) {
8816             pic16_emitcode("movlw","%s",l);
8817             pic16_emitcode("movwf","indf0 ;2");
8818           } else 
8819             pic16_emitcode("clrf","indf0");
8820         }else {
8821           pic16_emitcode("movf","%s,w",l);
8822           pic16_emitcode("movwf","indf0 ;2");
8823         }
8824         //pic16_emitcode("mov","@%s,%s",rname,l);
8825       }
8826       if (size)
8827         pic16_emitcode("incf","fsr0,f ;3");
8828       //pic16_emitcode("inc","%s",rname);
8829       offset++;
8830     }
8831   }
8832
8833   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8834   /* now some housekeeping stuff */
8835   if (aop) {
8836     /* we had to allocate for this iCode */
8837     pic16_freeAsmop(NULL,aop,ic,TRUE);
8838   } else { 
8839     /* we did not allocate which means left
8840        already in a pointer register, then
8841        if size > 0 && this could be used again
8842        we have to point it back to where it 
8843        belongs */
8844     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8845     if (AOP_SIZE(right) > 1 &&
8846         !OP_SYMBOL(result)->remat &&
8847         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8848           ic->depth )) {
8849       int size = AOP_SIZE(right) - 1;
8850       while (size--)
8851         pic16_emitcode("decf","fsr0,f");
8852       //pic16_emitcode("dec","%s",rname);
8853     }
8854   }
8855
8856   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8857   /* done */
8858  release:
8859   pic16_freeAsmop(right,NULL,ic,TRUE);
8860   pic16_freeAsmop(result,NULL,ic,TRUE);
8861 }
8862
8863 /*-----------------------------------------------------------------*/
8864 /* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
8865 /*-----------------------------------------------------------------*/
8866 static void genPagedPointerSet (operand *right,
8867                                operand *result, 
8868                                iCode *ic)
8869 {
8870     asmop *aop = NULL;
8871     regs *preg = NULL ;
8872     char *rname , *l;
8873     sym_link *retype;
8874        
8875     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8876
8877     retype= getSpec(operandType(right));
8878     
8879     pic16_aopOp(result,ic,FALSE);
8880     
8881     /* if the value is already in a pointer register
8882        then don't need anything more */
8883     if (!AOP_INPREG(AOP(result))) {
8884         /* otherwise get a free pointer register */
8885         aop = newAsmop(0);
8886         preg = getFreePtr(ic,&aop,FALSE);
8887         pic16_emitcode("mov","%s,%s",
8888                 preg->name,
8889                 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8890         rname = preg->name ;
8891     } else
8892         rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8893     
8894     pic16_freeAsmop(result,NULL,ic,TRUE);
8895     pic16_aopOp (right,ic,FALSE);
8896
8897     /* if bitfield then unpack the bits */
8898     if (IS_BITVAR(retype)) 
8899         genPackBits (retype,right,rname,PPOINTER);
8900     else {
8901         /* we have can just get the values */
8902         int size = AOP_SIZE(right);
8903         int offset = 0 ;        
8904         
8905         while (size--) {
8906             l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8907             
8908             MOVA(l);
8909             pic16_emitcode("movx","@%s,a",rname);
8910
8911             if (size)
8912                 pic16_emitcode("inc","%s",rname);
8913
8914             offset++;
8915         }
8916     }
8917     
8918     /* now some housekeeping stuff */
8919     if (aop) {
8920         /* we had to allocate for this iCode */
8921         pic16_freeAsmop(NULL,aop,ic,TRUE);
8922     } else { 
8923         /* we did not allocate which means left
8924            already in a pointer register, then
8925            if size > 0 && this could be used again
8926            we have to point it back to where it 
8927            belongs */
8928         if (AOP_SIZE(right) > 1 &&
8929             !OP_SYMBOL(result)->remat &&
8930             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8931               ic->depth )) {
8932             int size = AOP_SIZE(right) - 1;
8933             while (size--)
8934                 pic16_emitcode("dec","%s",rname);
8935         }
8936     }
8937
8938     /* done */
8939     pic16_freeAsmop(right,NULL,ic,TRUE);
8940     
8941         
8942 }
8943
8944 /*-----------------------------------------------------------------*/
8945 /* genFarPointerSet - set value from far space                     */
8946 /*-----------------------------------------------------------------*/
8947 static void genFarPointerSet (operand *right,
8948                               operand *result, iCode *ic)
8949 {
8950     int size, offset ;
8951     sym_link *retype = getSpec(operandType(right));
8952
8953     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8954     pic16_aopOp(result,ic,FALSE);
8955
8956     /* if the operand is already in dptr 
8957     then we do nothing else we move the value to dptr */
8958     if (AOP_TYPE(result) != AOP_STR) {
8959         /* if this is remateriazable */
8960         if (AOP_TYPE(result) == AOP_IMMD)
8961             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8962         else { /* we need to get it byte by byte */
8963             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8964             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8965             if (options.model == MODEL_FLAT24)
8966             {
8967                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8968             }
8969         }
8970     }
8971     /* so dptr know contains the address */
8972     pic16_freeAsmop(result,NULL,ic,TRUE);
8973     pic16_aopOp(right,ic,FALSE);
8974
8975     /* if bit then unpack */
8976     if (IS_BITVAR(retype)) 
8977         genPackBits(retype,right,"dptr",FPOINTER);
8978     else {
8979         size = AOP_SIZE(right);
8980         offset = 0 ;
8981
8982         while (size--) {
8983             char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8984             MOVA(l);
8985             pic16_emitcode("movx","@dptr,a");
8986             if (size)
8987                 pic16_emitcode("inc","dptr");
8988         }
8989     }
8990
8991     pic16_freeAsmop(right,NULL,ic,TRUE);
8992 }
8993
8994 /*-----------------------------------------------------------------*/
8995 /* genGenPointerSet - set value from generic pointer space         */
8996 /*-----------------------------------------------------------------*/
8997 static void genGenPointerSet (operand *right,
8998                               operand *result, iCode *ic)
8999 {
9000   int size, offset ;
9001   sym_link *retype = getSpec(operandType(right));
9002
9003   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9004
9005   pic16_aopOp(result,ic,FALSE);
9006   pic16_aopOp(right,ic,FALSE);
9007   size = AOP_SIZE(right);
9008
9009   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9010
9011   /* if the operand is already in dptr 
9012      then we do nothing else we move the value to dptr */
9013   if (AOP_TYPE(result) != AOP_STR) {
9014     /* if this is remateriazable */
9015     if (AOP_TYPE(result) == AOP_IMMD) {
9016       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9017       pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9018     }
9019     else { /* we need to get it byte by byte */
9020       //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9021       size = AOP_SIZE(right);
9022       offset = 0 ;
9023
9024       /* hack hack! see if this the FSR. If so don't load W */
9025       if(AOP_TYPE(right) != AOP_ACC) {
9026
9027
9028         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9029         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9030
9031         if(AOP_SIZE(result) > 1) {
9032           pic16_emitpcode(POC_BCF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9033           pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9034           pic16_emitpcode(POC_BSF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9035
9036         }
9037
9038         //if(size==2)
9039         //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9040         //if(size==4) {
9041         //  pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9042         //  pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9043         //}
9044
9045         while(size--) {
9046           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9047           pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9048           
9049           if(size)
9050             pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9051         }
9052
9053
9054         goto release;
9055       } 
9056
9057       if(aopIdx(AOP(result),0) != 4) {
9058
9059         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9060         goto release;
9061       }
9062
9063       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9064       goto release;
9065
9066     }
9067   }
9068   /* so dptr know contains the address */
9069
9070
9071   /* if bit then unpack */
9072   if (IS_BITVAR(retype)) 
9073     genPackBits(retype,right,"dptr",GPOINTER);
9074   else {
9075     size = AOP_SIZE(right);
9076     offset = 0 ;
9077
9078   DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9079
9080     while (size--) {
9081
9082       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9083       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9084
9085       if (AOP_TYPE(right) == AOP_LIT) 
9086         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9087       else
9088         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9089
9090       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9091
9092       offset++;
9093     }
9094   }
9095
9096  release:
9097   pic16_freeAsmop(right,NULL,ic,TRUE);
9098   pic16_freeAsmop(result,NULL,ic,TRUE);
9099 }
9100
9101 /*-----------------------------------------------------------------*/
9102 /* genPointerSet - stores the value into a pointer location        */
9103 /*-----------------------------------------------------------------*/
9104 static void genPointerSet (iCode *ic)
9105 {    
9106     operand *right, *result ;
9107     sym_link *type, *etype;
9108     int p_type;
9109
9110     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9111
9112     right = IC_RIGHT(ic);
9113     result = IC_RESULT(ic) ;
9114
9115     /* depending on the type of pointer we need to
9116     move it to the correct pointer register */
9117     type = operandType(result);
9118     etype = getSpec(type);
9119     /* if left is of type of pointer then it is simple */
9120     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9121         p_type = DCL_TYPE(type);
9122     }
9123     else {
9124         /* we have to go by the storage class */
9125         p_type = PTR_TYPE(SPEC_OCLS(etype));
9126
9127 /*      if (SPEC_OCLS(etype)->codesp ) { */
9128 /*          p_type = CPOINTER ;  */
9129 /*      } */
9130 /*      else */
9131 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9132 /*              p_type = FPOINTER ; */
9133 /*          else */
9134 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9135 /*                  p_type = PPOINTER ; */
9136 /*              else */
9137 /*                  if (SPEC_OCLS(etype) == idata ) */
9138 /*                      p_type = IPOINTER ; */
9139 /*                  else */
9140 /*                      p_type = POINTER ; */
9141     }
9142
9143     /* now that we have the pointer type we assign
9144     the pointer values */
9145     switch (p_type) {
9146
9147     case POINTER:
9148     case IPOINTER:
9149         genNearPointerSet (right,result,ic);
9150         break;
9151
9152     case PPOINTER:
9153         genPagedPointerSet (right,result,ic);
9154         break;
9155
9156     case FPOINTER:
9157         genFarPointerSet (right,result,ic);
9158         break;
9159
9160     case GPOINTER:
9161         genGenPointerSet (right,result,ic);
9162         break;
9163
9164     default:
9165       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9166               "genPointerSet: illegal pointer type");
9167     }
9168 }
9169
9170 /*-----------------------------------------------------------------*/
9171 /* genIfx - generate code for Ifx statement                        */
9172 /*-----------------------------------------------------------------*/
9173 static void genIfx (iCode *ic, iCode *popIc)
9174 {
9175   operand *cond = IC_COND(ic);
9176   int isbit =0;
9177
9178   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9179
9180   pic16_aopOp(cond,ic,FALSE);
9181
9182   /* get the value into acc */
9183   if (AOP_TYPE(cond) != AOP_CRY)
9184     pic16_toBoolean(cond);
9185   else
9186     isbit = 1;
9187   /* the result is now in the accumulator */
9188   pic16_freeAsmop(cond,NULL,ic,TRUE);
9189
9190   /* if there was something to be popped then do it */
9191   if (popIc)
9192     genIpop(popIc);
9193
9194   /* if the condition is  a bit variable */
9195   if (isbit && IS_ITEMP(cond) && 
9196       SPIL_LOC(cond)) {
9197     genIfxJump(ic,SPIL_LOC(cond)->rname);
9198     DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9199   }
9200   else {
9201     if (isbit && !IS_ITEMP(cond))
9202       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9203     else
9204       genIfxJump(ic,"a");
9205   }
9206   ic->generated = 1;
9207
9208 }
9209
9210 /*-----------------------------------------------------------------*/
9211 /* genAddrOf - generates code for address of                       */
9212 /*-----------------------------------------------------------------*/
9213 static void genAddrOf (iCode *ic)
9214 {
9215   operand *right, *result, *left;
9216   int size, offset ;
9217
9218   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9219
9220
9221   //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9222
9223   pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9224   pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9225   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9226
9227   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9228
9229   size = AOP_SIZE(IC_RESULT(ic));
9230   offset = 0;
9231
9232
9233   while (size--) {
9234     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9235     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9236     offset++;
9237   }
9238
9239
9240   pic16_freeAsmop(left,NULL,ic,FALSE);
9241   pic16_freeAsmop(result,NULL,ic,TRUE);
9242
9243 }
9244
9245 #if 0
9246 /*-----------------------------------------------------------------*/
9247 /* genFarFarAssign - assignment when both are in far space         */
9248 /*-----------------------------------------------------------------*/
9249 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9250 {
9251     int size = AOP_SIZE(right);
9252     int offset = 0;
9253     char *l ;
9254     /* first push the right side on to the stack */
9255     while (size--) {
9256         l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9257         MOVA(l);
9258         pic16_emitcode ("push","acc");
9259     }
9260     
9261     pic16_freeAsmop(right,NULL,ic,FALSE);
9262     /* now assign DPTR to result */
9263     pic16_aopOp(result,ic,FALSE);
9264     size = AOP_SIZE(result);
9265     while (size--) {
9266         pic16_emitcode ("pop","acc");
9267         pic16_aopPut(AOP(result),"a",--offset);
9268     }
9269     pic16_freeAsmop(result,NULL,ic,FALSE);
9270         
9271 }
9272 #endif
9273
9274 /*-----------------------------------------------------------------*/
9275 /* genAssign - generate code for assignment                        */
9276 /*-----------------------------------------------------------------*/
9277 static void genAssign (iCode *ic)
9278 {
9279   operand *result, *right;
9280   int size, offset,know_W;
9281   unsigned long lit = 0L;
9282
9283   result = IC_RESULT(ic);
9284   right  = IC_RIGHT(ic) ;
9285
9286   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9287   
9288   /* if they are the same */
9289   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9290     return ;
9291
9292   pic16_aopOp(right,ic,FALSE);
9293   pic16_aopOp(result,ic,TRUE);
9294
9295   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9296
9297   /* if they are the same registers */
9298   if (pic16_sameRegs(AOP(right),AOP(result)))
9299     goto release;
9300
9301   /* if the result is a bit */
9302   if (AOP_TYPE(result) == AOP_CRY) {
9303     /* if the right size is a literal then
9304        we know what the value is */
9305     if (AOP_TYPE(right) == AOP_LIT) {
9306           
9307       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9308                   pic16_popGet(AOP(result),0));
9309
9310       if (((int) operandLitValue(right))) 
9311         pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9312                        AOP(result)->aopu.aop_dir,
9313                        AOP(result)->aopu.aop_dir);
9314       else
9315         pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9316                        AOP(result)->aopu.aop_dir,
9317                        AOP(result)->aopu.aop_dir);
9318       goto release;
9319     }
9320
9321     /* the right is also a bit variable */
9322     if (AOP_TYPE(right) == AOP_CRY) {
9323       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9324       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9325       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9326
9327       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9328                      AOP(result)->aopu.aop_dir,
9329                      AOP(result)->aopu.aop_dir);
9330       pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9331                      AOP(right)->aopu.aop_dir,
9332                      AOP(right)->aopu.aop_dir);
9333       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9334                      AOP(result)->aopu.aop_dir,
9335                      AOP(result)->aopu.aop_dir);
9336       goto release ;
9337     }
9338
9339     /* we need to or */
9340     pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9341     pic16_toBoolean(right);
9342     emitSKPZ;
9343     pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9344     //pic16_aopPut(AOP(result),"a",0);
9345     goto release ;
9346   }
9347
9348   /* bit variables done */
9349   /* general case */
9350   size = AOP_SIZE(result);
9351   offset = 0 ;
9352   if(AOP_TYPE(right) == AOP_LIT)
9353     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9354
9355 /* VR - What is this?! */
9356   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9357   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9358     if(aopIdx(AOP(result),0) == 4) {
9359   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9360       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9361       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9362       goto release;
9363     } else
9364       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9365   }
9366
9367   know_W=-1;
9368   while (size--) {
9369   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9370     if(AOP_TYPE(right) == AOP_LIT) {
9371       if(lit&0xff) {
9372         if(know_W != (lit&0xff))
9373           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9374         know_W = lit&0xff;
9375         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9376       } else
9377         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9378
9379       lit >>= 8;
9380
9381     } else if (AOP_TYPE(right) == AOP_CRY) {
9382       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9383       if(offset == 0) {
9384         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9385         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9386       }
9387     } else {
9388   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9389
9390 #if 1
9391         /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9392            normally should work, but mind that thw W register live range
9393            is not checked, so if the code generator assumes that the W
9394            is already loaded after such a pair, wrong code will be generated.
9395            
9396            Checking the live range is the next step.
9397            This is experimental code yet and has not been fully tested yet.
9398            USE WITH CARE. Revert to old code by setting 0 to the condition above.
9399            Vangelis Rokas 030603 (vrokas@otenet.gr) */
9400            
9401         
9402         pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9403 #else   
9404         /* This is the old code, which is assumed(?!) that works fine(!?) */
9405
9406         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9407         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9408 #endif
9409     }
9410             
9411     offset++;
9412   }
9413
9414     
9415  release:
9416   pic16_freeAsmop (right,NULL,ic,FALSE);
9417   pic16_freeAsmop (result,NULL,ic,TRUE);
9418 }   
9419
9420 /*-----------------------------------------------------------------*/
9421 /* genJumpTab - generates code for jump table                       */
9422 /*-----------------------------------------------------------------*/
9423 static void genJumpTab (iCode *ic)
9424 {
9425     symbol *jtab;
9426     char *l;
9427
9428     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9429
9430     pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9431     /* get the condition into accumulator */
9432     l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9433     MOVA(l);
9434     /* multiply by three */
9435     pic16_emitcode("add","a,acc");
9436     pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9437
9438     jtab = newiTempLabel(NULL);
9439     pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9440     pic16_emitcode("jmp","@a+dptr");
9441     pic16_emitcode("","%05d_DS_:",jtab->key+100);
9442
9443     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9444     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9445     emitSKPNC;
9446     pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9447     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9448     pic16_emitpLabel(jtab->key);
9449
9450     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9451
9452     /* now generate the jump labels */
9453     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9454          jtab = setNextItem(IC_JTLABELS(ic))) {
9455         pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9456         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9457         
9458     }
9459
9460 }
9461
9462 /*-----------------------------------------------------------------*/
9463 /* genMixedOperation - gen code for operators between mixed types  */
9464 /*-----------------------------------------------------------------*/
9465 /*
9466   TSD - Written for the PIC port - but this unfortunately is buggy.
9467   This routine is good in that it is able to efficiently promote 
9468   types to different (larger) sizes. Unfortunately, the temporary
9469   variables that are optimized out by this routine are sometimes
9470   used in other places. So until I know how to really parse the 
9471   iCode tree, I'm going to not be using this routine :(.
9472 */
9473 static int genMixedOperation (iCode *ic)
9474 {
9475 #if 0
9476   operand *result = IC_RESULT(ic);
9477   sym_link *ctype = operandType(IC_LEFT(ic));
9478   operand *right = IC_RIGHT(ic);
9479   int ret = 0;
9480   int big,small;
9481   int offset;
9482
9483   iCode *nextic;
9484   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9485
9486   pic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9487
9488   nextic = ic->next;
9489   if(!nextic)
9490     return 0;
9491
9492   nextright = IC_RIGHT(nextic);
9493   nextleft  = IC_LEFT(nextic);
9494   nextresult = IC_RESULT(nextic);
9495
9496   pic16_aopOp(right,ic,FALSE);
9497   pic16_aopOp(result,ic,FALSE);
9498   pic16_aopOp(nextright,  nextic, FALSE);
9499   pic16_aopOp(nextleft,   nextic, FALSE);
9500   pic16_aopOp(nextresult, nextic, FALSE);
9501
9502   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9503
9504     operand *t = right;
9505     right = nextright;
9506     nextright = t; 
9507
9508     pic16_emitcode(";remove right +","");
9509
9510   } else   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9511 /*
9512     operand *t = right;
9513     right = nextleft;
9514     nextleft = t; 
9515 */
9516     pic16_emitcode(";remove left +","");
9517   } else
9518     return 0;
9519
9520   big = AOP_SIZE(nextleft);
9521   small = AOP_SIZE(nextright);
9522
9523   switch(nextic->op) {
9524
9525   case '+':
9526     pic16_emitcode(";optimize a +","");
9527     /* if unsigned or not an integral type */
9528     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9529       pic16_emitcode(";add a bit to something","");
9530     } else {
9531
9532       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9533
9534       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9535         pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9536         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9537       } else
9538         pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9539
9540       offset = 0;
9541       while(--big) {
9542
9543         offset++;
9544
9545         if(--small) {
9546           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9547             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9548             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9549           }
9550
9551           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9552           emitSKPNC;
9553           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9554                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9555                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9556           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9557           pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9558
9559         } else {
9560           pic16_emitcode("rlf","known_zero,w");
9561
9562           /*
9563             if right is signed
9564               btfsc  right,7
9565                addlw ff
9566           */
9567           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9568             pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9569             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9570           } else {
9571             pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9572           }
9573         }
9574       }
9575       ret = 1;
9576     }
9577   }
9578   ret = 1;
9579
9580 release:
9581   pic16_freeAsmop(right,NULL,ic,TRUE);
9582   pic16_freeAsmop(result,NULL,ic,TRUE);
9583   pic16_freeAsmop(nextright,NULL,ic,TRUE);
9584   pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9585   if(ret)
9586     nextic->generated = 1;
9587
9588   return ret;
9589 #else
9590   return 0;
9591 #endif
9592 }
9593 /*-----------------------------------------------------------------*/
9594 /* genCast - gen code for casting                                  */
9595 /*-----------------------------------------------------------------*/
9596 static void genCast (iCode *ic)
9597 {
9598     operand *result = IC_RESULT(ic);
9599     sym_link *ctype = operandType(IC_LEFT(ic));
9600     sym_link *rtype = operandType(IC_RIGHT(ic));
9601     operand *right = IC_RIGHT(ic);
9602     int size, offset ;
9603
9604     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9605     /* if they are equivalent then do nothing */
9606     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9607         return ;
9608
9609     pic16_aopOp(right,ic,FALSE) ;
9610     pic16_aopOp(result,ic,FALSE);
9611
9612     DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9613
9614     /* if the result is a bit */
9615     if (AOP_TYPE(result) == AOP_CRY) {
9616         /* if the right size is a literal then
9617         we know what the value is */
9618       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9619         if (AOP_TYPE(right) == AOP_LIT) {
9620
9621           pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9622                       pic16_popGet(AOP(result),0));
9623
9624             if (((int) operandLitValue(right))) 
9625               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9626                        AOP(result)->aopu.aop_dir,
9627                        AOP(result)->aopu.aop_dir);
9628             else
9629               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9630                        AOP(result)->aopu.aop_dir,
9631                        AOP(result)->aopu.aop_dir);
9632
9633             goto release;
9634         }
9635
9636         /* the right is also a bit variable */
9637         if (AOP_TYPE(right) == AOP_CRY) {
9638
9639           emitCLRC;
9640           pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9641
9642           pic16_emitcode("clrc","");
9643           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9644                    AOP(right)->aopu.aop_dir,
9645                    AOP(right)->aopu.aop_dir);
9646             pic16_aopPut(AOP(result),"c",0);
9647             goto release ;
9648         }
9649
9650         /* we need to or */
9651         if (AOP_TYPE(right) == AOP_REG) {
9652           pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9653           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9654           pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9655         }
9656         pic16_toBoolean(right);
9657         pic16_aopPut(AOP(result),"a",0);
9658         goto release ;
9659     }
9660
9661     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9662       int offset = 1;
9663       size = AOP_SIZE(result);
9664
9665       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9666
9667       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
9668       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9669       pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
9670
9671       while (size--)
9672         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9673
9674       goto release;
9675     }
9676
9677     /* if they are the same size : or less */
9678     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9679
9680         /* if they are in the same place */
9681       if (pic16_sameRegs(AOP(right),AOP(result)))
9682         goto release;
9683
9684       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9685       if (IS_PTR_CONST(rtype))
9686         DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9687       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9688         DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9689
9690       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9691         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9692         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9693         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9694         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9695         if(AOP_SIZE(result) <2)
9696           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9697
9698       } else {
9699
9700         /* if they in different places then copy */
9701         size = AOP_SIZE(result);
9702         offset = 0 ;
9703         while (size--) {
9704           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9705           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9706
9707           //pic16_aopPut(AOP(result),
9708           // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9709           // offset);
9710
9711           offset++;
9712         }
9713       }
9714       goto release;
9715     }
9716
9717
9718     /* if the result is of type pointer */
9719     if (IS_PTR(ctype)) {
9720
9721         int p_type;
9722         sym_link *type = operandType(right);
9723         sym_link *etype = getSpec(type);
9724       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9725
9726         /* pointer to generic pointer */
9727         if (IS_GENPTR(ctype)) {
9728             char *l = zero;
9729             
9730             if (IS_PTR(type)) 
9731                 p_type = DCL_TYPE(type);
9732             else {
9733                 /* we have to go by the storage class */
9734                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9735
9736 /*              if (SPEC_OCLS(etype)->codesp )  */
9737 /*                  p_type = CPOINTER ;  */
9738 /*              else */
9739 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9740 /*                      p_type = FPOINTER ; */
9741 /*                  else */
9742 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9743 /*                          p_type = PPOINTER; */
9744 /*                      else */
9745 /*                          if (SPEC_OCLS(etype) == idata ) */
9746 /*                              p_type = IPOINTER ; */
9747 /*                          else */
9748 /*                              p_type = POINTER ; */
9749             }
9750                 
9751             /* the first two bytes are known */
9752       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9753             size = GPTRSIZE - 1; 
9754             offset = 0 ;
9755             while (size--) {
9756               if(offset < AOP_SIZE(right)) {
9757       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9758                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9759                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9760                   pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9761                   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9762                 } else { 
9763                   pic16_aopPut(AOP(result),
9764                          pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9765                          offset);
9766                 }
9767               } else 
9768                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9769               offset++;
9770             }
9771             /* the last byte depending on type */
9772             switch (p_type) {
9773             case IPOINTER:
9774             case POINTER:
9775                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9776                 break;
9777             case FPOINTER:
9778               pic16_emitcode(";BUG!? ","%d",__LINE__);
9779                 l = one;
9780                 break;
9781             case CPOINTER:
9782               pic16_emitcode(";BUG!? ","%d",__LINE__);
9783                 l = "#0x02";
9784                 break;                          
9785             case PPOINTER:
9786               pic16_emitcode(";BUG!? ","%d",__LINE__);
9787                 l = "#0x03";
9788                 break;
9789                 
9790             default:
9791                 /* this should never happen */
9792                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9793                        "got unknown pointer type");
9794                 exit(1);
9795             }
9796             //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
9797             goto release ;
9798         }
9799         
9800         /* just copy the pointers */
9801         size = AOP_SIZE(result);
9802         offset = 0 ;
9803         while (size--) {
9804             pic16_aopPut(AOP(result),
9805                    pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9806                    offset);
9807             offset++;
9808         }
9809         goto release ;
9810     }
9811     
9812
9813
9814     /* so we now know that the size of destination is greater
9815     than the size of the source.
9816     Now, if the next iCode is an operator then we might be
9817     able to optimize the operation without performing a cast.
9818     */
9819     if(genMixedOperation(ic))
9820       goto release;
9821
9822     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9823     
9824     /* we move to result for the size of source */
9825     size = AOP_SIZE(right);
9826     offset = 0 ;
9827     while (size--) {
9828       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(right),offset));
9829       pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset));
9830       offset++;
9831     }
9832
9833     /* now depending on the sign of the destination */
9834     size = AOP_SIZE(result) - AOP_SIZE(right);
9835     /* if unsigned or not an integral type */
9836     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9837       while (size--)
9838         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9839     } else {
9840       /* we need to extend the sign :{ */
9841
9842       if(size == 1) {
9843         /* Save one instruction of casting char to int */
9844         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
9845         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9846         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
9847       } else {
9848         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9849
9850         if(offset)
9851           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9852         else
9853           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9854         
9855         pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
9856
9857         while (size--)
9858           pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
9859       }
9860     }
9861
9862 release:
9863     pic16_freeAsmop(right,NULL,ic,TRUE);
9864     pic16_freeAsmop(result,NULL,ic,TRUE);
9865
9866 }
9867
9868 /*-----------------------------------------------------------------*/
9869 /* genDjnz - generate decrement & jump if not zero instrucion      */
9870 /*-----------------------------------------------------------------*/
9871 static int genDjnz (iCode *ic, iCode *ifx)
9872 {
9873     symbol *lbl, *lbl1;
9874     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9875
9876     if (!ifx)
9877         return 0;
9878     
9879     /* if the if condition has a false label
9880        then we cannot save */
9881     if (IC_FALSE(ifx))
9882         return 0;
9883
9884     /* if the minus is not of the form 
9885        a = a - 1 */
9886     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9887         !IS_OP_LITERAL(IC_RIGHT(ic)))
9888         return 0;
9889
9890     if (operandLitValue(IC_RIGHT(ic)) != 1)
9891         return 0;
9892
9893     /* if the size of this greater than one then no
9894        saving */
9895     if (getSize(operandType(IC_RESULT(ic))) > 1)
9896         return 0;
9897
9898     /* otherwise we can save BIG */
9899     lbl = newiTempLabel(NULL);
9900     lbl1= newiTempLabel(NULL);
9901
9902     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9903     
9904     if (IS_AOP_PREG(IC_RESULT(ic))) {
9905         pic16_emitcode("dec","%s",
9906                  pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9907         pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9908         pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9909     } else {    
9910
9911
9912       pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9913       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9914
9915       pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9916       pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9917
9918     }
9919 /*     pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9920 /*     pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9921 /*     pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9922 /*     pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9923
9924     
9925     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9926     ifx->generated = 1;
9927     return 1;
9928 }
9929
9930 /*-----------------------------------------------------------------*/
9931 /* genReceive - generate code for a receive iCode                  */
9932 /*-----------------------------------------------------------------*/
9933 static void genReceive (iCode *ic)
9934 {    
9935   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9936
9937   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9938       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9939         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9940
9941     int size = getSize(operandType(IC_RESULT(ic)));
9942     int offset =  pic16_fReturnSizePic - size;
9943     while (size--) {
9944       pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9945                                     fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9946       offset++;
9947     }
9948     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9949     size = AOP_SIZE(IC_RESULT(ic));
9950     offset = 0;
9951     while (size--) {
9952       pic16_emitcode ("pop","acc");
9953       pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9954     }
9955         
9956   } else {
9957     _G.accInUse++;
9958     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9959     _G.accInUse--;
9960     assignResultValue(IC_RESULT(ic));   
9961   }
9962
9963   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9964 }
9965
9966 /*-----------------------------------------------------------------*/
9967 /* genDummyRead - generate code for dummy read of volatiles        */
9968 /*-----------------------------------------------------------------*/
9969 static void
9970 genDummyRead (iCode * ic)
9971 {
9972   pic16_emitcode ("; genDummyRead","");
9973   pic16_emitcode ("; not implemented","");
9974
9975   ic = ic;
9976 }
9977
9978 /*-----------------------------------------------------------------*/
9979 /* genpic16Code - generate code for pic16 based controllers        */
9980 /*-----------------------------------------------------------------*/
9981 /*
9982  * At this point, ralloc.c has gone through the iCode and attempted
9983  * to optimize in a way suitable for a PIC. Now we've got to generate
9984  * PIC instructions that correspond to the iCode.
9985  *
9986  * Once the instructions are generated, we'll pass through both the
9987  * peep hole optimizer and the pCode optimizer.
9988  *-----------------------------------------------------------------*/
9989
9990 void genpic16Code (iCode *lic)
9991 {
9992     iCode *ic;
9993     int cln = 0;
9994
9995     lineHead = lineCurr = NULL;
9996
9997     pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9998     pic16_addpBlock(pb);
9999
10000 #if 0
10001     /* if debug information required */
10002     if (options.debug && currFunc) {
10003       if (currFunc) {
10004         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10005         _G.debugLine = 1;
10006         if (IS_STATIC(currFunc->etype)) {
10007           pic16_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
10008           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10009         } else {
10010           pic16_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
10011           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10012         }
10013         _G.debugLine = 0;
10014       }
10015     }
10016 #endif
10017
10018 //    dumpiCode(lic);
10019
10020     for (ic = lic ; ic ; ic = ic->next ) {
10021
10022 //      fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10023 //      DEBUGpic16_emitcode("; VR", "");
10024       DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10025         if ( cln != ic->lineno ) {
10026             if ( options.debug ) {
10027                 _G.debugLine = 1;
10028                 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10029                          FileBaseName(ic->filename),ic->lineno,
10030                          ic->level,ic->block);
10031                 _G.debugLine = 0;
10032             }
10033             /*
10034               pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10035               pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
10036               printCLine(ic->filename, ic->lineno));
10037             */
10038             pic16_addpCode2pBlock(pb,
10039                             pic16_newpCodeCSource(ic->lineno, 
10040                                             ic->filename, 
10041                                             printCLine(ic->filename, ic->lineno)));
10042
10043             cln = ic->lineno ;
10044         }
10045         /* if the result is marked as
10046            spilt and rematerializable or code for
10047            this has already been generated then
10048            do nothing */
10049         if (resultRemat(ic) || ic->generated ) 
10050             continue ;
10051         
10052         /* depending on the operation */
10053         switch (ic->op) {
10054         case '!' :
10055             genNot(ic);
10056             break;
10057             
10058         case '~' :
10059             genCpl(ic);
10060             break;
10061             
10062         case UNARYMINUS:
10063             genUminus (ic);
10064             break;
10065             
10066         case IPUSH:
10067             genIpush (ic);
10068             break;
10069             
10070         case IPOP:
10071             /* IPOP happens only when trying to restore a 
10072                spilt live range, if there is an ifx statement
10073                following this pop then the if statement might
10074                be using some of the registers being popped which
10075                would destroy the contents of the register so
10076                we need to check for this condition and handle it */
10077             if (ic->next            && 
10078                 ic->next->op == IFX &&
10079                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10080                 genIfx (ic->next,ic);
10081             else
10082                 genIpop (ic);
10083             break; 
10084             
10085         case CALL:
10086             genCall (ic);
10087             break;
10088             
10089         case PCALL:
10090             genPcall (ic);
10091             break;
10092             
10093         case FUNCTION:
10094             genFunction (ic);
10095             break;
10096             
10097         case ENDFUNCTION:
10098             genEndFunction (ic);
10099             break;
10100             
10101         case RETURN:
10102             genRet (ic);
10103             break;
10104             
10105         case LABEL:
10106             genLabel (ic);
10107             break;
10108             
10109         case GOTO:
10110             genGoto (ic);
10111             break;
10112             
10113         case '+' :
10114             pic16_genPlus (ic) ;
10115             break;
10116             
10117         case '-' :
10118             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10119                 pic16_genMinus (ic);
10120             break;
10121             
10122         case '*' :
10123             genMult (ic);
10124             break;
10125             
10126         case '/' :
10127             genDiv (ic) ;
10128             break;
10129             
10130         case '%' :
10131             genMod (ic);
10132             break;
10133             
10134         case '>' :
10135             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10136             break;
10137             
10138         case '<' :
10139             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10140             break;
10141             
10142         case LE_OP:
10143         case GE_OP:
10144         case NE_OP:
10145             
10146             /* note these two are xlated by algebraic equivalence
10147                during parsing SDCC.y */
10148             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10149                    "got '>=' or '<=' shouldn't have come here");
10150             break;      
10151             
10152         case EQ_OP:
10153             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10154             break;          
10155             
10156         case AND_OP:
10157             genAndOp (ic);
10158             break;
10159             
10160         case OR_OP:
10161             genOrOp (ic);
10162             break;
10163             
10164         case '^' :
10165             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10166             break;
10167             
10168         case '|' :
10169                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10170             break;
10171             
10172         case BITWISEAND:
10173             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10174             break;
10175             
10176         case INLINEASM:
10177             genInline (ic);
10178             break;
10179             
10180         case RRC:
10181             genRRC (ic);
10182             break;
10183             
10184         case RLC:
10185             genRLC (ic);
10186             break;
10187             
10188         case GETHBIT:
10189             genGetHbit (ic);
10190             break;
10191             
10192         case LEFT_OP:
10193             genLeftShift (ic);
10194             break;
10195             
10196         case RIGHT_OP:
10197             genRightShift (ic);
10198             break;
10199             
10200         case GET_VALUE_AT_ADDRESS:
10201             genPointerGet(ic);
10202             break;
10203             
10204         case '=' :
10205             if (POINTER_SET(ic))
10206                 genPointerSet(ic);
10207             else
10208                 genAssign(ic);
10209             break;
10210             
10211         case IFX:
10212             genIfx (ic,NULL);
10213             break;
10214             
10215         case ADDRESS_OF:
10216             genAddrOf (ic);
10217             break;
10218             
10219         case JUMPTABLE:
10220             genJumpTab (ic);
10221             break;
10222             
10223         case CAST:
10224             genCast (ic);
10225             break;
10226             
10227         case RECEIVE:
10228             genReceive(ic);
10229             break;
10230             
10231         case SEND:
10232             addSet(&_G.sendSet,ic);
10233             break;
10234
10235         case DUMMY_READ_VOLATILE:
10236           genDummyRead (ic);
10237           break;
10238
10239         default :
10240             ic = ic;
10241         }
10242     }
10243
10244
10245     /* now we are ready to call the
10246        peep hole optimizer */
10247     if (!options.nopeep) {
10248       peepHole (&lineHead);
10249     }
10250     /* now do the actual printing */
10251     printLine (lineHead,codeOutFile);
10252
10253 #ifdef PCODE_DEBUG
10254     DFPRINTF((stderr,"printing pBlock\n\n"));
10255     pic16_printpBlock(stdout,pb);
10256 #endif
10257
10258     return;
10259 }
10260