Changed the type of the result of the ! (NOT) operator to char;
[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 #if 0
1733 /*-----------------------------------------------------------------*/
1734 /* opIsGptr: returns non-zero if the passed operand is             */   
1735 /* a generic pointer type.                                         */
1736 /*-----------------------------------------------------------------*/ 
1737 static int opIsGptr(operand *op)
1738 {
1739     sym_link *type = operandType(op);
1740     
1741     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1742     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1743     {
1744         return 1;
1745     }
1746     return 0;        
1747 }
1748 #endif
1749
1750 /*-----------------------------------------------------------------*/
1751 /* pic16_getDataSize - get the operand data size                         */
1752 /*-----------------------------------------------------------------*/
1753 int pic16_getDataSize(operand *op)
1754 {
1755     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1756
1757
1758     return AOP_SIZE(op);
1759
1760     // tsd- in the pic port, the genptr size is 1, so this code here
1761     // fails. ( in the 8051 port, the size was 4).
1762 #if 0
1763     int size;
1764     size = AOP_SIZE(op);
1765     if (size == GPTRSIZE)
1766     {
1767         sym_link *type = operandType(op);
1768         if (IS_GENPTR(type))
1769         {
1770             /* generic pointer; arithmetic operations
1771              * should ignore the high byte (pointer type).
1772              */
1773             size--;
1774     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1775         }
1776     }
1777     return size;
1778 #endif
1779 }
1780
1781 /*-----------------------------------------------------------------*/
1782 /* pic16_outAcc - output Acc                                             */
1783 /*-----------------------------------------------------------------*/
1784 void pic16_outAcc(operand *result)
1785 {
1786   int size,offset;
1787   DEBUGpic16_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1788   DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1789
1790
1791   size = pic16_getDataSize(result);
1792   if(size){
1793     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1794     size--;
1795     offset = 1;
1796     /* unsigned or positive */
1797     while(size--)
1798       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1799   }
1800
1801 }
1802
1803 /*-----------------------------------------------------------------*/
1804 /* pic16_outBitC - output a bit C                                        */
1805 /*-----------------------------------------------------------------*/
1806 void pic16_outBitC(operand *result)
1807 {
1808
1809     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1810     /* if the result is bit */
1811     if (AOP_TYPE(result) == AOP_CRY) 
1812         pic16_aopPut(AOP(result),"c",0);
1813     else {
1814         pic16_emitcode("clr","a  ; %d", __LINE__);
1815         pic16_emitcode("rlc","a");
1816         pic16_outAcc(result);
1817     }
1818 }
1819
1820 /*-----------------------------------------------------------------*/
1821 /* pic16_toBoolean - emit code for orl a,operator(sizeop)                */
1822 /*-----------------------------------------------------------------*/
1823 void pic16_toBoolean(operand *oper)
1824 {
1825     int size = AOP_SIZE(oper) - 1;
1826     int offset = 1;
1827
1828     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1829
1830     if ( AOP_TYPE(oper) != AOP_ACC) {
1831       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1832     }
1833     while (size--) {
1834       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1835     }
1836 }
1837
1838
1839 /*-----------------------------------------------------------------*/
1840 /* genNot - generate code for ! operation                          */
1841 /*-----------------------------------------------------------------*/
1842 static void genNot (iCode *ic)
1843 {
1844   symbol *tlbl;
1845   int size;
1846
1847   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1848   /* assign asmOps to operand & result */
1849   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1850   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1851
1852   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1853   /* if in bit space then a special case */
1854   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1855     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1856       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1857       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1858     } else {
1859       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1860       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1861       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1862     }
1863     goto release;
1864   }
1865
1866   size = AOP_SIZE(IC_LEFT(ic));
1867   if(size == 1) {
1868     pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1869     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1870     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1871     goto release;
1872   }
1873   pic16_toBoolean(IC_LEFT(ic));
1874
1875   tlbl = newiTempLabel(NULL);
1876   pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1877   pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1878   pic16_outBitC(IC_RESULT(ic));
1879
1880  release:    
1881   /* release the aops */
1882   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1883   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1884 }
1885
1886
1887 /*-----------------------------------------------------------------*/
1888 /* genCpl - generate code for complement                           */
1889 /*-----------------------------------------------------------------*/
1890 static void genCpl (iCode *ic)
1891 {
1892     int offset = 0;
1893     int size ;
1894
1895
1896     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1897     /* assign asmOps to operand & result */
1898     pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1899     pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1900
1901     /* if both are in bit space then 
1902     a special case */
1903     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1904         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1905
1906         pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1907         pic16_emitcode("cpl","c"); 
1908         pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1909         goto release; 
1910     } 
1911
1912     size = AOP_SIZE(IC_RESULT(ic));
1913     while (size--) {
1914 /*
1915         char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1916         MOVA(l);       
1917         pic16_emitcode("cpl","a");
1918         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1919 */
1920         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1921               pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
1922         } else {
1923                 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1924                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1925         }
1926         offset++;
1927
1928     }
1929
1930
1931 release:
1932     /* release the aops */
1933     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1934     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1935 }
1936
1937 /*-----------------------------------------------------------------*/
1938 /* genUminusFloat - unary minus for floating points                */
1939 /*-----------------------------------------------------------------*/
1940 static void genUminusFloat(operand *op,operand *result)
1941 {
1942     int size ,offset =0 ;
1943     char *l;
1944
1945     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1946     /* for this we just need to flip the 
1947     first it then copy the rest in place */
1948     size = AOP_SIZE(op) - 1;
1949     l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1950
1951     MOVA(l);    
1952
1953     pic16_emitcode("cpl","acc.7");
1954     pic16_aopPut(AOP(result),"a",3);    
1955
1956     while(size--) {
1957         pic16_aopPut(AOP(result),
1958                pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1959                offset);
1960         offset++;
1961     }          
1962 }
1963
1964 /*-----------------------------------------------------------------*/
1965 /* genUminus - unary minus code generation                         */
1966 /*-----------------------------------------------------------------*/
1967 static void genUminus (iCode *ic)
1968 {
1969   int size, i;
1970   sym_link *optype, *rtype;
1971
1972
1973   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1974   /* assign asmops */
1975   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1976   pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1977
1978   /* if both in bit space then special
1979      case */
1980   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1981       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1982
1983     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1984     pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1985     pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1986
1987     goto release; 
1988   } 
1989
1990   optype = operandType(IC_LEFT(ic));
1991   rtype = operandType(IC_RESULT(ic));
1992
1993   /* if float then do float stuff */
1994   if (IS_FLOAT(optype)) {
1995     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1996     goto release;
1997   }
1998
1999   /* otherwise subtract from zero by taking the 2's complement */
2000   size = AOP_SIZE(IC_LEFT(ic));
2001
2002   for(i=0; i<size; i++) {
2003     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2004       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
2005     else {
2006       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2007       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2008     }
2009   }
2010
2011   pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
2012   for(i=1; i<size; i++) {
2013     emitSKPNZ;
2014     pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
2015   }
2016
2017  release:
2018   /* release the aops */
2019   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2020   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2021 }
2022
2023 /*-----------------------------------------------------------------*/
2024 /* saveRegisters - will look for a call and save the registers     */
2025 /*-----------------------------------------------------------------*/
2026 static void saveRegisters(iCode *lic) 
2027 {
2028     int i;
2029     iCode *ic;
2030     bitVect *rsave;
2031     sym_link *dtype;
2032
2033     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2034     /* look for call */
2035     for (ic = lic ; ic ; ic = ic->next) 
2036         if (ic->op == CALL || ic->op == PCALL)
2037             break;
2038
2039     if (!ic) {
2040         fprintf(stderr,"found parameter push with no function call\n");
2041         return ;
2042     }
2043
2044     /* if the registers have been saved already then
2045     do nothing */
2046     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2047         return ;
2048
2049     /* find the registers in use at this time 
2050     and push them away to safety */
2051     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2052                           ic->rUsed);
2053
2054     ic->regsSaved = 1;
2055     if (options.useXstack) {
2056         if (bitVectBitValue(rsave,R0_IDX))
2057             pic16_emitcode("mov","b,r0");
2058         pic16_emitcode("mov","r0,%s",spname);
2059         for (i = 0 ; i < pic16_nRegs ; i++) {
2060             if (bitVectBitValue(rsave,i)) {
2061                 if (i == R0_IDX)
2062                     pic16_emitcode("mov","a,b");
2063                 else
2064                     pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2065                 pic16_emitcode("movx","@r0,a");
2066                 pic16_emitcode("inc","r0");
2067             }
2068         }
2069         pic16_emitcode("mov","%s,r0",spname);
2070         if (bitVectBitValue(rsave,R0_IDX))
2071             pic16_emitcode("mov","r0,b");           
2072     }// else
2073     //for (i = 0 ; i < pic16_nRegs ; i++) {
2074     //    if (bitVectBitValue(rsave,i))
2075     //  pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2076     //}
2077
2078     dtype = operandType(IC_LEFT(ic));
2079     if (currFunc && dtype && 
2080         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2081         IFFUNC_ISISR(currFunc->type) &&
2082         !ic->bankSaved) 
2083
2084         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2085
2086 }
2087 /*-----------------------------------------------------------------*/
2088 /* unsaveRegisters - pop the pushed registers                      */
2089 /*-----------------------------------------------------------------*/
2090 static void unsaveRegisters (iCode *ic)
2091 {
2092     int i;
2093     bitVect *rsave;
2094
2095     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2096     /* find the registers in use at this time 
2097     and push them away to safety */
2098     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2099                           ic->rUsed);
2100     
2101     if (options.useXstack) {
2102         pic16_emitcode("mov","r0,%s",spname);   
2103         for (i =  pic16_nRegs ; i >= 0 ; i--) {
2104             if (bitVectBitValue(rsave,i)) {
2105                 pic16_emitcode("dec","r0");
2106                 pic16_emitcode("movx","a,@r0");
2107                 if (i == R0_IDX)
2108                     pic16_emitcode("mov","b,a");
2109                 else
2110                     pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2111             }       
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 =  pic16_nRegs ; i >= 0 ; i--) {
2119     //    if (bitVectBitValue(rsave,i))
2120     //  pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2121     //}
2122
2123 }  
2124
2125
2126 /*-----------------------------------------------------------------*/
2127 /* pushSide -                                                      */
2128 /*-----------------------------------------------------------------*/
2129 static void pushSide(operand * oper, int size)
2130 {
2131 #if 0
2132         int offset = 0;
2133     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2134         while (size--) {
2135                 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2136                 if (AOP_TYPE(oper) != AOP_REG &&
2137                     AOP_TYPE(oper) != AOP_DIR &&
2138                     strcmp(l,"a") ) {
2139                         pic16_emitcode("mov","a,%s",l);
2140                         pic16_emitcode("push","acc");
2141                 } else
2142                         pic16_emitcode("push","%s",l);
2143         }
2144 #endif
2145 }
2146
2147 /*-----------------------------------------------------------------*/
2148 /* assignResultValue -                                             */
2149 /*-----------------------------------------------------------------*/
2150 static void assignResultValue(operand * oper)
2151 {
2152   int size = AOP_SIZE(oper);
2153
2154   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2155
2156   DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2157
2158   if(!GpsuedoStkPtr) {
2159     /* The last byte in the assignment is in W */
2160     size--;
2161     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2162     GpsuedoStkPtr++;
2163   }
2164
2165   while (size--) {
2166     pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2167     GpsuedoStkPtr++;
2168     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2169   }
2170 }
2171
2172
2173 /*-----------------------------------------------------------------*/
2174 /* genIpush - genrate code for pushing this gets a little complex  */
2175 /*-----------------------------------------------------------------*/
2176 static void genIpush (iCode *ic)
2177 {
2178
2179   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2180 #if 0
2181     int size, offset = 0 ;
2182     char *l;
2183
2184
2185     /* if this is not a parm push : ie. it is spill push 
2186     and spill push is always done on the local stack */
2187     if (!ic->parmPush) {
2188
2189         /* and the item is spilt then do nothing */
2190         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2191             return ;
2192
2193         pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2194         size = AOP_SIZE(IC_LEFT(ic));
2195         /* push it on the stack */
2196         while(size--) {
2197             l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2198             if (*l == '#') {
2199                 MOVA(l);
2200                 l = "acc";
2201             }
2202             pic16_emitcode("push","%s",l);
2203         }
2204         return ;        
2205     }
2206
2207     /* this is a paramter push: in this case we call
2208     the routine to find the call and save those
2209     registers that need to be saved */   
2210     saveRegisters(ic);
2211
2212     /* then do the push */
2213     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2214
2215
2216         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2217     size = AOP_SIZE(IC_LEFT(ic));
2218
2219     while (size--) {
2220         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2221         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2222             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2223             strcmp(l,"a") ) {
2224             pic16_emitcode("mov","a,%s",l);
2225             pic16_emitcode("push","acc");
2226         } else
2227             pic16_emitcode("push","%s",l);
2228     }       
2229
2230     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2231 #endif
2232 }
2233
2234 /*-----------------------------------------------------------------*/
2235 /* genIpop - recover the registers: can happen only for spilling   */
2236 /*-----------------------------------------------------------------*/
2237 static void genIpop (iCode *ic)
2238 {
2239   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2240 #if 0
2241     int size,offset ;
2242
2243
2244     /* if the temp was not pushed then */
2245     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2246         return ;
2247
2248     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2249     size = AOP_SIZE(IC_LEFT(ic));
2250     offset = (size-1);
2251     while (size--) 
2252         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2253                                    FALSE,TRUE));
2254
2255     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2256 #endif
2257 }
2258
2259 /*-----------------------------------------------------------------*/
2260 /* unsaverbank - restores the resgister bank from stack            */
2261 /*-----------------------------------------------------------------*/
2262 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2263 {
2264   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2265 #if 0
2266     int i;
2267     asmop *aop ;
2268     regs *r = NULL;
2269
2270     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2271     if (popPsw) {
2272         if (options.useXstack) {
2273             aop = newAsmop(0);
2274             r = getFreePtr(ic,&aop,FALSE);
2275             
2276             
2277             pic16_emitcode("mov","%s,_spx",r->name);
2278             pic16_emitcode("movx","a,@%s",r->name);
2279             pic16_emitcode("mov","psw,a");
2280             pic16_emitcode("dec","%s",r->name);
2281             
2282         }else
2283             pic16_emitcode ("pop","psw");
2284     }
2285
2286     for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2287         if (options.useXstack) {       
2288             pic16_emitcode("movx","a,@%s",r->name);
2289             //pic16_emitcode("mov","(%s+%d),a",
2290             //       regspic16[i].base,8*bank+regspic16[i].offset);
2291             pic16_emitcode("dec","%s",r->name);
2292
2293         } else 
2294           pic16_emitcode("pop",""); //"(%s+%d)",
2295         //regspic16[i].base,8*bank); //+regspic16[i].offset);
2296     }
2297
2298     if (options.useXstack) {
2299
2300         pic16_emitcode("mov","_spx,%s",r->name);
2301         pic16_freeAsmop(NULL,aop,ic,TRUE);
2302
2303     }
2304 #endif 
2305 }
2306
2307 /*-----------------------------------------------------------------*/
2308 /* saverbank - saves an entire register bank on the stack          */
2309 /*-----------------------------------------------------------------*/
2310 static void saverbank (int bank, iCode *ic, bool pushPsw)
2311 {
2312   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2313 #if 0
2314     int i;
2315     asmop *aop ;
2316     regs *r = NULL;
2317
2318     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2319     if (options.useXstack) {
2320
2321         aop = newAsmop(0);
2322         r = getFreePtr(ic,&aop,FALSE);  
2323         pic16_emitcode("mov","%s,_spx",r->name);
2324
2325     }
2326
2327     for (i = 0 ; i < pic16_nRegs ;i++) {
2328         if (options.useXstack) {
2329             pic16_emitcode("inc","%s",r->name);
2330             //pic16_emitcode("mov","a,(%s+%d)",
2331             //         regspic16[i].base,8*bank+regspic16[i].offset);
2332             pic16_emitcode("movx","@%s,a",r->name);           
2333         } else 
2334           pic16_emitcode("push","");// "(%s+%d)",
2335                      //regspic16[i].base,8*bank+regspic16[i].offset);
2336     }
2337     
2338     if (pushPsw) {
2339         if (options.useXstack) {
2340             pic16_emitcode("mov","a,psw");
2341             pic16_emitcode("movx","@%s,a",r->name);     
2342             pic16_emitcode("inc","%s",r->name);
2343             pic16_emitcode("mov","_spx,%s",r->name);       
2344             pic16_freeAsmop (NULL,aop,ic,TRUE);
2345             
2346         } else
2347             pic16_emitcode("push","psw");
2348         
2349         pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2350     }
2351     ic->bankSaved = 1;
2352 #endif
2353 }
2354
2355 /*-----------------------------------------------------------------*/
2356 /* genCall - generates a call statement                            */
2357 /*-----------------------------------------------------------------*/
2358 static void genCall (iCode *ic)
2359 {
2360   sym_link *dtype;   
2361
2362   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2363
2364   /* if caller saves & we have not saved then */
2365   if (!ic->regsSaved)
2366     saveRegisters(ic);
2367
2368   /* if we are calling a function that is not using
2369      the same register bank then we need to save the
2370      destination registers on the stack */
2371   dtype = operandType(IC_LEFT(ic));
2372   if (currFunc && dtype && 
2373       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2374       IFFUNC_ISISR(currFunc->type) &&
2375       !ic->bankSaved) 
2376
2377     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2378
2379   /* if send set is not empty the assign */
2380   if (_G.sendSet) {
2381     iCode *sic;
2382     /* For the Pic port, there is no data stack.
2383      * So parameters passed to functions are stored
2384      * in registers. (The pCode optimizer will get
2385      * rid of most of these :).
2386      */
2387     int psuedoStkPtr=-1; 
2388     int firstTimeThruLoop = 1;
2389
2390     _G.sendSet = reverseSet(_G.sendSet);
2391
2392     /* First figure how many parameters are getting passed */
2393     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2394          sic = setNextItem(_G.sendSet)) {
2395
2396       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2397       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2398       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2399     }
2400
2401     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2402          sic = setNextItem(_G.sendSet)) {
2403       int size, offset = 0;
2404
2405       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2406       size = AOP_SIZE(IC_LEFT(sic));
2407
2408       while (size--) {
2409         DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2410                              pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2411
2412         if(!firstTimeThruLoop) {
2413           /* If this is not the first time we've been through the loop
2414            * then we need to save the parameter in a temporary
2415            * register. The last byte of the last parameter is
2416            * passed in W. */
2417           pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2418
2419         }
2420         firstTimeThruLoop=0;
2421
2422         //if (strcmp(l,fReturn[offset])) {
2423         mov2w (AOP(IC_LEFT(sic)),  offset);
2424 /*
2425         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2426              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2427           pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2428         else
2429           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2430 */
2431         //}
2432         offset++;
2433       }
2434       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2435     }
2436     _G.sendSet = NULL;
2437   }
2438   /* make the call */
2439   pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2440                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2441                                       OP_SYMBOL(IC_LEFT(ic))->name));
2442
2443   GpsuedoStkPtr=0;
2444   /* if we need assign a result value */
2445   if ((IS_ITEMP(IC_RESULT(ic)) && 
2446        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2447         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2448       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2449
2450     _G.accInUse++;
2451     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2452     _G.accInUse--;
2453
2454     assignResultValue(IC_RESULT(ic));
2455
2456     DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2457                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2458                 
2459     pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2460   }
2461
2462   /* adjust the stack for parameters if 
2463      required */
2464   if (ic->parmBytes) {
2465     int i;
2466     if (ic->parmBytes > 3) {
2467       pic16_emitcode("mov","a,%s",spname);
2468       pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2469       pic16_emitcode("mov","%s,a",spname);
2470     } else 
2471       for ( i = 0 ; i <  ic->parmBytes ;i++)
2472         pic16_emitcode("dec","%s",spname);
2473
2474   }
2475
2476   /* if register bank was saved then pop them */
2477   if (ic->bankSaved)
2478     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2479
2480   /* if we hade saved some registers then unsave them */
2481   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2482     unsaveRegisters (ic);
2483
2484
2485 }
2486
2487 /*-----------------------------------------------------------------*/
2488 /* genPcall - generates a call by pointer statement                */
2489 /*-----------------------------------------------------------------*/
2490 static void genPcall (iCode *ic)
2491 {
2492     sym_link *dtype;
2493     symbol *rlbl = newiTempLabel(NULL);
2494
2495
2496     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2497     /* if caller saves & we have not saved then */
2498     if (!ic->regsSaved)
2499         saveRegisters(ic);
2500
2501     /* if we are calling a function that is not using
2502     the same register bank then we need to save the
2503     destination registers on the stack */
2504     dtype = operandType(IC_LEFT(ic));
2505     if (currFunc && dtype && 
2506         IFFUNC_ISISR(currFunc->type) &&
2507         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2508         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2509
2510
2511     /* push the return address on to the stack */
2512     pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2513     pic16_emitcode("push","acc");    
2514     pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2515     pic16_emitcode("push","acc");
2516     
2517     if (options.model == MODEL_FLAT24)
2518     {
2519         pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2520         pic16_emitcode("push","acc");    
2521     }
2522
2523     /* now push the calling address */
2524     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2525
2526     pushSide(IC_LEFT(ic), FPTRSIZE);
2527
2528     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2529
2530     /* if send set is not empty the assign */
2531     if (_G.sendSet) {
2532         iCode *sic ;
2533
2534         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2535              sic = setNextItem(_G.sendSet)) {
2536             int size, offset = 0;
2537             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2538             size = AOP_SIZE(IC_LEFT(sic));
2539             while (size--) {
2540                 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2541                                 FALSE,FALSE);
2542                 if (strcmp(l,fReturn[offset]))
2543                     pic16_emitcode("mov","%s,%s",
2544                              fReturn[offset],
2545                              l);
2546                 offset++;
2547             }
2548             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2549         }
2550         _G.sendSet = NULL;
2551     }
2552
2553     pic16_emitcode("ret","");
2554     pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2555
2556
2557     /* if we need assign a result value */
2558     if ((IS_ITEMP(IC_RESULT(ic)) &&
2559          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2560           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2561         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2562
2563         _G.accInUse++;
2564         pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2565         _G.accInUse--;
2566         
2567         assignResultValue(IC_RESULT(ic));
2568
2569         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2570     }
2571
2572     /* adjust the stack for parameters if 
2573     required */
2574     if (ic->parmBytes) {
2575         int i;
2576         if (ic->parmBytes > 3) {
2577             pic16_emitcode("mov","a,%s",spname);
2578             pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2579             pic16_emitcode("mov","%s,a",spname);
2580         } else 
2581             for ( i = 0 ; i <  ic->parmBytes ;i++)
2582                 pic16_emitcode("dec","%s",spname);
2583
2584     }
2585
2586     /* if register bank was saved then unsave them */
2587     if (currFunc && dtype && 
2588         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2589         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2590
2591     /* if we hade saved some registers then
2592     unsave them */
2593     if (ic->regsSaved)
2594         unsaveRegisters (ic);
2595
2596 }
2597
2598 /*-----------------------------------------------------------------*/
2599 /* resultRemat - result  is rematerializable                       */
2600 /*-----------------------------------------------------------------*/
2601 static int resultRemat (iCode *ic)
2602 {
2603   //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2604   if (SKIP_IC(ic) || ic->op == IFX)
2605     return 0;
2606
2607   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2608     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2609     if (sym->remat && !POINTER_SET(ic)) 
2610       return 1;
2611   }
2612
2613   return 0;
2614 }
2615
2616 #if defined(__BORLANDC__) || defined(_MSC_VER)
2617 #define STRCASECMP stricmp
2618 #else
2619 #define STRCASECMP strcasecmp
2620 #endif
2621
2622 #if 0
2623 /*-----------------------------------------------------------------*/
2624 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2625 /*-----------------------------------------------------------------*/
2626 static bool inExcludeList(char *s)
2627 {
2628   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2629     int i =0;
2630     
2631     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2632     if (options.excludeRegs[i] &&
2633     STRCASECMP(options.excludeRegs[i],"none") == 0)
2634         return FALSE ;
2635
2636     for ( i = 0 ; options.excludeRegs[i]; i++) {
2637         if (options.excludeRegs[i] &&
2638         STRCASECMP(s,options.excludeRegs[i]) == 0)
2639             return TRUE;
2640     }
2641     return FALSE ;
2642 }
2643 #endif
2644
2645 /*-----------------------------------------------------------------*/
2646 /* genFunction - generated code for function entry                 */
2647 /*-----------------------------------------------------------------*/
2648 static void genFunction (iCode *ic)
2649 {
2650     symbol *sym;
2651     sym_link *ftype;
2652
2653     DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2654
2655     labelOffset += (max_key+4);
2656     max_key=0;
2657     GpsuedoStkPtr=0;
2658     _G.nRegsSaved = 0;
2659     /* create the function header */
2660     pic16_emitcode(";","-----------------------------------------");
2661     pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2662     pic16_emitcode(";","-----------------------------------------");
2663
2664     pic16_emitcode("","%s:",sym->rname);
2665     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2666
2667     ftype = operandType(IC_LEFT(ic));
2668
2669     /* if critical function then turn interrupts off */
2670     if (IFFUNC_ISCRITICAL(ftype))
2671         pic16_emitcode("clr","ea");
2672
2673     /* here we need to generate the equates for the
2674        register bank if required */
2675 #if 0
2676     if (FUNC_REGBANK(ftype) != rbank) {
2677         int i ;
2678
2679         rbank = FUNC_REGBANK(ftype);
2680         for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2681             if (strcmp(regspic16[i].base,"0") == 0)
2682                 pic16_emitcode("","%s = 0x%02x",
2683                          regspic16[i].dname,
2684                          8*rbank+regspic16[i].offset);
2685             else
2686                 pic16_emitcode ("","%s = %s + 0x%02x",
2687                           regspic16[i].dname,
2688                           regspic16[i].base,
2689                           8*rbank+regspic16[i].offset);
2690         }
2691     }
2692 #endif
2693
2694     /* if this is an interrupt service routine then
2695     save acc, b, dpl, dph  */
2696     if (IFFUNC_ISISR(sym->type)) {
2697
2698 #if 0
2699         pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2700         
2701         /* what is the reason of having these 3 NOPS? VR - 030701 */
2702         pic16_emitpcodeNULLop(POC_NOP);
2703         pic16_emitpcodeNULLop(POC_NOP);
2704         pic16_emitpcodeNULLop(POC_NOP);
2705 #endif
2706
2707       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
2708       pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2709       pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2710       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
2711
2712       pic16_pBlockConvert2ISR(pb);
2713 #if 0  
2714         if (!inExcludeList("acc"))          
2715             pic16_emitcode ("push","acc");      
2716         if (!inExcludeList("b"))
2717             pic16_emitcode ("push","b");
2718         if (!inExcludeList("dpl"))
2719             pic16_emitcode ("push","dpl");
2720         if (!inExcludeList("dph"))
2721             pic16_emitcode ("push","dph");
2722         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2723         {
2724             pic16_emitcode ("push", "dpx");
2725             /* Make sure we're using standard DPTR */
2726             pic16_emitcode ("push", "dps");
2727             pic16_emitcode ("mov", "dps, #0x00");
2728             if (options.stack10bit)
2729             {   
2730                 /* This ISR could conceivably use DPTR2. Better save it. */
2731                 pic16_emitcode ("push", "dpl1");
2732                 pic16_emitcode ("push", "dph1");
2733                 pic16_emitcode ("push", "dpx1");
2734             }
2735         }
2736         /* if this isr has no bank i.e. is going to
2737            run with bank 0 , then we need to save more
2738            registers :-) */
2739         if (!FUNC_REGBANK(sym->type)) {
2740
2741             /* if this function does not call any other
2742                function then we can be economical and
2743                save only those registers that are used */
2744             if (! IFFUNC_HASFCALL(sym->type)) {
2745                 int i;
2746
2747                 /* if any registers used */
2748                 if (sym->regsUsed) {
2749                     /* save the registers used */
2750                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2751                         if (bitVectBitValue(sym->regsUsed,i) ||
2752                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753                           pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                         
2754                     }
2755                 }
2756                 
2757             } else {
2758                 /* this function has  a function call cannot
2759                    determines register usage so we will have the
2760                    entire bank */
2761                 saverbank(0,ic,FALSE);
2762             }       
2763         }
2764 #endif
2765     } else {
2766         /* if callee-save to be used for this function
2767            then save the registers being used in this function */
2768         if (IFFUNC_CALLEESAVES(sym->type)) {
2769             int i;
2770             
2771             /* if any registers used */
2772             if (sym->regsUsed) {
2773                 /* save the registers used */
2774                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2775                     if (bitVectBitValue(sym->regsUsed,i) ||
2776                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2777                       //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2778                         _G.nRegsSaved++;
2779                     }
2780                 }
2781             }
2782         }
2783     }
2784
2785     /* set the register bank to the desired value */
2786     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2787         pic16_emitcode("push","psw");
2788         pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2789     }
2790
2791     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2792
2793         if (options.useXstack) {
2794             pic16_emitcode("mov","r0,%s",spname);
2795             pic16_emitcode("mov","a,_bp");
2796             pic16_emitcode("movx","@r0,a");
2797             pic16_emitcode("inc","%s",spname);
2798         }
2799         else
2800         {
2801             /* set up the stack */
2802             pic16_emitcode ("push","_bp");     /* save the callers stack  */
2803         }
2804         pic16_emitcode ("mov","_bp,%s",spname);
2805     }
2806
2807     /* adjust the stack for the function */
2808     if (sym->stack) {
2809
2810         int i = sym->stack;
2811         if (i > 256 ) 
2812             werror(W_STACK_OVERFLOW,sym->name);
2813
2814         if (i > 3 && sym->recvSize < 4) {              
2815
2816             pic16_emitcode ("mov","a,sp");
2817             pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2818             pic16_emitcode ("mov","sp,a");
2819            
2820         }
2821         else
2822             while(i--)
2823                 pic16_emitcode("inc","sp");
2824     }
2825
2826      if (sym->xstack) {
2827
2828         pic16_emitcode ("mov","a,_spx");
2829         pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2830         pic16_emitcode ("mov","_spx,a");
2831     }    
2832
2833 }
2834
2835 /*-----------------------------------------------------------------*/
2836 /* genEndFunction - generates epilogue for functions               */
2837 /*-----------------------------------------------------------------*/
2838 static void genEndFunction (iCode *ic)
2839 {
2840     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2841
2842     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2843
2844     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2845     {
2846         pic16_emitcode ("mov","%s,_bp",spname);
2847     }
2848
2849     /* if use external stack but some variables were
2850     added to the local stack then decrement the
2851     local stack */
2852     if (options.useXstack && sym->stack) {      
2853         pic16_emitcode("mov","a,sp");
2854         pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2855         pic16_emitcode("mov","sp,a");
2856     }
2857
2858
2859     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2860         if (options.useXstack) {
2861             pic16_emitcode("mov","r0,%s",spname);
2862             pic16_emitcode("movx","a,@r0");
2863             pic16_emitcode("mov","_bp,a");
2864             pic16_emitcode("dec","%s",spname);
2865         }
2866         else
2867         {
2868             pic16_emitcode ("pop","_bp");
2869         }
2870     }
2871
2872     /* restore the register bank  */    
2873     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2874         pic16_emitcode ("pop","psw");
2875
2876     if (IFFUNC_ISISR(sym->type)) {
2877
2878         /* now we need to restore the registers */
2879         /* if this isr has no bank i.e. is going to
2880            run with bank 0 , then we need to save more
2881            registers :-) */
2882         if (!FUNC_REGBANK(sym->type)) {
2883             
2884             /* if this function does not call any other
2885                function then we can be economical and
2886                save only those registers that are used */
2887             if (! IFFUNC_HASFCALL(sym->type)) {
2888                 int i;
2889                 
2890                 /* if any registers used */
2891                 if (sym->regsUsed) {
2892                     /* save the registers used */
2893                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2894                         if (bitVectBitValue(sym->regsUsed,i) ||
2895                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2896                           pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2897                     }
2898                 }
2899                 
2900             } else {
2901                 /* this function has  a function call cannot
2902                    determines register usage so we will have the
2903                    entire bank */
2904                 unsaverbank(0,ic,FALSE);
2905             }       
2906         }
2907 #if 0
2908         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2909         {
2910             if (options.stack10bit)
2911             {
2912                 pic16_emitcode ("pop", "dpx1");
2913                 pic16_emitcode ("pop", "dph1");
2914                 pic16_emitcode ("pop", "dpl1");
2915             }   
2916             pic16_emitcode ("pop", "dps");
2917             pic16_emitcode ("pop", "dpx");
2918         }
2919         if (!inExcludeList("dph"))
2920             pic16_emitcode ("pop","dph");
2921         if (!inExcludeList("dpl"))
2922             pic16_emitcode ("pop","dpl");
2923         if (!inExcludeList("b"))
2924             pic16_emitcode ("pop","b");
2925         if (!inExcludeList("acc"))
2926             pic16_emitcode ("pop","acc");
2927
2928         if (IFFUNC_ISCRITICAL(sym->type))
2929             pic16_emitcode("setb","ea");
2930 #endif
2931
2932         /* if debug then send end of function */
2933 /*      if (options.debug && currFunc) { */
2934         if (currFunc) {
2935             _G.debugLine = 1;
2936             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2937                      FileBaseName(ic->filename),currFunc->lastLine,
2938                      ic->level,ic->block); 
2939             if (IS_STATIC(currFunc->etype))         
2940                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2941             else
2942                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2943             _G.debugLine = 0;
2944         }
2945         
2946 //      pic16_emitcode ("reti","");
2947
2948         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2949         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2950         pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
2951         pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
2952         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2953
2954 #if 0
2955         pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2956 #endif
2957
2958         pic16_emitpcodeNULLop(POC_RETFIE);
2959
2960     }
2961     else {
2962         if (IFFUNC_ISCRITICAL(sym->type))
2963             pic16_emitcode("setb","ea");
2964         
2965         if (IFFUNC_CALLEESAVES(sym->type)) {
2966             int i;
2967             
2968             /* if any registers used */
2969             if (sym->regsUsed) {
2970                 /* save the registers used */
2971                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2972                     if (bitVectBitValue(sym->regsUsed,i) ||
2973                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2974                       pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2975                 }
2976             }
2977             
2978         }
2979
2980         /* if debug then send end of function */
2981         if (currFunc) {
2982             _G.debugLine = 1;
2983             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2984                      FileBaseName(ic->filename),currFunc->lastLine,
2985                      ic->level,ic->block); 
2986             if (IS_STATIC(currFunc->etype))         
2987                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2988             else
2989                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2990             _G.debugLine = 0;
2991         }
2992
2993         pic16_emitcode ("return","");
2994         pic16_emitpcodeNULLop(POC_RETURN);
2995
2996         /* Mark the end of a function */
2997         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
2998     }
2999
3000 }
3001
3002 /*-----------------------------------------------------------------*/
3003 /* genRet - generate code for return statement                     */
3004 /*-----------------------------------------------------------------*/
3005 static void genRet (iCode *ic)
3006 {
3007   int size,offset = 0 , pushed = 0;
3008     
3009   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3010   /* if we have no return value then
3011      just generate the "ret" */
3012   if (!IC_LEFT(ic)) 
3013     goto jumpret;       
3014     
3015   /* we have something to return then
3016      move the return value into place */
3017   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3018   size = AOP_SIZE(IC_LEFT(ic));
3019     
3020   while (size--) {
3021     char *l ;
3022     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3023       /* #NOCHANGE */
3024       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3025                  FALSE,TRUE);
3026       pic16_emitcode("push","%s",l);
3027       pushed++;
3028     } else {
3029       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3030                  FALSE,FALSE);
3031       if (strcmp(fReturn[offset],l)) {
3032         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3033             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3034           pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3035         }else {
3036           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3037         }
3038         if(size) {
3039           pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3040         }
3041         offset++;
3042       }
3043     }
3044   }    
3045
3046   if (pushed) {
3047     while(pushed) {
3048       pushed--;
3049       if (strcmp(fReturn[pushed],"a"))
3050         pic16_emitcode("pop",fReturn[pushed]);
3051       else
3052         pic16_emitcode("pop","acc");
3053     }
3054   }
3055   pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3056     
3057  jumpret:
3058   /* generate a jump to the return label
3059      if the next is not the return statement */
3060   if (!(ic->next && ic->next->op == LABEL &&
3061         IC_LABEL(ic->next) == returnLabel)) {
3062         
3063     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3064     pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3065   }
3066     
3067 }
3068
3069 /*-----------------------------------------------------------------*/
3070 /* genLabel - generates a label                                    */
3071 /*-----------------------------------------------------------------*/
3072 static void genLabel (iCode *ic)
3073 {
3074     /* special case never generate */
3075     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3076     if (IC_LABEL(ic) == entryLabel)
3077         return ;
3078
3079     pic16_emitpLabel(IC_LABEL(ic)->key);
3080     pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3081 }
3082
3083 /*-----------------------------------------------------------------*/
3084 /* genGoto - generates a goto                                      */
3085 /*-----------------------------------------------------------------*/
3086 //tsd
3087 static void genGoto (iCode *ic)
3088 {
3089   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3090   pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3091 }
3092
3093
3094 /*-----------------------------------------------------------------*/
3095 /* genMultbits :- multiplication of bits                           */
3096 /*-----------------------------------------------------------------*/
3097 static void genMultbits (operand *left, 
3098                          operand *right, 
3099                          operand *result)
3100 {
3101   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3102
3103   if(!pic16_sameRegs(AOP(result),AOP(right)))
3104     pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),0));
3105
3106   pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3107   pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3108   pic16_emitpcode(POC_BCF,  pic16_popGet(AOP(result),0));
3109
3110 }
3111
3112
3113 /*-----------------------------------------------------------------*/
3114 /* genMultOneByte : 8 bit multiplication & division                */
3115 /*-----------------------------------------------------------------*/
3116 static void genMultOneByte (operand *left,
3117                             operand *right,
3118                             operand *result)
3119 {
3120   sym_link *opetype = operandType(result);
3121
3122   // symbol *lbl ;
3123   int size,offset;
3124
3125   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3126   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3127   DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3128
3129   /* (if two literals, the value is computed before) */
3130   /* if one literal, literal on the right */
3131   if (AOP_TYPE(left) == AOP_LIT){
3132     operand *t = right;
3133     right = left;
3134     left = t;
3135   }
3136
3137   size = AOP_SIZE(result);
3138   if(size == 1) {
3139
3140     if (AOP_TYPE(right) == AOP_LIT){
3141       pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3142                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3143                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3144                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3145       pic16_emitcode("call","genMultLit");
3146     } else {
3147       pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3148                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3149                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3150                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3151       pic16_emitcode("call","pic16_genMult8X8_8");
3152
3153     }
3154     pic16_genMult8X8_8 (left, right,result);
3155
3156
3157     /* signed or unsigned */
3158     //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3159     //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3160     //MOVA(l);       
3161     //pic16_emitcode("mul","ab");
3162     /* if result size = 1, mul signed = mul unsigned */
3163     //pic16_aopPut(AOP(result),"a",0);
3164
3165   } else {  // (size > 1)
3166
3167     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3168                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3169                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3170                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
3171
3172     if (SPEC_USIGN(opetype)){
3173       pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3174       pic16_genUMult8X8_16 (left, right, result, NULL);
3175
3176       if (size > 2) {
3177         /* for filling the MSBs */
3178         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),2));
3179         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),3));
3180       }
3181     }
3182     else{
3183       pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3184
3185       pic16_emitcode("mov","a,b");
3186
3187       /* adjust the MSB if left or right neg */
3188
3189       /* if one literal */
3190       if (AOP_TYPE(right) == AOP_LIT){
3191         pic16_emitcode("multiply ","right is a lit");
3192         /* AND literal negative */
3193         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3194           /* adjust MSB (c==0 after mul) */
3195           pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3196         }
3197       }
3198       else{
3199         pic16_genSMult8X8_16 (left, right, result, NULL);
3200       }
3201
3202       if(size > 2){
3203         pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3204         /* get the sign */
3205         pic16_emitcode("rlc","a");
3206         pic16_emitcode("subb","a,acc");
3207       }
3208     }
3209
3210     size -= 2;   
3211     offset = 2;
3212     if (size > 0)
3213       while (size--)
3214         pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3215     //pic16_aopPut(AOP(result),"a",offset++);
3216   }
3217 }
3218
3219 /*-----------------------------------------------------------------*/
3220 /* genMult - generates code for multiplication                     */
3221 /*-----------------------------------------------------------------*/
3222 static void genMult (iCode *ic)
3223 {
3224     operand *left = IC_LEFT(ic);
3225     operand *right = IC_RIGHT(ic);
3226     operand *result= IC_RESULT(ic);   
3227
3228     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3229     /* assign the amsops */
3230     pic16_aopOp (left,ic,FALSE);
3231     pic16_aopOp (right,ic,FALSE);
3232     pic16_aopOp (result,ic,TRUE);
3233
3234   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3235
3236     /* special cases first */
3237     /* both are bits */
3238     if (AOP_TYPE(left) == AOP_CRY &&
3239         AOP_TYPE(right)== AOP_CRY) {
3240         genMultbits(left,right,result);
3241         goto release ;
3242     }
3243
3244     /* if both are of size == 1 */
3245     if (AOP_SIZE(left) == 1 &&
3246         AOP_SIZE(right) == 1 ) {
3247         genMultOneByte(left,right,result);
3248         goto release ;
3249     }
3250
3251     pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3252
3253     /* should have been converted to function call */
3254     //assert(0) ;
3255
3256 release :
3257     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3259     pic16_freeAsmop(result,NULL,ic,TRUE); 
3260 }
3261
3262 /*-----------------------------------------------------------------*/
3263 /* genDivbits :- division of bits                                  */
3264 /*-----------------------------------------------------------------*/
3265 static void genDivbits (operand *left, 
3266                         operand *right, 
3267                         operand *result)
3268 {
3269
3270     char *l;
3271
3272     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3273     /* the result must be bit */    
3274     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3275     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3276
3277     MOVA(l);    
3278
3279     pic16_emitcode("div","ab");
3280     pic16_emitcode("rrc","a");
3281     pic16_aopPut(AOP(result),"c",0);
3282 }
3283
3284 /*-----------------------------------------------------------------*/
3285 /* genDivOneByte : 8 bit division                                  */
3286 /*-----------------------------------------------------------------*/
3287 static void genDivOneByte (operand *left,
3288                            operand *right,
3289                            operand *result)
3290 {
3291     sym_link *opetype = operandType(result);
3292     char *l ;
3293     symbol *lbl ;
3294     int size,offset;
3295
3296     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3297     size = AOP_SIZE(result) - 1;
3298     offset = 1;
3299     /* signed or unsigned */
3300     if (SPEC_USIGN(opetype)) {
3301         /* unsigned is easy */
3302         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3303         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3304         MOVA(l);        
3305         pic16_emitcode("div","ab");
3306         pic16_aopPut(AOP(result),"a",0);
3307         while (size--)
3308             pic16_aopPut(AOP(result),zero,offset++);
3309         return ;
3310     }
3311
3312     /* signed is a little bit more difficult */
3313
3314     /* save the signs of the operands */
3315     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3316     MOVA(l);    
3317     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3318     pic16_emitcode("push","acc"); /* save it on the stack */
3319
3320     /* now sign adjust for both left & right */
3321     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3322     MOVA(l);       
3323     lbl = newiTempLabel(NULL);
3324     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3325     pic16_emitcode("cpl","a");   
3326     pic16_emitcode("inc","a");
3327     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3328     pic16_emitcode("mov","b,a");
3329
3330     /* sign adjust left side */
3331     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3332     MOVA(l);
3333
3334     lbl = newiTempLabel(NULL);
3335     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3336     pic16_emitcode("cpl","a");
3337     pic16_emitcode("inc","a");
3338     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3339
3340     /* now the division */
3341     pic16_emitcode("div","ab");
3342     /* we are interested in the lower order
3343     only */
3344     pic16_emitcode("mov","b,a");
3345     lbl = newiTempLabel(NULL);
3346     pic16_emitcode("pop","acc");   
3347     /* if there was an over flow we don't 
3348     adjust the sign of the result */
3349     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3350     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3351     CLRC;
3352     pic16_emitcode("clr","a");
3353     pic16_emitcode("subb","a,b");
3354     pic16_emitcode("mov","b,a");
3355     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3356
3357     /* now we are done */
3358     pic16_aopPut(AOP(result),"b",0);
3359     if(size > 0){
3360         pic16_emitcode("mov","c,b.7");
3361         pic16_emitcode("subb","a,acc");   
3362     }
3363     while (size--)
3364         pic16_aopPut(AOP(result),"a",offset++);
3365
3366 }
3367
3368 /*-----------------------------------------------------------------*/
3369 /* genDiv - generates code for division                            */
3370 /*-----------------------------------------------------------------*/
3371 static void genDiv (iCode *ic)
3372 {
3373     operand *left = IC_LEFT(ic);
3374     operand *right = IC_RIGHT(ic);
3375     operand *result= IC_RESULT(ic);   
3376
3377     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3378     /* assign the amsops */
3379     pic16_aopOp (left,ic,FALSE);
3380     pic16_aopOp (right,ic,FALSE);
3381     pic16_aopOp (result,ic,TRUE);
3382
3383     /* special cases first */
3384     /* both are bits */
3385     if (AOP_TYPE(left) == AOP_CRY &&
3386         AOP_TYPE(right)== AOP_CRY) {
3387         genDivbits(left,right,result);
3388         goto release ;
3389     }
3390
3391     /* if both are of size == 1 */
3392     if (AOP_SIZE(left) == 1 &&
3393         AOP_SIZE(right) == 1 ) {
3394         genDivOneByte(left,right,result);
3395         goto release ;
3396     }
3397
3398     /* should have been converted to function call */
3399     assert(0);
3400 release :
3401     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3403     pic16_freeAsmop(result,NULL,ic,TRUE); 
3404 }
3405
3406 /*-----------------------------------------------------------------*/
3407 /* genModbits :- modulus of bits                                   */
3408 /*-----------------------------------------------------------------*/
3409 static void genModbits (operand *left, 
3410                         operand *right, 
3411                         operand *result)
3412 {
3413
3414     char *l;
3415
3416     /* the result must be bit */    
3417     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3418     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3419
3420     MOVA(l);       
3421
3422     pic16_emitcode("div","ab");
3423     pic16_emitcode("mov","a,b");
3424     pic16_emitcode("rrc","a");
3425     pic16_aopPut(AOP(result),"c",0);
3426 }
3427
3428 /*-----------------------------------------------------------------*/
3429 /* genModOneByte : 8 bit modulus                                   */
3430 /*-----------------------------------------------------------------*/
3431 static void genModOneByte (operand *left,
3432                            operand *right,
3433                            operand *result)
3434 {
3435     sym_link *opetype = operandType(result);
3436     char *l ;
3437     symbol *lbl ;
3438
3439     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3440     /* signed or unsigned */
3441     if (SPEC_USIGN(opetype)) {
3442         /* unsigned is easy */
3443         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3444         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3445         MOVA(l);    
3446         pic16_emitcode("div","ab");
3447         pic16_aopPut(AOP(result),"b",0);
3448         return ;
3449     }
3450
3451     /* signed is a little bit more difficult */
3452
3453     /* save the signs of the operands */
3454     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3455     MOVA(l);
3456
3457     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3458     pic16_emitcode("push","acc"); /* save it on the stack */
3459
3460     /* now sign adjust for both left & right */
3461     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3462     MOVA(l);
3463
3464     lbl = newiTempLabel(NULL);
3465     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3466     pic16_emitcode("cpl","a");   
3467     pic16_emitcode("inc","a");
3468     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3469     pic16_emitcode("mov","b,a"); 
3470
3471     /* sign adjust left side */
3472     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3473     MOVA(l);
3474
3475     lbl = newiTempLabel(NULL);
3476     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3477     pic16_emitcode("cpl","a");   
3478     pic16_emitcode("inc","a");
3479     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3480
3481     /* now the multiplication */
3482     pic16_emitcode("div","ab");
3483     /* we are interested in the lower order
3484     only */
3485     lbl = newiTempLabel(NULL);
3486     pic16_emitcode("pop","acc");   
3487     /* if there was an over flow we don't 
3488     adjust the sign of the result */
3489     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3490     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3491     CLRC ;
3492     pic16_emitcode("clr","a");
3493     pic16_emitcode("subb","a,b");
3494     pic16_emitcode("mov","b,a");
3495     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3496
3497     /* now we are done */
3498     pic16_aopPut(AOP(result),"b",0);
3499
3500 }
3501
3502 /*-----------------------------------------------------------------*/
3503 /* genMod - generates code for division                            */
3504 /*-----------------------------------------------------------------*/
3505 static void genMod (iCode *ic)
3506 {
3507     operand *left = IC_LEFT(ic);
3508     operand *right = IC_RIGHT(ic);
3509     operand *result= IC_RESULT(ic);  
3510
3511     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3512     /* assign the amsops */
3513     pic16_aopOp (left,ic,FALSE);
3514     pic16_aopOp (right,ic,FALSE);
3515     pic16_aopOp (result,ic,TRUE);
3516
3517     /* special cases first */
3518     /* both are bits */
3519     if (AOP_TYPE(left) == AOP_CRY &&
3520         AOP_TYPE(right)== AOP_CRY) {
3521         genModbits(left,right,result);
3522         goto release ;
3523     }
3524
3525     /* if both are of size == 1 */
3526     if (AOP_SIZE(left) == 1 &&
3527         AOP_SIZE(right) == 1 ) {
3528         genModOneByte(left,right,result);
3529         goto release ;
3530     }
3531
3532     /* should have been converted to function call */
3533     assert(0);
3534
3535 release :
3536     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3538     pic16_freeAsmop(result,NULL,ic,TRUE); 
3539 }
3540
3541 /*-----------------------------------------------------------------*/
3542 /* genIfxJump :- will create a jump depending on the ifx           */
3543 /*-----------------------------------------------------------------*/
3544 /*
3545   note: May need to add parameter to indicate when a variable is in bit space.
3546 */
3547 static void genIfxJump (iCode *ic, char *jval)
3548 {
3549
3550     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3551     /* if true label then we jump if condition
3552     supplied is true */
3553     if ( IC_TRUE(ic) ) {
3554
3555         if(strcmp(jval,"a") == 0)
3556           emitSKPZ;
3557         else if (strcmp(jval,"c") == 0)
3558           emitSKPC;
3559         else {
3560           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3561           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1));
3562         }
3563
3564         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3565         pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3566
3567     }
3568     else {
3569         /* false label is present */
3570         if(strcmp(jval,"a") == 0)
3571           emitSKPNZ;
3572         else if (strcmp(jval,"c") == 0)
3573           emitSKPNC;
3574         else {
3575           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3576           pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1));
3577         }
3578
3579         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3580         pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3581
3582     }
3583
3584
3585     /* mark the icode as generated */
3586     ic->generated = 1;
3587 }
3588
3589 /*-----------------------------------------------------------------*/
3590 /* genSkip                                                         */
3591 /*-----------------------------------------------------------------*/
3592 static void genSkip(iCode *ifx,int status_bit)
3593 {
3594   if(!ifx)
3595     return;
3596
3597   if ( IC_TRUE(ifx) ) {
3598     switch(status_bit) {
3599     case 'z':
3600       emitSKPNZ;
3601       break;
3602
3603     case 'c':
3604       emitSKPNC;
3605       break;
3606
3607     case 'd':
3608       emitSKPDC;
3609       break;
3610
3611     }
3612
3613     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3614     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3615
3616   } else {
3617
3618     switch(status_bit) {
3619
3620     case 'z':
3621       emitSKPZ;
3622       break;
3623
3624     case 'c':
3625       emitSKPC;
3626       break;
3627
3628     case 'd':
3629       emitSKPDC;
3630       break;
3631     }
3632     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3633     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3634
3635   }
3636
3637 }
3638
3639 /*-----------------------------------------------------------------*/
3640 /* genSkipc                                                        */
3641 /*-----------------------------------------------------------------*/
3642 static void genSkipc(resolvedIfx *rifx)
3643 {
3644   if(!rifx)
3645     return;
3646
3647   if(rifx->condition)
3648     emitSKPC;
3649   else
3650     emitSKPNC;
3651
3652   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3653   rifx->generated = 1;
3654 }
3655
3656 /*-----------------------------------------------------------------*/
3657 /* genSkipz2                                                       */
3658 /*-----------------------------------------------------------------*/
3659 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3660 {
3661   if(!rifx)
3662     return;
3663
3664   if( (rifx->condition ^ invert_condition) & 1)
3665     emitSKPZ;
3666   else
3667     emitSKPNZ;
3668
3669   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3670   rifx->generated = 1;
3671 }
3672
3673 /*-----------------------------------------------------------------*/
3674 /* genSkipz                                                        */
3675 /*-----------------------------------------------------------------*/
3676 static void genSkipz(iCode *ifx, int condition)
3677 {
3678   if(!ifx)
3679     return;
3680
3681   if(condition)
3682     emitSKPNZ;
3683   else
3684     emitSKPZ;
3685
3686   if ( IC_TRUE(ifx) )
3687     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3688   else
3689     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3690
3691   if ( IC_TRUE(ifx) )
3692     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3693   else
3694     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3695
3696 }
3697 /*-----------------------------------------------------------------*/
3698 /* genSkipCond                                                     */
3699 /*-----------------------------------------------------------------*/
3700 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3701 {
3702   if(!rifx)
3703     return;
3704
3705   if(rifx->condition)
3706     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3707   else
3708     pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3709
3710
3711   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3712   rifx->generated = 1;
3713 }
3714
3715 #if 0
3716 /*-----------------------------------------------------------------*/
3717 /* genChkZeroes :- greater or less than comparison                 */
3718 /*     For each byte in a literal that is zero, inclusive or the   */
3719 /*     the corresponding byte in the operand with W                */
3720 /*     returns true if any of the bytes are zero                   */
3721 /*-----------------------------------------------------------------*/
3722 static int genChkZeroes(operand *op, int lit,  int size)
3723 {
3724
3725   int i;
3726   int flag =1;
3727
3728   while(size--) {
3729     i = (lit >> (size*8)) & 0xff;
3730
3731     if(i==0) {
3732       if(flag) 
3733         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3734       else
3735         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3736       flag = 0;
3737     }
3738   }
3739
3740   return (flag==0);
3741 }
3742 #endif
3743
3744 /*-----------------------------------------------------------------*/
3745 /* genCmp :- greater or less than comparison                       */
3746 /*-----------------------------------------------------------------*/
3747 static void genCmp (operand *left,operand *right,
3748                     operand *result, iCode *ifx, int sign)
3749 {
3750   int size; //, offset = 0 ;
3751   unsigned long lit = 0L,i = 0;
3752   resolvedIfx rFalseIfx;
3753   //  resolvedIfx rTrueIfx;
3754   symbol *truelbl;
3755   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3756 /*
3757   if(ifx) {
3758     DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3759     DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3760   }
3761 */
3762
3763   resolveIfx(&rFalseIfx,ifx);
3764   truelbl  = newiTempLabel(NULL);
3765   size = max(AOP_SIZE(left),AOP_SIZE(right));
3766
3767   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3768
3769 #define _swapp
3770
3771   /* if literal is on the right then swap with left */
3772   if ((AOP_TYPE(right) == AOP_LIT)) {
3773     operand *tmp = right ;
3774     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3775     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3776 #ifdef _swapp
3777
3778     lit = (lit - 1) & mask;
3779     right = left;
3780     left = tmp;
3781     rFalseIfx.condition ^= 1;
3782 #endif
3783
3784   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3785     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3786   }
3787
3788
3789   //if(IC_TRUE(ifx) == NULL)
3790   /* if left & right are bit variables */
3791   if (AOP_TYPE(left) == AOP_CRY &&
3792       AOP_TYPE(right) == AOP_CRY ) {
3793     pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3794     pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3795   } else {
3796     /* subtract right from left if at the
3797        end the carry flag is set then we know that
3798        left is greater than right */
3799
3800     //    {
3801
3802     symbol *lbl  = newiTempLabel(NULL);
3803
3804 #ifndef _swapp
3805     if(AOP_TYPE(right) == AOP_LIT) {
3806
3807       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3808
3809       DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3810
3811       /* special cases */
3812
3813       if(lit == 0) {
3814
3815         if(sign != 0) 
3816           genSkipCond(&rFalseIfx,left,size-1,7);
3817         else 
3818           /* no need to compare to 0...*/
3819           /* NOTE: this is a de-generate compare that most certainly 
3820            *       creates some dead code. */
3821           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3822
3823         if(ifx) ifx->generated = 1;
3824         return;
3825
3826       }
3827       size--;
3828
3829       if(size == 0) {
3830         //i = (lit >> (size*8)) & 0xff;
3831         DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3832         
3833         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3834
3835         i = ((0-lit) & 0xff);
3836         if(sign) {
3837           if( i == 0x81) { 
3838             /* lit is 0x7f, all signed chars are less than
3839              * this except for 0x7f itself */
3840             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3841             genSkipz2(&rFalseIfx,0);
3842           } else {
3843             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3844             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3845             genSkipc(&rFalseIfx);
3846           }
3847
3848         } else {
3849           if(lit == 1) {
3850             genSkipz2(&rFalseIfx,1);
3851           } else {
3852             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3853             genSkipc(&rFalseIfx);
3854           }
3855         }
3856
3857         if(ifx) ifx->generated = 1;
3858         return;
3859       }
3860
3861       /* chars are out of the way. now do ints and longs */
3862
3863
3864       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3865         
3866       /* special cases */
3867
3868       if(sign) {
3869
3870         if(lit == 0) {
3871           genSkipCond(&rFalseIfx,left,size,7);
3872           if(ifx) ifx->generated = 1;
3873           return;
3874         }
3875
3876         if(lit <0x100) {
3877           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3878
3879           //rFalseIfx.condition ^= 1;
3880           //genSkipCond(&rFalseIfx,left,size,7);
3881           //rFalseIfx.condition ^= 1;
3882
3883           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3884           if(rFalseIfx.condition)
3885             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3886           else
3887             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3888
3889           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3890           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3891           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3892
3893           while(size > 1)
3894             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3895
3896           if(rFalseIfx.condition) {
3897             emitSKPZ;
3898             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3899
3900           } else {
3901             emitSKPNZ;
3902           }
3903
3904           genSkipc(&rFalseIfx);
3905           pic16_emitpLabel(truelbl->key);
3906           if(ifx) ifx->generated = 1;
3907           return;
3908
3909         }
3910
3911         if(size == 1) {
3912
3913           if( (lit & 0xff) == 0) {
3914             /* lower byte is zero */
3915             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3916             i = ((lit >> 8) & 0xff) ^0x80;
3917             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3918             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3919             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3920             genSkipc(&rFalseIfx);
3921
3922
3923             if(ifx) ifx->generated = 1;
3924             return;
3925
3926           }
3927         } else {
3928           /* Special cases for signed longs */
3929           if( (lit & 0xffffff) == 0) {
3930             /* lower byte is zero */
3931             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3932             i = ((lit >> 8*3) & 0xff) ^0x80;
3933             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3934             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3935             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3936             genSkipc(&rFalseIfx);
3937
3938
3939             if(ifx) ifx->generated = 1;
3940             return;
3941
3942           }
3943
3944         }
3945
3946
3947         if(lit & (0x80 << (size*8))) {
3948           /* lit is negative */
3949           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3950
3951           //genSkipCond(&rFalseIfx,left,size,7);
3952
3953           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954
3955           if(rFalseIfx.condition)
3956             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3957           else
3958             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3959
3960
3961         } else {
3962           /* lit is positive */
3963           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3964           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3965           if(rFalseIfx.condition)
3966             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3967           else
3968             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3969
3970         }
3971
3972         /*
3973           This works, but is only good for ints.
3974           It also requires a "known zero" register.
3975           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3976           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3977           pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
3978           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3979           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3980           genSkipc(&rFalseIfx);
3981
3982           pic16_emitpLabel(truelbl->key);
3983           if(ifx) ifx->generated = 1;
3984           return;
3985         **/
3986           
3987         /* There are no more special cases, so perform a general compare */
3988   
3989         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3990         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3991
3992         while(size--) {
3993
3994           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3995           emitSKPNZ;
3996           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3997         }
3998         //rFalseIfx.condition ^= 1;
3999         genSkipc(&rFalseIfx);
4000
4001         pic16_emitpLabel(truelbl->key);
4002
4003         if(ifx) ifx->generated = 1;
4004         return;
4005
4006
4007       }
4008
4009
4010       /* sign is out of the way. So now do an unsigned compare */
4011       DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4012
4013
4014       /* General case - compare to an unsigned literal on the right.*/
4015
4016       i = (lit >> (size*8)) & 0xff;
4017       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4018       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4019       while(size--) {
4020         i = (lit >> (size*8)) & 0xff;
4021
4022         if(i) {
4023           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4024           emitSKPNZ;
4025           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4026         } else {
4027           /* this byte of the lit is zero, 
4028            *if it's not the last then OR in the variable */
4029           if(size)
4030             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4031         }
4032       }
4033
4034
4035       pic16_emitpLabel(lbl->key);
4036       //if(emitFinalCheck)
4037       genSkipc(&rFalseIfx);
4038       if(sign)
4039         pic16_emitpLabel(truelbl->key);
4040
4041       if(ifx) ifx->generated = 1;
4042       return;
4043
4044
4045     }
4046 #endif  // _swapp
4047
4048     if(AOP_TYPE(left) == AOP_LIT) {
4049       //symbol *lbl = newiTempLabel(NULL);
4050
4051       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4052
4053
4054       DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4055
4056       /* Special cases */
4057       if((lit == 0) && (sign == 0)){
4058
4059         size--;
4060         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4061         while(size) 
4062           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4063
4064         genSkipz2(&rFalseIfx,0);
4065         if(ifx) ifx->generated = 1;
4066         return;
4067       }
4068
4069       if(size==1) {
4070         /* Special cases */
4071         lit &= 0xff;
4072         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4073           /* degenerate compare can never be true */
4074           if(rFalseIfx.condition == 0)
4075             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4076
4077           if(ifx) ifx->generated = 1;
4078           return;
4079         }
4080
4081         if(sign) {
4082           /* signed comparisons to a literal byte */
4083
4084           int lp1 = (lit+1) & 0xff;
4085
4086           DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4087           switch (lp1) {
4088           case 0:
4089             rFalseIfx.condition ^= 1;
4090             genSkipCond(&rFalseIfx,right,0,7);
4091             break;
4092           case 0x7f:
4093             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4094             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4095             genSkipz2(&rFalseIfx,1);
4096             break;
4097           default:
4098             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4099             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4100             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4101             rFalseIfx.condition ^= 1;
4102             genSkipc(&rFalseIfx);
4103             break;
4104           }
4105         } else {
4106           /* unsigned comparisons to a literal byte */
4107
4108           switch(lit & 0xff ) {
4109           case 0:
4110             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4111             genSkipz2(&rFalseIfx,0);
4112             break;
4113           case 0x7f:
4114             rFalseIfx.condition ^= 1;
4115             genSkipCond(&rFalseIfx,right,0,7);
4116             break;
4117
4118           default:
4119             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4120             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4121             DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4122             rFalseIfx.condition ^= 1;
4123             if (AOP_TYPE(result) == AOP_CRY)
4124               genSkipc(&rFalseIfx);
4125             else {
4126               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4127               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4128             }         
4129             break;
4130           }
4131         }
4132
4133         if(ifx) ifx->generated = 1;
4134         //goto check_carry;
4135         return;
4136
4137       } else {
4138
4139         /* Size is greater than 1 */
4140
4141         if(sign) {
4142           int lp1 = lit+1;
4143
4144           size--;
4145
4146           if(lp1 == 0) {
4147             /* this means lit = 0xffffffff, or -1 */
4148
4149
4150             DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4151             rFalseIfx.condition ^= 1;
4152             genSkipCond(&rFalseIfx,right,size,7);
4153             if(ifx) ifx->generated = 1;
4154             return;
4155           }
4156
4157           if(lit == 0) {
4158             int s = size;
4159
4160             if(rFalseIfx.condition) {
4161               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4162               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4163             }
4164
4165             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4166             while(size--)
4167               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4168
4169
4170             emitSKPZ;
4171             if(rFalseIfx.condition) {
4172               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4173               pic16_emitpLabel(truelbl->key);
4174             }else {
4175               rFalseIfx.condition ^= 1;
4176               genSkipCond(&rFalseIfx,right,s,7);
4177             }
4178
4179             if(ifx) ifx->generated = 1;
4180             return;
4181           }
4182
4183           if((size == 1) &&  (0 == (lp1&0xff))) {
4184             /* lower byte of signed word is zero */
4185             DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4186             i = ((lp1 >> 8) & 0xff) ^0x80;
4187             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4188             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4189             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4190             rFalseIfx.condition ^= 1;
4191             genSkipc(&rFalseIfx);
4192
4193
4194             if(ifx) ifx->generated = 1;
4195             return;
4196           }
4197
4198           if(lit & (0x80 << (size*8))) {
4199             /* Lit is less than zero */
4200             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4201             //rFalseIfx.condition ^= 1;
4202             //genSkipCond(&rFalseIfx,left,size,7);
4203             //rFalseIfx.condition ^= 1;
4204             pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4205             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4206
4207             if(rFalseIfx.condition)
4208               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4209             else
4210               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4211
4212
4213           } else {
4214             /* Lit is greater than or equal to zero */
4215             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4216             //rFalseIfx.condition ^= 1;
4217             //genSkipCond(&rFalseIfx,right,size,7);
4218             //rFalseIfx.condition ^= 1;
4219
4220             //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4221             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4222
4223             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4224             if(rFalseIfx.condition)
4225               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4226             else
4227               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4228
4229           }
4230
4231
4232           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4233           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4234
4235           while(size--) {
4236
4237             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4238             emitSKPNZ;
4239             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4240           }
4241           rFalseIfx.condition ^= 1;
4242           //rFalseIfx.condition = 1;
4243           genSkipc(&rFalseIfx);
4244
4245           pic16_emitpLabel(truelbl->key);
4246
4247           if(ifx) ifx->generated = 1;
4248           return;
4249           // end of if (sign)
4250         } else {
4251
4252           /* compare word or long to an unsigned literal on the right.*/
4253
4254
4255           size--;
4256           if(lit < 0xff) {
4257             DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4258             switch (lit) {
4259             case 0:
4260               break; /* handled above */
4261 /*
4262             case 0xff:
4263               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4264               while(size--)
4265                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4266               genSkipz2(&rFalseIfx,0);
4267               break;
4268 */
4269             default:
4270               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4271               while(--size)
4272                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4273
4274               emitSKPZ;
4275               if(rFalseIfx.condition)
4276                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4277               else
4278                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4279
4280
4281               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4282               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4283
4284               rFalseIfx.condition ^= 1;
4285               genSkipc(&rFalseIfx);
4286             }
4287
4288             pic16_emitpLabel(truelbl->key);
4289
4290             if(ifx) ifx->generated = 1;
4291             return;
4292           }
4293
4294
4295           lit++;
4296           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4297           i = (lit >> (size*8)) & 0xff;
4298
4299           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4300           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4301
4302           while(size--) {
4303             i = (lit >> (size*8)) & 0xff;
4304
4305             if(i) {
4306               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4307               emitSKPNZ;
4308               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4309             } else {
4310               /* this byte of the lit is zero, 
4311                *if it's not the last then OR in the variable */
4312               if(size)
4313                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4314             }
4315           }
4316
4317
4318           pic16_emitpLabel(lbl->key);
4319
4320           rFalseIfx.condition ^= 1;
4321           genSkipc(&rFalseIfx);
4322         }
4323
4324         if(sign)
4325           pic16_emitpLabel(truelbl->key);
4326         if(ifx) ifx->generated = 1;
4327         return;
4328       }
4329     }
4330     /* Compare two variables */
4331
4332     DEBUGpic16_emitcode(";sign","%d",sign);
4333
4334     size--;
4335     if(sign) {
4336       /* Sigh. thus sucks... */
4337       if(size) {
4338         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4339         pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4340         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4341         pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4342         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4343         pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4344       } else {
4345         /* Signed char comparison */
4346         /* Special thanks to Nikolai Golovchenko for this snippet */
4347         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4348         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4349         pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
4350         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4351         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4352         pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4353
4354         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4355         genSkipc(&rFalseIfx);
4356           
4357         if(ifx) ifx->generated = 1;
4358         return;
4359       }
4360
4361     } else {
4362
4363       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4364       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4365     }
4366
4367
4368     /* The rest of the bytes of a multi-byte compare */
4369     while (size) {
4370
4371       emitSKPZ;
4372       pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
4373       size--;
4374
4375       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4376       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4377
4378
4379     }
4380
4381     pic16_emitpLabel(lbl->key);
4382
4383     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4384     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4385         (AOP_TYPE(result) == AOP_REG)) {
4386       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4387       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4388     } else {
4389       genSkipc(&rFalseIfx);
4390     }         
4391     //genSkipc(&rFalseIfx);
4392     if(ifx) ifx->generated = 1;
4393
4394     return;
4395
4396   }
4397
4398   // check_carry:
4399   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4400     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4401     pic16_outBitC(result);
4402   } else {
4403     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4404     /* if the result is used in the next
4405        ifx conditional branch then generate
4406        code a little differently */
4407     if (ifx )
4408       genIfxJump (ifx,"c");
4409     else
4410       pic16_outBitC(result);
4411     /* leave the result in acc */
4412   }
4413
4414 }
4415
4416 /*-----------------------------------------------------------------*/
4417 /* genCmpGt :- greater than comparison                             */
4418 /*-----------------------------------------------------------------*/
4419 static void genCmpGt (iCode *ic, iCode *ifx)
4420 {
4421     operand *left, *right, *result;
4422     sym_link *letype , *retype;
4423     int sign ;
4424
4425     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4426     left = IC_LEFT(ic);
4427     right= IC_RIGHT(ic);
4428     result = IC_RESULT(ic);
4429
4430     letype = getSpec(operandType(left));
4431     retype =getSpec(operandType(right));
4432     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4433     /* assign the amsops */
4434     pic16_aopOp (left,ic,FALSE);
4435     pic16_aopOp (right,ic,FALSE);
4436     pic16_aopOp (result,ic,TRUE);
4437
4438     genCmp(right, left, result, ifx, sign);
4439
4440     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442     pic16_freeAsmop(result,NULL,ic,TRUE); 
4443 }
4444
4445 /*-----------------------------------------------------------------*/
4446 /* genCmpLt - less than comparisons                                */
4447 /*-----------------------------------------------------------------*/
4448 static void genCmpLt (iCode *ic, iCode *ifx)
4449 {
4450     operand *left, *right, *result;
4451     sym_link *letype , *retype;
4452     int sign ;
4453
4454     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4455     left = IC_LEFT(ic);
4456     right= IC_RIGHT(ic);
4457     result = IC_RESULT(ic);
4458
4459     letype = getSpec(operandType(left));
4460     retype =getSpec(operandType(right));
4461     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4462
4463     /* assign the amsops */
4464     pic16_aopOp (left,ic,FALSE);
4465     pic16_aopOp (right,ic,FALSE);
4466     pic16_aopOp (result,ic,TRUE);
4467
4468     genCmp(left, right, result, ifx, sign);
4469
4470     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472     pic16_freeAsmop(result,NULL,ic,TRUE); 
4473 }
4474
4475 /*-----------------------------------------------------------------*/
4476 /* genc16bit2lit - compare a 16 bit value to a literal             */
4477 /*-----------------------------------------------------------------*/
4478 static void genc16bit2lit(operand *op, int lit, int offset)
4479 {
4480   int i;
4481
4482   DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4483   if( (lit&0xff) == 0) 
4484     i=1;
4485   else
4486     i=0;
4487
4488   switch( BYTEofLONG(lit,i)) { 
4489   case 0:
4490     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4491     break;
4492   case 1:
4493     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4494     break;
4495   case 0xff:
4496     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4497     break;
4498   default:
4499     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4500     pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4501   }
4502
4503   i ^= 1;
4504
4505   switch( BYTEofLONG(lit,i)) { 
4506   case 0:
4507     pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4508     break;
4509   case 1:
4510     emitSKPNZ;
4511     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4512     break;
4513   case 0xff:
4514     emitSKPNZ;
4515     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4516     break;
4517   default:
4518     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4519     emitSKPNZ;
4520     pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4521
4522   }
4523
4524 }
4525
4526 /*-----------------------------------------------------------------*/
4527 /* gencjneshort - compare and jump if not equal                    */
4528 /*-----------------------------------------------------------------*/
4529 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4530 {
4531   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4532   int offset = 0;
4533   int res_offset = 0;  /* the result may be a different size then left or right */
4534   int res_size = AOP_SIZE(result);
4535   resolvedIfx rIfx;
4536   symbol *lbl;
4537
4538   unsigned long lit = 0L;
4539   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4540   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4541   if(result)
4542     DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4543   resolveIfx(&rIfx,ifx);
4544   lbl =  newiTempLabel(NULL);
4545
4546
4547   /* if the left side is a literal or 
4548      if the right is in a pointer register and left 
4549      is not */
4550   if ((AOP_TYPE(left) == AOP_LIT) || 
4551       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4552     operand *t = right;
4553     right = left;
4554     left = t;
4555   }
4556   if(AOP_TYPE(right) == AOP_LIT)
4557     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4558
4559   /* if the right side is a literal then anything goes */
4560   if (AOP_TYPE(right) == AOP_LIT &&
4561       AOP_TYPE(left) != AOP_DIR ) {
4562     switch(size) {
4563     case 2:
4564       genc16bit2lit(left, lit, 0);
4565       emitSKPNZ;
4566       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4567       break;
4568     default:
4569       while (size--) {
4570         if(lit & 0xff) {
4571           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4572           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4573         } else {
4574           pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4575         }
4576
4577         emitSKPNZ;
4578         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4579         offset++;
4580         if(res_offset < res_size-1)
4581           res_offset++;
4582         lit >>= 8;
4583       }
4584       break;
4585     }
4586   }
4587
4588   /* if the right side is in a register or in direct space or
4589      if the left is a pointer register & right is not */    
4590   else if (AOP_TYPE(right) == AOP_REG ||
4591            AOP_TYPE(right) == AOP_DIR || 
4592            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4593            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4594     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4595     int lbl_key = lbl->key;
4596
4597     if(result) {
4598       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4599       //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4600     }else {
4601       DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4602       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4603               __FUNCTION__,__LINE__);
4604       return;
4605     }
4606
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       int emit_skip=1;
4616       if((AOP_TYPE(left) == AOP_DIR) && 
4617          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4618
4619         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4620         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4621
4622       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4623             
4624         switch (lit & 0xff) {
4625         case 0:
4626           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4627           break;
4628         case 1:
4629           pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4630           pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4631           //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4632           emit_skip=0;
4633           break;
4634         case 0xff:
4635           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4636           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4637           //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4638           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4639           emit_skip=0;
4640           break;
4641         default:
4642           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4643           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4644         }
4645         lit >>= 8;
4646
4647       } else {
4648         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4649       }
4650       if(emit_skip) {
4651         if(AOP_TYPE(result) == AOP_CRY) {
4652           pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4653           if(rIfx.condition)
4654             emitSKPNZ;
4655           else
4656             emitSKPZ;
4657           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4658         } else {
4659           /* fix me. probably need to check result size too */
4660           //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4661           if(rIfx.condition)
4662             emitSKPZ;
4663           else
4664             emitSKPNZ;
4665           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4666           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4667         }
4668         if(ifx)
4669           ifx->generated=1;
4670       }
4671       emit_skip++;
4672       offset++;
4673       if(res_offset < res_size-1)
4674         res_offset++;
4675     }
4676 /*       break; */
4677 /*     } */
4678   } else if(AOP_TYPE(right) == AOP_REG &&
4679             AOP_TYPE(left) != AOP_DIR){
4680
4681     while(size--) {
4682       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4683       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4684       pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4685       if(rIfx.condition)
4686         emitSKPNZ;
4687       else
4688         emitSKPZ;
4689       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4690       offset++;
4691       if(res_offset < res_size-1)
4692         res_offset++;
4693     }
4694       
4695   }else{
4696     /* right is a pointer reg need both a & b */
4697     while(size--) {
4698       char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4699       if(strcmp(l,"b"))
4700         pic16_emitcode("mov","b,%s",l);
4701       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4702       pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4703       offset++;
4704     }
4705   }
4706
4707   pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4708   if(!rIfx.condition)
4709     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4710
4711   pic16_emitpLabel(lbl->key);
4712
4713   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4714
4715   if(ifx)
4716     ifx->generated = 1;
4717 }
4718
4719 #if 0
4720 /*-----------------------------------------------------------------*/
4721 /* gencjne - compare and jump if not equal                         */
4722 /*-----------------------------------------------------------------*/
4723 static void gencjne(operand *left, operand *right, iCode *ifx)
4724 {
4725     symbol *tlbl  = newiTempLabel(NULL);
4726
4727     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4728     gencjneshort(left, right, lbl);
4729
4730     pic16_emitcode("mov","a,%s",one);
4731     pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4732     pic16_emitcode("","%05d_DS_:",lbl->key+100);
4733     pic16_emitcode("clr","a");
4734     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4735
4736     pic16_emitpLabel(lbl->key);
4737     pic16_emitpLabel(tlbl->key);
4738
4739 }
4740 #endif
4741
4742 /*-----------------------------------------------------------------*/
4743 /* genCmpEq - generates code for equal to                          */
4744 /*-----------------------------------------------------------------*/
4745 static void genCmpEq (iCode *ic, iCode *ifx)
4746 {
4747     operand *left, *right, *result;
4748     unsigned long lit = 0L;
4749     int size,offset=0;
4750
4751     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4752
4753     if(ifx)
4754       DEBUGpic16_emitcode ("; ifx is non-null","");
4755     else
4756       DEBUGpic16_emitcode ("; ifx is null","");
4757
4758     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4759     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4760     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4761
4762     size = max(AOP_SIZE(left),AOP_SIZE(right));
4763
4764     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4765
4766     /* if literal, literal on the right or 
4767     if the right is in a pointer register and left 
4768     is not */
4769     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4770         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4771       operand *tmp = right ;
4772       right = left;
4773       left = tmp;
4774     }
4775
4776
4777     if(ifx && !AOP_SIZE(result)){
4778         symbol *tlbl;
4779         /* if they are both bit variables */
4780         if (AOP_TYPE(left) == AOP_CRY &&
4781             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4782             if(AOP_TYPE(right) == AOP_LIT){
4783                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4784                 if(lit == 0L){
4785                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4786                     pic16_emitcode("cpl","c");
4787                 } else if(lit == 1L) {
4788                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789                 } else {
4790                     pic16_emitcode("clr","c");
4791                 }
4792                 /* AOP_TYPE(right) == AOP_CRY */
4793             } else {
4794                 symbol *lbl = newiTempLabel(NULL);
4795                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4796                 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4797                 pic16_emitcode("cpl","c");
4798                 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4799             }
4800             /* if true label then we jump if condition
4801             supplied is true */
4802             tlbl = newiTempLabel(NULL);
4803             if ( IC_TRUE(ifx) ) {
4804                 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4805                 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4806             } else {
4807                 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4808                 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4809             }
4810             pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4811
4812             {
4813               /* left and right are both bit variables, result is carry */
4814               resolvedIfx rIfx;
4815               
4816               resolveIfx(&rIfx,ifx);
4817
4818               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4819               pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4820               pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4821               pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4822               genSkipz2(&rIfx,0);
4823             }
4824         } else {
4825
4826           /* They're not both bit variables. Is the right a literal? */
4827           if(AOP_TYPE(right) == AOP_LIT) {
4828             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4829             
4830             switch(size) {
4831
4832             case 1:
4833               switch(lit & 0xff) {
4834               case 1:
4835                 if ( IC_TRUE(ifx) ) {
4836                   pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4837                   emitSKPNZ;
4838                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4839                 } else {
4840                   pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4841                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4842                 }
4843                 break;
4844               case 0xff:
4845                 if ( IC_TRUE(ifx) ) {
4846                   pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4847                   emitSKPNZ;
4848                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4849                 } else {
4850                   pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4851                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4852                 }
4853                 break;
4854               default:
4855                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4856                 if(lit)
4857                   pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4858                 genSkip(ifx,'z');
4859               }
4860
4861
4862               /* end of size == 1 */
4863               break;
4864               
4865             case 2:
4866               genc16bit2lit(left,lit,offset);
4867               genSkip(ifx,'z');
4868               break;
4869               /* end of size == 2 */
4870
4871             default:
4872               /* size is 4 */
4873               if(lit==0) {
4874                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4875                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4876                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4877                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4878
4879               } else {
4880
4881                 /* search for patterns that can be optimized */
4882
4883                 genc16bit2lit(left,lit,0);
4884                 lit >>= 16;
4885                 if(lit) {
4886                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4887                   //genSkip(ifx,'z');
4888                   genc16bit2lit(left,lit,2);
4889                 } else {
4890                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4891                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4892
4893                 }
4894                 
4895               }
4896
4897               genSkip(ifx,'z');
4898             }
4899           
4900             ifx->generated = 1;
4901             goto release ;
4902             
4903
4904           } else if(AOP_TYPE(right) == AOP_CRY ) {
4905             /* we know the left is not a bit, but that the right is */
4906             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4907             pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4908                       pic16_popGet(AOP(right),offset));
4909             pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4910
4911             /* if the two are equal, then W will be 0 and the Z bit is set
4912              * we could test Z now, or go ahead and check the high order bytes if
4913              * the variable we're comparing is larger than a byte. */
4914
4915             while(--size)
4916               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4917
4918             if ( IC_TRUE(ifx) ) {
4919               emitSKPNZ;
4920               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4921               pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4922             } else {
4923               emitSKPZ;
4924               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4925               pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4926             }
4927
4928           } else {
4929             /* They're both variables that are larger than bits */
4930             int s = size;
4931
4932             tlbl = newiTempLabel(NULL);
4933
4934             while(size--) {
4935               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4936               pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4937
4938               if ( IC_TRUE(ifx) ) {
4939                 if(size) {
4940                   emitSKPZ;
4941                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4942                   pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4943                 } else {
4944                   emitSKPNZ;
4945                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4946                   pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4947                 }
4948               } else {
4949                 emitSKPZ;
4950                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4951                 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4952               }
4953               offset++;
4954             }
4955             if(s>1 && IC_TRUE(ifx)) {
4956               pic16_emitpLabel(tlbl->key);
4957               pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4958             }
4959           }
4960         }
4961         /* mark the icode as generated */
4962         ifx->generated = 1;
4963         goto release ;
4964     }
4965
4966     /* if they are both bit variables */
4967     if (AOP_TYPE(left) == AOP_CRY &&
4968         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4969         if(AOP_TYPE(right) == AOP_LIT){
4970             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4971             if(lit == 0L){
4972                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4973                 pic16_emitcode("cpl","c");
4974             } else if(lit == 1L) {
4975                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976             } else {
4977                 pic16_emitcode("clr","c");
4978             }
4979             /* AOP_TYPE(right) == AOP_CRY */
4980         } else {
4981             symbol *lbl = newiTempLabel(NULL);
4982             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4983             pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4984             pic16_emitcode("cpl","c");
4985             pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4986         }
4987         /* c = 1 if egal */
4988         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4989             pic16_outBitC(result);
4990             goto release ;
4991         }
4992         if (ifx) {
4993             genIfxJump (ifx,"c");
4994             goto release ;
4995         }
4996         /* if the result is used in an arithmetic operation
4997         then put the result in place */
4998         pic16_outBitC(result);
4999     } else {
5000       
5001       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5002       gencjne(left,right,result,ifx);
5003 /*
5004       if(ifx) 
5005         gencjne(left,right,newiTempLabel(NULL));
5006       else {
5007         if(IC_TRUE(ifx)->key)
5008           gencjne(left,right,IC_TRUE(ifx)->key);
5009         else
5010           gencjne(left,right,IC_FALSE(ifx)->key);
5011         ifx->generated = 1;
5012         goto release ;
5013       }
5014       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5015         pic16_aopPut(AOP(result),"a",0);
5016         goto release ;
5017       }
5018
5019       if (ifx) {
5020         genIfxJump (ifx,"a");
5021         goto release ;
5022       }
5023 */
5024       /* if the result is used in an arithmetic operation
5025          then put the result in place */
5026 /*
5027       if (AOP_TYPE(result) != AOP_CRY) 
5028         pic16_outAcc(result);
5029 */
5030       /* leave the result in acc */
5031     }
5032
5033 release:
5034     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5036     pic16_freeAsmop(result,NULL,ic,TRUE);
5037 }
5038
5039 /*-----------------------------------------------------------------*/
5040 /* ifxForOp - returns the icode containing the ifx for operand     */
5041 /*-----------------------------------------------------------------*/
5042 static iCode *ifxForOp ( operand *op, iCode *ic )
5043 {
5044     /* if true symbol then needs to be assigned */
5045     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5046     if (IS_TRUE_SYMOP(op))
5047         return NULL ;
5048
5049     /* if this has register type condition and
5050     the next instruction is ifx with the same operand
5051     and live to of the operand is upto the ifx only then */
5052     if (ic->next &&
5053         ic->next->op == IFX &&
5054         IC_COND(ic->next)->key == op->key &&
5055         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5056         return ic->next;
5057
5058     if (ic->next &&
5059         ic->next->op == IFX &&
5060         IC_COND(ic->next)->key == op->key) {
5061       DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5062       return ic->next;
5063     }
5064
5065     DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5066     if (ic->next &&
5067         ic->next->op == IFX)
5068       DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5069
5070     if (ic->next &&
5071         ic->next->op == IFX &&
5072         IC_COND(ic->next)->key == op->key) {
5073       DEBUGpic16_emitcode ("; "," key is okay");
5074       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5075                            OP_SYMBOL(op)->liveTo,
5076                            ic->next->seq);
5077     }
5078
5079
5080     return NULL;
5081 }
5082 /*-----------------------------------------------------------------*/
5083 /* genAndOp - for && operation                                     */
5084 /*-----------------------------------------------------------------*/
5085 static void genAndOp (iCode *ic)
5086 {
5087     operand *left,*right, *result;
5088 /*     symbol *tlbl; */
5089
5090     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5091     /* note here that && operations that are in an
5092     if statement are taken away by backPatchLabels
5093     only those used in arthmetic operations remain */
5094     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5095     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5096     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5097
5098     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5099
5100     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5101     pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5102     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5103
5104     /* if both are bit variables */
5105 /*     if (AOP_TYPE(left) == AOP_CRY && */
5106 /*         AOP_TYPE(right) == AOP_CRY ) { */
5107 /*         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5108 /*         pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5109 /*         pic16_outBitC(result); */
5110 /*     } else { */
5111 /*         tlbl = newiTempLabel(NULL); */
5112 /*         pic16_toBoolean(left);     */
5113 /*         pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5114 /*         pic16_toBoolean(right); */
5115 /*         pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5116 /*         pic16_outBitAcc(result); */
5117 /*     } */
5118
5119     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5121     pic16_freeAsmop(result,NULL,ic,TRUE);
5122 }
5123
5124
5125 /*-----------------------------------------------------------------*/
5126 /* genOrOp - for || operation                                      */
5127 /*-----------------------------------------------------------------*/
5128 /*
5129   tsd pic port -
5130   modified this code, but it doesn't appear to ever get called
5131 */
5132
5133 static void genOrOp (iCode *ic)
5134 {
5135     operand *left,*right, *result;
5136     symbol *tlbl;
5137
5138     /* note here that || operations that are in an
5139     if statement are taken away by backPatchLabels
5140     only those used in arthmetic operations remain */
5141     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5142     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5143     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5144     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5145
5146     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5147
5148     /* if both are bit variables */
5149     if (AOP_TYPE(left) == AOP_CRY &&
5150         AOP_TYPE(right) == AOP_CRY ) {
5151       pic16_emitcode("clrc","");
5152       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5153                AOP(left)->aopu.aop_dir,
5154                AOP(left)->aopu.aop_dir);
5155       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5156                AOP(right)->aopu.aop_dir,
5157                AOP(right)->aopu.aop_dir);
5158       pic16_emitcode("setc","");
5159
5160     } else {
5161         tlbl = newiTempLabel(NULL);
5162         pic16_toBoolean(left);
5163         emitSKPZ;
5164         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5165         pic16_toBoolean(right);
5166         pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5167
5168         pic16_outBitAcc(result);
5169     }
5170
5171     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5173     pic16_freeAsmop(result,NULL,ic,TRUE);            
5174 }
5175
5176 /*-----------------------------------------------------------------*/
5177 /* isLiteralBit - test if lit == 2^n                               */
5178 /*-----------------------------------------------------------------*/
5179 static int isLiteralBit(unsigned long lit)
5180 {
5181     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5182     0x100L,0x200L,0x400L,0x800L,
5183     0x1000L,0x2000L,0x4000L,0x8000L,
5184     0x10000L,0x20000L,0x40000L,0x80000L,
5185     0x100000L,0x200000L,0x400000L,0x800000L,
5186     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5187     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5188     int idx;
5189     
5190     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5191     for(idx = 0; idx < 32; idx++)
5192         if(lit == pw[idx])
5193             return idx+1;
5194     return 0;
5195 }
5196
5197 /*-----------------------------------------------------------------*/
5198 /* continueIfTrue -                                                */
5199 /*-----------------------------------------------------------------*/
5200 static void continueIfTrue (iCode *ic)
5201 {
5202     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5203     if(IC_TRUE(ic))
5204         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5205     ic->generated = 1;
5206 }
5207
5208 /*-----------------------------------------------------------------*/
5209 /* jmpIfTrue -                                                     */
5210 /*-----------------------------------------------------------------*/
5211 static void jumpIfTrue (iCode *ic)
5212 {
5213     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5214     if(!IC_TRUE(ic))
5215         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5216     ic->generated = 1;
5217 }
5218
5219 /*-----------------------------------------------------------------*/
5220 /* jmpTrueOrFalse -                                                */
5221 /*-----------------------------------------------------------------*/
5222 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5223 {
5224     // ugly but optimized by peephole
5225     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5226     if(IC_TRUE(ic)){
5227         symbol *nlbl = newiTempLabel(NULL);
5228         pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5229         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5230         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5231         pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5232     }
5233     else{
5234         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5235         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5236     }
5237     ic->generated = 1;
5238 }
5239
5240 /*-----------------------------------------------------------------*/
5241 /* genAnd  - code for and                                          */
5242 /*-----------------------------------------------------------------*/
5243 static void genAnd (iCode *ic, iCode *ifx)
5244 {
5245   operand *left, *right, *result;
5246   int size, offset=0;  
5247   unsigned long lit = 0L;
5248   int bytelit = 0;
5249   resolvedIfx rIfx;
5250
5251
5252   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5253   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5254   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5255   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5256
5257   resolveIfx(&rIfx,ifx);
5258
5259   /* if left is a literal & right is not then exchange them */
5260   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5261       AOP_NEEDSACC(left)) {
5262     operand *tmp = right ;
5263     right = left;
5264     left = tmp;
5265   }
5266
5267   /* if result = right then exchange them */
5268   if(pic16_sameRegs(AOP(result),AOP(right))){
5269     operand *tmp = right ;
5270     right = left;
5271     left = tmp;
5272   }
5273
5274   /* if right is bit then exchange them */
5275   if (AOP_TYPE(right) == AOP_CRY &&
5276       AOP_TYPE(left) != AOP_CRY){
5277     operand *tmp = right ;
5278     right = left;
5279     left = tmp;
5280   }
5281   if(AOP_TYPE(right) == AOP_LIT)
5282     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5283
5284   size = AOP_SIZE(result);
5285
5286   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5287
5288   // if(bit & yy)
5289   // result = bit & yy;
5290   if (AOP_TYPE(left) == AOP_CRY){
5291     // c = bit & literal;
5292     if(AOP_TYPE(right) == AOP_LIT){
5293       if(lit & 1) {
5294         if(size && pic16_sameRegs(AOP(result),AOP(left)))
5295           // no change
5296           goto release;
5297         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5298       } else {
5299         // bit(result) = 0;
5300         if(size && (AOP_TYPE(result) == AOP_CRY)){
5301           pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5302           goto release;
5303         }
5304         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5305           jumpIfTrue(ifx);
5306           goto release;
5307         }
5308         pic16_emitcode("clr","c");
5309       }
5310     } else {
5311       if (AOP_TYPE(right) == AOP_CRY){
5312         // c = bit & bit;
5313         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5314         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5315       } else {
5316         // c = bit & val;
5317         MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5318         // c = lsb
5319         pic16_emitcode("rrc","a");
5320         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5321       }
5322     }
5323     // bit = c
5324     // val = c
5325     if(size)
5326       pic16_outBitC(result);
5327     // if(bit & ...)
5328     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5329       genIfxJump(ifx, "c");           
5330     goto release ;
5331   }
5332
5333   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5334   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5335   if((AOP_TYPE(right) == AOP_LIT) &&
5336      (AOP_TYPE(result) == AOP_CRY) &&
5337      (AOP_TYPE(left) != AOP_CRY)){
5338     int posbit = isLiteralBit(lit);
5339     /* left &  2^n */
5340     if(posbit){
5341       posbit--;
5342       //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5343       // bit = left & 2^n
5344       if(size)
5345         pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5346       // if(left &  2^n)
5347       else{
5348         if(ifx){
5349 /*
5350           if(IC_TRUE(ifx)) {
5351             pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5352             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5353           } else {
5354             pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5355             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5356           }
5357 */
5358           pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5359                     pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5360           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5361           
5362           ifx->generated = 1;
5363         }
5364         goto release;
5365       }
5366     } else {
5367       symbol *tlbl = newiTempLabel(NULL);
5368       int sizel = AOP_SIZE(left);
5369       if(size)
5370         pic16_emitcode("setb","c");
5371       while(sizel--){
5372         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5373           MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5374           // byte ==  2^n ?
5375           if((posbit = isLiteralBit(bytelit)) != 0)
5376             pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5377           else{
5378             if(bytelit != 0x0FFL)
5379               pic16_emitcode("anl","a,%s",
5380                              pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5381             pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5382           }
5383         }
5384         offset++;
5385       }
5386       // bit = left & literal
5387       if(size){
5388         pic16_emitcode("clr","c");
5389         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5390       }
5391       // if(left & literal)
5392       else{
5393         if(ifx)
5394           jmpTrueOrFalse(ifx, tlbl);
5395         goto release ;
5396       }
5397     }
5398     pic16_outBitC(result);
5399     goto release ;
5400   }
5401
5402   /* if left is same as result */
5403   if(pic16_sameRegs(AOP(result),AOP(left))){
5404     int know_W = -1;
5405     for(;size--; offset++,lit>>=8) {
5406       if(AOP_TYPE(right) == AOP_LIT){
5407         switch(lit & 0xff) {
5408         case 0x00:
5409           /*  and'ing with 0 has clears the result */
5410 //        pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5411           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5412           break;
5413         case 0xff:
5414           /* and'ing with 0xff is a nop when the result and left are the same */
5415           break;
5416
5417         default:
5418           {
5419             int p = my_powof2( (~lit) & 0xff );
5420             if(p>=0) {
5421               /* only one bit is set in the literal, so use a bcf instruction */
5422 //            pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5423               pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5424
5425             } else {
5426               pic16_emitcode("movlw","0x%x", (lit & 0xff));
5427               pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5428               if(know_W != (lit&0xff))
5429                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5430               know_W = lit &0xff;
5431               pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5432             }
5433           }    
5434         }
5435       } else {
5436         if (AOP_TYPE(left) == AOP_ACC) {
5437           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5438         } else {                    
5439           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5440           pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5441
5442         }
5443       }
5444     }
5445
5446   } else {
5447     // left & result in different registers
5448     if(AOP_TYPE(result) == AOP_CRY){
5449       // result = bit
5450       // if(size), result in bit
5451       // if(!size && ifx), conditional oper: if(left & right)
5452       symbol *tlbl = newiTempLabel(NULL);
5453       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5454       if(size)
5455         pic16_emitcode("setb","c");
5456       while(sizer--){
5457         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5458         pic16_emitcode("anl","a,%s",
5459                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5460         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5461         offset++;
5462       }
5463       if(size){
5464         CLRC;
5465         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5466         pic16_outBitC(result);
5467       } else if(ifx)
5468         jmpTrueOrFalse(ifx, tlbl);
5469     } else {
5470       for(;(size--);offset++) {
5471         // normal case
5472         // result = left & right
5473         if(AOP_TYPE(right) == AOP_LIT){
5474           int t = (lit >> (offset*8)) & 0x0FFL;
5475           switch(t) { 
5476           case 0x00:
5477             pic16_emitcode("clrf","%s",
5478                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5479             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5480             break;
5481           case 0xff:
5482             pic16_emitcode("movf","%s,w",
5483                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5484             pic16_emitcode("movwf","%s",
5485                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5486             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5487             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5488             break;
5489           default:
5490             pic16_emitcode("movlw","0x%x",t);
5491             pic16_emitcode("andwf","%s,w",
5492                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5493             pic16_emitcode("movwf","%s",
5494                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5495               
5496             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5497             pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5498             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5499           }
5500           continue;
5501         }
5502
5503         if (AOP_TYPE(left) == AOP_ACC) {
5504           pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5505           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5506         } else {
5507           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5508           pic16_emitcode("andwf","%s,w",
5509                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5510           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5511           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5512         }
5513         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5514         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5515       }
5516     }
5517   }
5518
5519   release :
5520     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5522   pic16_freeAsmop(result,NULL,ic,TRUE);     
5523 }
5524
5525 /*-----------------------------------------------------------------*/
5526 /* genOr  - code for or                                            */
5527 /*-----------------------------------------------------------------*/
5528 static void genOr (iCode *ic, iCode *ifx)
5529 {
5530     operand *left, *right, *result;
5531     int size, offset=0;
5532     unsigned long lit = 0L;
5533
5534     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5535
5536     pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5537     pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5538     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5539
5540     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5541
5542     /* if left is a literal & right is not then exchange them */
5543     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5544         AOP_NEEDSACC(left)) {
5545         operand *tmp = right ;
5546         right = left;
5547         left = tmp;
5548     }
5549
5550     /* if result = right then exchange them */
5551     if(pic16_sameRegs(AOP(result),AOP(right))){
5552         operand *tmp = right ;
5553         right = left;
5554         left = tmp;
5555     }
5556
5557     /* if right is bit then exchange them */
5558     if (AOP_TYPE(right) == AOP_CRY &&
5559         AOP_TYPE(left) != AOP_CRY){
5560         operand *tmp = right ;
5561         right = left;
5562         left = tmp;
5563     }
5564
5565     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5566
5567     if(AOP_TYPE(right) == AOP_LIT)
5568         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5569
5570     size = AOP_SIZE(result);
5571
5572     // if(bit | yy)
5573     // xx = bit | yy;
5574     if (AOP_TYPE(left) == AOP_CRY){
5575         if(AOP_TYPE(right) == AOP_LIT){
5576             // c = bit & literal;
5577             if(lit){
5578                 // lit != 0 => result = 1
5579                 if(AOP_TYPE(result) == AOP_CRY){
5580                   if(size)
5581                     pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5582                   //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5583                   //     AOP(result)->aopu.aop_dir,
5584                   //     AOP(result)->aopu.aop_dir);
5585                     else if(ifx)
5586                         continueIfTrue(ifx);
5587                     goto release;
5588                 }
5589             } else {
5590                 // lit == 0 => result = left
5591                 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5592                     goto release;
5593                 pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5594             }
5595         } else {
5596             if (AOP_TYPE(right) == AOP_CRY){
5597               if(pic16_sameRegs(AOP(result),AOP(left))){
5598                 // c = bit | bit;
5599                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5600                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5601                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5602
5603                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5604                          AOP(result)->aopu.aop_dir,
5605                          AOP(result)->aopu.aop_dir);
5606                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5607                          AOP(right)->aopu.aop_dir,
5608                          AOP(right)->aopu.aop_dir);
5609                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5610                          AOP(result)->aopu.aop_dir,
5611                          AOP(result)->aopu.aop_dir);
5612               } else {
5613                 if( AOP_TYPE(result) == AOP_ACC) {
5614                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5615                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5616                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5617                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5618
5619                 } else {
5620
5621                   pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5622                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5623                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5624                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5625
5626                   pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5627                                  AOP(result)->aopu.aop_dir,
5628                                  AOP(result)->aopu.aop_dir);
5629                   pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5630                                  AOP(right)->aopu.aop_dir,
5631                                  AOP(right)->aopu.aop_dir);
5632                   pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5633                                  AOP(left)->aopu.aop_dir,
5634                                  AOP(left)->aopu.aop_dir);
5635                   pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5636                                  AOP(result)->aopu.aop_dir,
5637                                  AOP(result)->aopu.aop_dir);
5638                 }
5639               }
5640             } else {
5641                 // c = bit | val;
5642                 symbol *tlbl = newiTempLabel(NULL);
5643                 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5644
5645
5646                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5647                 if( AOP_TYPE(right) == AOP_ACC) {
5648                   pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5649                   emitSKPNZ;
5650                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5651                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5652                 }
5653
5654
5655
5656                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5657                     pic16_emitcode(";XXX setb","c");
5658                 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5659                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5660                 pic16_toBoolean(right);
5661                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5662                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5663                     jmpTrueOrFalse(ifx, tlbl);
5664                     goto release;
5665                 } else {
5666                     CLRC;
5667                     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5668                 }
5669             }
5670         }
5671         // bit = c
5672         // val = c
5673         if(size)
5674             pic16_outBitC(result);
5675         // if(bit | ...)
5676         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5677             genIfxJump(ifx, "c");           
5678         goto release ;
5679     }
5680
5681     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5682     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5683     if((AOP_TYPE(right) == AOP_LIT) &&
5684        (AOP_TYPE(result) == AOP_CRY) &&
5685        (AOP_TYPE(left) != AOP_CRY)){
5686         if(lit){
5687           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5688             // result = 1
5689             if(size)
5690                 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5691             else 
5692                 continueIfTrue(ifx);
5693             goto release;
5694         } else {
5695           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696             // lit = 0, result = boolean(left)
5697             if(size)
5698                 pic16_emitcode(";XXX setb","c");
5699             pic16_toBoolean(right);
5700             if(size){
5701                 symbol *tlbl = newiTempLabel(NULL);
5702                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5703                 CLRC;
5704                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5705             } else {
5706                 genIfxJump (ifx,"a");
5707                 goto release;
5708             }
5709         }
5710         pic16_outBitC(result);
5711         goto release ;
5712     }
5713
5714     /* if left is same as result */
5715     if(pic16_sameRegs(AOP(result),AOP(left))){
5716       int know_W = -1;
5717       for(;size--; offset++,lit>>=8) {
5718         if(AOP_TYPE(right) == AOP_LIT){
5719           if((lit & 0xff) == 0)
5720             /*  or'ing with 0 has no effect */
5721             continue;
5722           else {
5723             int p = my_powof2(lit & 0xff);
5724             if(p>=0) {
5725               /* only one bit is set in the literal, so use a bsf instruction */
5726               pic16_emitpcode(POC_BSF,
5727                         pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5728             } else {
5729               if(know_W != (lit & 0xff))
5730                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5731               know_W = lit & 0xff;
5732               pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5733             }
5734                     
5735           }
5736         } else {
5737           if (AOP_TYPE(left) == AOP_ACC) {
5738             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
5739             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5740           } else {                  
5741             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5742             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
5743
5744             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5745             pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5746
5747           }
5748         }
5749       }
5750     } else {
5751         // left & result in different registers
5752         if(AOP_TYPE(result) == AOP_CRY){
5753             // result = bit
5754             // if(size), result in bit
5755             // if(!size && ifx), conditional oper: if(left | right)
5756             symbol *tlbl = newiTempLabel(NULL);
5757             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5758             pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5759
5760
5761             if(size)
5762                 pic16_emitcode(";XXX setb","c");
5763             while(sizer--){
5764                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5765                 pic16_emitcode(";XXX orl","a,%s",
5766                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5767                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5768                 offset++;
5769             }
5770             if(size){
5771                 CLRC;
5772                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5773                 pic16_outBitC(result);
5774             } else if(ifx)
5775                 jmpTrueOrFalse(ifx, tlbl);
5776         } else for(;(size--);offset++){
5777           // normal case
5778           // result = left & right
5779           if(AOP_TYPE(right) == AOP_LIT){
5780             int t = (lit >> (offset*8)) & 0x0FFL;
5781             switch(t) { 
5782             case 0x00:
5783               pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
5784               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5785
5786               pic16_emitcode("movf","%s,w",
5787                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5788               pic16_emitcode("movwf","%s",
5789                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5790               break;
5791             default:
5792               pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
5793               pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5794               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5795
5796               pic16_emitcode("movlw","0x%x",t);
5797               pic16_emitcode("iorwf","%s,w",
5798                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5799               pic16_emitcode("movwf","%s",
5800                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5801               
5802             }
5803             continue;
5804           }
5805
5806           // faster than result <- left, anl result,right
5807           // and better if result is SFR
5808           if (AOP_TYPE(left) == AOP_ACC) {
5809             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
5810             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5811           } else {
5812             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5813             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5814
5815             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5816             pic16_emitcode("iorwf","%s,w",
5817                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5818           }
5819           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5820           pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5821         }
5822     }
5823
5824 release :
5825     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827     pic16_freeAsmop(result,NULL,ic,TRUE);     
5828 }
5829
5830 /*-----------------------------------------------------------------*/
5831 /* genXor - code for xclusive or                                   */
5832 /*-----------------------------------------------------------------*/
5833 static void genXor (iCode *ic, iCode *ifx)
5834 {
5835   operand *left, *right, *result;
5836   int size, offset=0;
5837   unsigned long lit = 0L;
5838
5839   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5840
5841   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5842   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5843   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5844
5845   /* if left is a literal & right is not ||
5846      if left needs acc & right does not */
5847   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5848       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5849     operand *tmp = right ;
5850     right = left;
5851     left = tmp;
5852   }
5853
5854   /* if result = right then exchange them */
5855   if(pic16_sameRegs(AOP(result),AOP(right))){
5856     operand *tmp = right ;
5857     right = left;
5858     left = tmp;
5859   }
5860
5861   /* if right is bit then exchange them */
5862   if (AOP_TYPE(right) == AOP_CRY &&
5863       AOP_TYPE(left) != AOP_CRY){
5864     operand *tmp = right ;
5865     right = left;
5866     left = tmp;
5867   }
5868   if(AOP_TYPE(right) == AOP_LIT)
5869     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5870
5871   size = AOP_SIZE(result);
5872
5873   // if(bit ^ yy)
5874   // xx = bit ^ yy;
5875   if (AOP_TYPE(left) == AOP_CRY){
5876     if(AOP_TYPE(right) == AOP_LIT){
5877       // c = bit & literal;
5878       if(lit>>1){
5879         // lit>>1  != 0 => result = 1
5880         if(AOP_TYPE(result) == AOP_CRY){
5881           if(size)
5882             {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
5883             pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5884           else if(ifx)
5885             continueIfTrue(ifx);
5886           goto release;
5887         }
5888         pic16_emitcode("setb","c");
5889       } else{
5890         // lit == (0 or 1)
5891         if(lit == 0){
5892           // lit == 0, result = left
5893           if(size && pic16_sameRegs(AOP(result),AOP(left)))
5894             goto release;
5895           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5896         } else{
5897           // lit == 1, result = not(left)
5898           if(size && pic16_sameRegs(AOP(result),AOP(left))){
5899             pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
5900             pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
5901             pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5902             goto release;
5903           } else {
5904             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5905             pic16_emitcode("cpl","c");
5906           }
5907         }
5908       }
5909
5910     } else {
5911       // right != literal
5912       symbol *tlbl = newiTempLabel(NULL);
5913       if (AOP_TYPE(right) == AOP_CRY){
5914         // c = bit ^ bit;
5915         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5916       }
5917       else{
5918         int sizer = AOP_SIZE(right);
5919         // c = bit ^ val
5920         // if val>>1 != 0, result = 1
5921         pic16_emitcode("setb","c");
5922         while(sizer){
5923           MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5924           if(sizer == 1)
5925             // test the msb of the lsb
5926             pic16_emitcode("anl","a,#0xfe");
5927           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5928           sizer--;
5929         }
5930         // val = (0,1)
5931         pic16_emitcode("rrc","a");
5932       }
5933       pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5934       pic16_emitcode("cpl","c");
5935       pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5936     }
5937     // bit = c
5938     // val = c
5939     if(size)
5940       pic16_outBitC(result);
5941     // if(bit | ...)
5942     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5943       genIfxJump(ifx, "c");           
5944     goto release ;
5945   }
5946
5947   if(pic16_sameRegs(AOP(result),AOP(left))){
5948     /* if left is same as result */
5949     for(;size--; offset++) {
5950       if(AOP_TYPE(right) == AOP_LIT){
5951         int t  = (lit >> (offset*8)) & 0x0FFL;
5952         if(t == 0x00L)
5953           continue;
5954         else
5955           if (IS_AOP_PREG(left)) {
5956             MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5957             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5958             pic16_aopPut(AOP(result),"a",offset);
5959           } else {
5960             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5961             pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5962             pic16_emitcode("xrl","%s,%s",
5963                            pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5964                            pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5965           }
5966       } else {
5967         if (AOP_TYPE(left) == AOP_ACC)
5968           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5969         else {
5970           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5971           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5972 /*
5973           if (IS_AOP_PREG(left)) {
5974             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5975             pic16_aopPut(AOP(result),"a",offset);
5976           } else
5977             pic16_emitcode("xrl","%s,a",
5978                            pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5979 */
5980         }
5981       }
5982     }
5983   } else {
5984     // left & result in different registers
5985     if(AOP_TYPE(result) == AOP_CRY){
5986       // result = bit
5987       // if(size), result in bit
5988       // if(!size && ifx), conditional oper: if(left ^ right)
5989       symbol *tlbl = newiTempLabel(NULL);
5990       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5991       if(size)
5992         pic16_emitcode("setb","c");
5993       while(sizer--){
5994         if((AOP_TYPE(right) == AOP_LIT) &&
5995            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5996           MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5997         } else {
5998           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5999           pic16_emitcode("xrl","a,%s",
6000                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6001         }
6002         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6003         offset++;
6004       }
6005       if(size){
6006         CLRC;
6007         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6008         pic16_outBitC(result);
6009       } else if(ifx)
6010         jmpTrueOrFalse(ifx, tlbl);
6011     } else for(;(size--);offset++){
6012       // normal case
6013       // result = left & right
6014       if(AOP_TYPE(right) == AOP_LIT){
6015         int t = (lit >> (offset*8)) & 0x0FFL;
6016         switch(t) { 
6017         case 0x00:
6018           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6019           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6020           pic16_emitcode("movf","%s,w",
6021                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6022           pic16_emitcode("movwf","%s",
6023                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6024           break;
6025         case 0xff:
6026           pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6027           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6028           pic16_emitcode("comf","%s,w",
6029                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6030           pic16_emitcode("movwf","%s",
6031                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6032           break;
6033         default:
6034           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6035           pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6036           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6037           pic16_emitcode("movlw","0x%x",t);
6038           pic16_emitcode("xorwf","%s,w",
6039                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6040           pic16_emitcode("movwf","%s",
6041                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6042
6043         }
6044         continue;
6045       }
6046
6047       // faster than result <- left, anl result,right
6048       // and better if result is SFR
6049       if (AOP_TYPE(left) == AOP_ACC) {
6050         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6051         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6052       } else {
6053         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6054         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6055         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6056         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6057       }
6058       if ( AOP_TYPE(result) != AOP_ACC){
6059         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6060         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6061       }
6062     }
6063   }
6064
6065   release :
6066     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068   pic16_freeAsmop(result,NULL,ic,TRUE);     
6069 }
6070
6071 /*-----------------------------------------------------------------*/
6072 /* genInline - write the inline code out                           */
6073 /*-----------------------------------------------------------------*/
6074 static void genInline (iCode *ic)
6075 {
6076     char *buffer, *bp, *bp1;
6077     
6078     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6079
6080     _G.inLine += (!options.asmpeep);
6081
6082     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6083     strcpy(buffer,IC_INLINE(ic));
6084
6085     /* emit each line as a code */
6086     while (*bp) {
6087         if (*bp == '\n') {
6088             *bp++ = '\0';
6089
6090             if(*bp1)
6091               pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6092             bp1 = bp;
6093         } else {
6094             if (*bp == ':') {
6095                 bp++;
6096                 *bp = '\0';
6097                 bp++;
6098                 pic16_emitcode(bp1,"");
6099                 bp1 = bp;
6100             } else
6101                 bp++;
6102         }
6103     }
6104     if ((bp1 != bp) && *bp1)
6105       pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6106
6107     Safe_free(buffer);
6108
6109     _G.inLine -= (!options.asmpeep);
6110 }
6111
6112 /*-----------------------------------------------------------------*/
6113 /* genRRC - rotate right with carry                                */
6114 /*-----------------------------------------------------------------*/
6115 static void genRRC (iCode *ic)
6116 {
6117   operand *left , *result ;
6118   int size, offset = 0, same;
6119
6120   /* rotate right with carry */
6121   left = IC_LEFT(ic);
6122   result=IC_RESULT(ic);
6123   pic16_aopOp (left,ic,FALSE);
6124   pic16_aopOp (result,ic,FALSE);
6125
6126   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6127
6128   same = pic16_sameRegs(AOP(result),AOP(left));
6129
6130   size = AOP_SIZE(result);    
6131
6132   /* get the lsb and put it into the carry */
6133   pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6134
6135   offset = 0 ;
6136
6137   while(size--) {
6138
6139     if(same) {
6140       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6141     } else {
6142       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6143       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6144     }
6145
6146     offset++;
6147   }
6148
6149   pic16_freeAsmop(left,NULL,ic,TRUE);
6150   pic16_freeAsmop(result,NULL,ic,TRUE);
6151 }
6152
6153 /*-----------------------------------------------------------------*/
6154 /* genRLC - generate code for rotate left with carry               */
6155 /*-----------------------------------------------------------------*/
6156 static void genRLC (iCode *ic)
6157 {    
6158   operand *left , *result ;
6159   int size, offset = 0;
6160   int same;
6161
6162   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6163   /* rotate right with carry */
6164   left = IC_LEFT(ic);
6165   result=IC_RESULT(ic);
6166   pic16_aopOp (left,ic,FALSE);
6167   pic16_aopOp (result,ic,FALSE);
6168
6169   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6170
6171   same = pic16_sameRegs(AOP(result),AOP(left));
6172
6173   /* move it to the result */
6174   size = AOP_SIZE(result);    
6175
6176   /* get the msb and put it into the carry */
6177   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6178
6179   offset = 0 ;
6180
6181   while(size--) {
6182
6183     if(same) {
6184       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6185     } else {
6186       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6187       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6188     }
6189
6190     offset++;
6191   }
6192
6193
6194   pic16_freeAsmop(left,NULL,ic,TRUE);
6195   pic16_freeAsmop(result,NULL,ic,TRUE);
6196 }
6197
6198 /*-----------------------------------------------------------------*/
6199 /* genGetHbit - generates code get highest order bit               */
6200 /*-----------------------------------------------------------------*/
6201 static void genGetHbit (iCode *ic)
6202 {
6203     operand *left, *result;
6204     left = IC_LEFT(ic);
6205     result=IC_RESULT(ic);
6206     pic16_aopOp (left,ic,FALSE);
6207     pic16_aopOp (result,ic,FALSE);
6208
6209     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6210     /* get the highest order byte into a */
6211     MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6212     if(AOP_TYPE(result) == AOP_CRY){
6213         pic16_emitcode("rlc","a");
6214         pic16_outBitC(result);
6215     }
6216     else{
6217         pic16_emitcode("rl","a");
6218         pic16_emitcode("anl","a,#0x01");
6219         pic16_outAcc(result);
6220     }
6221
6222
6223     pic16_freeAsmop(left,NULL,ic,TRUE);
6224     pic16_freeAsmop(result,NULL,ic,TRUE);
6225 }
6226
6227 /*-----------------------------------------------------------------*/
6228 /* AccRol - rotate left accumulator by known count                 */
6229 /*-----------------------------------------------------------------*/
6230 static void AccRol (int shCount)
6231 {
6232     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6233     shCount &= 0x0007;              // shCount : 0..7
6234     switch(shCount){
6235         case 0 :
6236             break;
6237         case 1 :
6238             pic16_emitcode("rl","a");
6239             break;
6240         case 2 :
6241             pic16_emitcode("rl","a");
6242             pic16_emitcode("rl","a");
6243             break;
6244         case 3 :
6245             pic16_emitcode("swap","a");
6246             pic16_emitcode("rr","a");
6247             break;
6248         case 4 :
6249             pic16_emitcode("swap","a");
6250             break;
6251         case 5 :
6252             pic16_emitcode("swap","a");
6253             pic16_emitcode("rl","a");
6254             break;
6255         case 6 :
6256             pic16_emitcode("rr","a");
6257             pic16_emitcode("rr","a");
6258             break;
6259         case 7 :
6260             pic16_emitcode("rr","a");
6261             break;
6262     }
6263 }
6264
6265 /*-----------------------------------------------------------------*/
6266 /* AccLsh - left shift accumulator by known count                  */
6267 /*-----------------------------------------------------------------*/
6268 static void AccLsh (int shCount)
6269 {
6270     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6271     if(shCount != 0){
6272         if(shCount == 1)
6273             pic16_emitcode("add","a,acc");
6274         else 
6275             if(shCount == 2) {
6276             pic16_emitcode("add","a,acc");
6277             pic16_emitcode("add","a,acc");
6278         } else {
6279             /* rotate left accumulator */
6280             AccRol(shCount);
6281             /* and kill the lower order bits */
6282             pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6283         }
6284     }
6285 }
6286
6287 /*-----------------------------------------------------------------*/
6288 /* AccRsh - right shift accumulator by known count                 */
6289 /*-----------------------------------------------------------------*/
6290 static void AccRsh (int shCount)
6291 {
6292     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6293     if(shCount != 0){
6294         if(shCount == 1){
6295             CLRC;
6296             pic16_emitcode("rrc","a");
6297         } else {
6298             /* rotate right accumulator */
6299             AccRol(8 - shCount);
6300             /* and kill the higher order bits */
6301             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6302         }
6303     }
6304 }
6305
6306 #if 0
6307 /*-----------------------------------------------------------------*/
6308 /* AccSRsh - signed right shift accumulator by known count                 */
6309 /*-----------------------------------------------------------------*/
6310 static void AccSRsh (int shCount)
6311 {
6312     symbol *tlbl ;
6313     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6314     if(shCount != 0){
6315         if(shCount == 1){
6316             pic16_emitcode("mov","c,acc.7");
6317             pic16_emitcode("rrc","a");
6318         } else if(shCount == 2){
6319             pic16_emitcode("mov","c,acc.7");
6320             pic16_emitcode("rrc","a");
6321             pic16_emitcode("mov","c,acc.7");
6322             pic16_emitcode("rrc","a");
6323         } else {
6324             tlbl = newiTempLabel(NULL);
6325             /* rotate right accumulator */
6326             AccRol(8 - shCount);
6327             /* and kill the higher order bits */
6328             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6329             pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6330             pic16_emitcode("orl","a,#0x%02x",
6331                      (unsigned char)~SRMask[shCount]);
6332             pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6333         }
6334     }
6335 }
6336 #endif
6337 /*-----------------------------------------------------------------*/
6338 /* shiftR1Left2Result - shift right one byte from left to result   */
6339 /*-----------------------------------------------------------------*/
6340 static void shiftR1Left2ResultSigned (operand *left, int offl,
6341                                 operand *result, int offr,
6342                                 int shCount)
6343 {
6344   int same;
6345
6346   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6347
6348   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6349
6350   switch(shCount) {
6351   case 1:
6352     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6353     if(same) 
6354       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6355     else {
6356       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6357       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6358     }
6359
6360     break;
6361   case 2:
6362
6363     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6364     if(same) 
6365       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6366     else {
6367       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6368       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6369     }
6370     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6371     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6372
6373     break;
6374
6375   case 3:
6376     if(same)
6377       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6378     else {
6379       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6380       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6381     }
6382
6383     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6384     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6385     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6386
6387     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6388     pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6389
6390     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6391     break;
6392
6393   case 4:
6394     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6395     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
6396     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6397     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
6398     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6399     break;
6400   case 5:
6401     if(same) {
6402       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
6403     } else {
6404       pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
6405       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6406     }
6407     pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
6408     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
6409     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6410     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
6411     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6412     break;
6413
6414   case 6:
6415     if(same) {
6416       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6417       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6418       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6419       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6420       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6421       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6422     } else {
6423       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6424       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6425       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6426       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6427       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6428     }
6429     break;
6430
6431   case 7:
6432     if(same) {
6433       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6434       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6435       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6436       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6437     } else {
6438       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6439       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6440       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6441     }
6442
6443   default:
6444     break;
6445   }
6446 }
6447
6448 /*-----------------------------------------------------------------*/
6449 /* shiftR1Left2Result - shift right one byte from left to result   */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftR1Left2Result (operand *left, int offl,
6452                                 operand *result, int offr,
6453                                 int shCount, int sign)
6454 {
6455   int same;
6456
6457   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6458
6459   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6460
6461   /* Copy the msb into the carry if signed. */
6462   if(sign) {
6463     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6464     return;
6465   }
6466
6467
6468
6469   switch(shCount) {
6470   case 1:
6471     emitCLRC;
6472     if(same) 
6473       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6474     else {
6475       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6476       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6477     }
6478     break;
6479   case 2:
6480     emitCLRC;
6481     if(same) {
6482       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6483     } else {
6484       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6485       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6486     }
6487     emitCLRC;
6488     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6489
6490     break;
6491   case 3:
6492     if(same)
6493       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6494     else {
6495       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6496       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6497     }
6498
6499     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6500     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6501     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6502     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6503     break;
6504       
6505   case 4:
6506     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6507     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6508     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6509     break;
6510
6511   case 5:
6512     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6513     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6514     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6515     emitCLRC;
6516     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6517
6518     break;
6519   case 6:
6520
6521     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl));
6522     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6523     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6524     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6525     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6526     break;
6527
6528   case 7:
6529
6530     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6531     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6532     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6533
6534     break;
6535
6536   default:
6537     break;
6538   }
6539 }
6540
6541 /*-----------------------------------------------------------------*/
6542 /* shiftL1Left2Result - shift left one byte from left to result    */
6543 /*-----------------------------------------------------------------*/
6544 static void shiftL1Left2Result (operand *left, int offl,
6545                                 operand *result, int offr, int shCount)
6546 {
6547   int same;
6548
6549   //    char *l;
6550   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6551
6552   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6553   DEBUGpic16_emitcode ("; ***","same =  %d",same);
6554     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6555     //    MOVA(l);
6556     /* shift left accumulator */
6557     //AccLsh(shCount); // don't comment out just yet...
6558   //    pic16_aopPut(AOP(result),"a",offr);
6559
6560   switch(shCount) {
6561   case 1:
6562     /* Shift left 1 bit position */
6563     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6564     if(same) {
6565       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6566     } else {
6567       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6568       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6569     }
6570     break;
6571   case 2:
6572     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6573     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6574     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6575     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6576     break;
6577   case 3:
6578     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6579     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6580     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6581     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6582     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6583     break;
6584   case 4:
6585     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6586     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6587     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6588     break;
6589   case 5:
6590     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6591     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6592     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6593     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6594     break;
6595   case 6:
6596     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6597     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6598     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6599     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6600     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6601     break;
6602   case 7:
6603     pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6604     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6605     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6606     break;
6607
6608   default:
6609     DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6610   }
6611
6612 }
6613
6614 /*-----------------------------------------------------------------*/
6615 /* movLeft2Result - move byte from left to result                  */
6616 /*-----------------------------------------------------------------*/
6617 static void movLeft2Result (operand *left, int offl,
6618                             operand *result, int offr)
6619 {
6620   char *l;
6621   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6622   if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6623     l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6624
6625     if (*l == '@' && (IS_AOP_PREG(result))) {
6626       pic16_emitcode("mov","a,%s",l);
6627       pic16_aopPut(AOP(result),"a",offr);
6628     } else {
6629       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6630       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6631     }
6632   }
6633 }
6634
6635 /*-----------------------------------------------------------------*/
6636 /* shiftL2Left2Result - shift left two bytes from left to result   */
6637 /*-----------------------------------------------------------------*/
6638 static void shiftL2Left2Result (operand *left, int offl,
6639                                 operand *result, int offr, int shCount)
6640 {
6641
6642
6643   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6644
6645   if(pic16_sameRegs(AOP(result), AOP(left))) {
6646     switch(shCount) {
6647     case 0:
6648       break;
6649     case 1:
6650     case 2:
6651     case 3:
6652
6653       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6654       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6655       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6656
6657       while(--shCount) {
6658         emitCLRC;
6659         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6660         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6661       }
6662
6663       break;
6664     case 4:
6665     case 5:
6666       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6667       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6668       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6669       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6670       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6671       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6672       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6673       if(shCount >=5) {
6674         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6675         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6676       }
6677       break;
6678     case 6:
6679       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6680       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6681       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6682       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6683       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6684       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6685       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6686       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6687       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6688       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6689       break;
6690     case 7:
6691       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6692       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6693       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6694       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6695       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6696     }
6697
6698   } else {
6699     switch(shCount) {
6700     case 0:
6701       break;
6702     case 1:
6703     case 2:
6704     case 3:
6705       /* note, use a mov/add for the shift since the mov has a
6706          chance of getting optimized out */
6707       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6708       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6709       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6710       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl+MSB16));
6711       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6712
6713       while(--shCount) {
6714         emitCLRC;
6715         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6716         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6717       }
6718       break;
6719
6720     case 4:
6721     case 5:
6722       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6723       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6724       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6725       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6726       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6727       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6728       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6729       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6730
6731
6732       if(shCount == 5) {
6733         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6734         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6735       }
6736       break;
6737     case 6:
6738       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6739       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6740       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6741       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6742
6743       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6744       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6745       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6746       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6747       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6748       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6749       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6750       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6751       break;
6752     case 7:
6753       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6754       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6755       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6756       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6757       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6758     }
6759   }
6760
6761 }
6762 /*-----------------------------------------------------------------*/
6763 /* shiftR2Left2Result - shift right two bytes from left to result  */
6764 /*-----------------------------------------------------------------*/
6765 static void shiftR2Left2Result (operand *left, int offl,
6766                                 operand *result, int offr,
6767                                 int shCount, int sign)
6768 {
6769   int same=0;
6770
6771   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6772   same = pic16_sameRegs(AOP(result), AOP(left));
6773
6774   if(same && ((offl + MSB16) == offr)){
6775     same=1;
6776     /* don't crash result[offr] */
6777     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6778     pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6779   }
6780 /* else {
6781     movLeft2Result(left,offl, result, offr);
6782     MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6783   }
6784 */
6785   /* a:x >> shCount (x = lsb(result))*/
6786 /*
6787   if(sign)
6788     AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789   else {
6790     AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6791 */
6792   switch(shCount) {
6793   case 0:
6794     break;
6795   case 1:
6796   case 2:
6797   case 3:
6798     if(sign)
6799       pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6800     else
6801       emitCLRC;
6802
6803     if(same) {
6804       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6805       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6806     } else {
6807       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6808       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6809       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6810       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6811     }
6812
6813     while(--shCount) {
6814       if(sign)
6815         pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6816       else
6817         emitCLRC;
6818       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6819       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6820     }
6821     break;
6822   case 4:
6823   case 5:
6824     if(same) {
6825
6826       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6827       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6828       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6829
6830       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6831       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6832       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6833       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6834     } else {
6835       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6836       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6837       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6838
6839       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6840       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6841       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6842       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6843       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6844     }
6845
6846     if(shCount >=5) {
6847       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6848       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6849     }
6850
6851     if(sign) {
6852       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6853       pic16_emitpcode(POC_BTFSC, 
6854                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6855       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6856     }
6857
6858     break;
6859
6860   case 6:
6861     if(same) {
6862
6863       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6864       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6865
6866       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6867       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6868       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6869       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6870       if(sign) {
6871         pic16_emitpcode(POC_BTFSC, 
6872                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6873         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6874       }
6875       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6876       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6877       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6878       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6879     } else {
6880       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6881       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6882       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6883       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6884       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6885       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6886       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6887       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6888       if(sign) {
6889         pic16_emitpcode(POC_BTFSC, 
6890                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6891         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6892       }
6893       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6894       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6895
6896         
6897     }
6898
6899     break;
6900   case 7:
6901     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6902     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6903     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6904     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6905     if(sign) {
6906       emitSKPNC;
6907       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6908     } else 
6909       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6910   }
6911 }
6912
6913
6914 /*-----------------------------------------------------------------*/
6915 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6916 /*-----------------------------------------------------------------*/
6917 static void shiftLLeftOrResult (operand *left, int offl,
6918                                 operand *result, int offr, int shCount)
6919 {
6920     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6921     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6922     /* shift left accumulator */
6923     AccLsh(shCount);
6924     /* or with result */
6925     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6926     /* back to result */
6927     pic16_aopPut(AOP(result),"a",offr);
6928 }
6929
6930 /*-----------------------------------------------------------------*/
6931 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6932 /*-----------------------------------------------------------------*/
6933 static void shiftRLeftOrResult (operand *left, int offl,
6934                                 operand *result, int offr, int shCount)
6935 {
6936     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6937     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6938     /* shift right accumulator */
6939     AccRsh(shCount);
6940     /* or with result */
6941     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6942     /* back to result */
6943     pic16_aopPut(AOP(result),"a",offr);
6944 }
6945
6946 /*-----------------------------------------------------------------*/
6947 /* genlshOne - left shift a one byte quantity by known count       */
6948 /*-----------------------------------------------------------------*/
6949 static void genlshOne (operand *result, operand *left, int shCount)
6950 {       
6951     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6952     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6953 }
6954
6955 /*-----------------------------------------------------------------*/
6956 /* genlshTwo - left shift two bytes by known amount != 0           */
6957 /*-----------------------------------------------------------------*/
6958 static void genlshTwo (operand *result,operand *left, int shCount)
6959 {
6960     int size;
6961     
6962     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6963     size = pic16_getDataSize(result);
6964
6965     /* if shCount >= 8 */
6966     if (shCount >= 8) {
6967         shCount -= 8 ;
6968
6969         if (size > 1){
6970             if (shCount)
6971                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6972             else 
6973                 movLeft2Result(left, LSB, result, MSB16);
6974         }
6975         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6976     }
6977
6978     /*  1 <= shCount <= 7 */
6979     else {  
6980         if(size == 1)
6981             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6982         else 
6983             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6984     }
6985 }
6986
6987 /*-----------------------------------------------------------------*/
6988 /* shiftLLong - shift left one long from left to result            */
6989 /* offl = LSB or MSB16                                             */
6990 /*-----------------------------------------------------------------*/
6991 static void shiftLLong (operand *left, operand *result, int offr )
6992 {
6993     char *l;
6994     int size = AOP_SIZE(result);
6995
6996     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6997     if(size >= LSB+offr){
6998         l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
6999         MOVA(l);
7000         pic16_emitcode("add","a,acc");
7001         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7002             size >= MSB16+offr && offr != LSB )
7003             pic16_emitcode("xch","a,%s",
7004                      pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7005         else        
7006             pic16_aopPut(AOP(result),"a",LSB+offr);
7007     }
7008
7009     if(size >= MSB16+offr){
7010         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7011             l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7012             MOVA(l);
7013         }
7014         pic16_emitcode("rlc","a");
7015         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7016             size >= MSB24+offr && offr != LSB)
7017             pic16_emitcode("xch","a,%s",
7018                      pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7019         else        
7020             pic16_aopPut(AOP(result),"a",MSB16+offr);
7021     }
7022
7023     if(size >= MSB24+offr){
7024         if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7025             l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7026             MOVA(l);
7027         }
7028         pic16_emitcode("rlc","a");
7029         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7030             size >= MSB32+offr && offr != LSB )
7031             pic16_emitcode("xch","a,%s",
7032                      pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7033         else        
7034             pic16_aopPut(AOP(result),"a",MSB24+offr);
7035     }
7036
7037     if(size > MSB32+offr){
7038         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7039             l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7040             MOVA(l);    
7041         }
7042         pic16_emitcode("rlc","a");
7043         pic16_aopPut(AOP(result),"a",MSB32+offr);
7044     }
7045     if(offr != LSB)
7046         pic16_aopPut(AOP(result),zero,LSB);       
7047 }
7048
7049 /*-----------------------------------------------------------------*/
7050 /* genlshFour - shift four byte by a known amount != 0             */
7051 /*-----------------------------------------------------------------*/
7052 static void genlshFour (operand *result, operand *left, int shCount)
7053 {
7054     int size;
7055
7056     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7057     size = AOP_SIZE(result);
7058
7059     /* if shifting more that 3 bytes */
7060     if (shCount >= 24 ) {
7061         shCount -= 24;
7062         if (shCount)
7063             /* lowest order of left goes to the highest
7064             order of the destination */
7065             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7066         else
7067             movLeft2Result(left, LSB, result, MSB32);
7068         pic16_aopPut(AOP(result),zero,LSB);
7069         pic16_aopPut(AOP(result),zero,MSB16);
7070         pic16_aopPut(AOP(result),zero,MSB32);
7071         return;
7072     }
7073
7074     /* more than two bytes */
7075     else if ( shCount >= 16 ) {
7076         /* lower order two bytes goes to higher order two bytes */
7077         shCount -= 16;
7078         /* if some more remaining */
7079         if (shCount)
7080             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7081         else {
7082             movLeft2Result(left, MSB16, result, MSB32);
7083             movLeft2Result(left, LSB, result, MSB24);
7084         }
7085         pic16_aopPut(AOP(result),zero,MSB16);
7086         pic16_aopPut(AOP(result),zero,LSB);
7087         return;
7088     }    
7089
7090     /* if more than 1 byte */
7091     else if ( shCount >= 8 ) {
7092         /* lower order three bytes goes to higher order  three bytes */
7093         shCount -= 8;
7094         if(size == 2){
7095             if(shCount)
7096                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7097             else
7098                 movLeft2Result(left, LSB, result, MSB16);
7099         }
7100         else{   /* size = 4 */
7101             if(shCount == 0){
7102                 movLeft2Result(left, MSB24, result, MSB32);
7103                 movLeft2Result(left, MSB16, result, MSB24);
7104                 movLeft2Result(left, LSB, result, MSB16);
7105                 pic16_aopPut(AOP(result),zero,LSB);
7106             }
7107             else if(shCount == 1)
7108                 shiftLLong(left, result, MSB16);
7109             else{
7110                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7111                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7112                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7113                 pic16_aopPut(AOP(result),zero,LSB);
7114             }
7115         }
7116     }
7117
7118     /* 1 <= shCount <= 7 */
7119     else if(shCount <= 2){
7120         shiftLLong(left, result, LSB);
7121         if(shCount == 2)
7122             shiftLLong(result, result, LSB);
7123     }
7124     /* 3 <= shCount <= 7, optimize */
7125     else{
7126         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7127         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7128         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7129     }
7130 }
7131
7132 /*-----------------------------------------------------------------*/
7133 /* genLeftShiftLiteral - left shifting by known count              */
7134 /*-----------------------------------------------------------------*/
7135 static void genLeftShiftLiteral (operand *left,
7136                                  operand *right,
7137                                  operand *result,
7138                                  iCode *ic)
7139 {    
7140     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7141     int size;
7142
7143     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7144     pic16_freeAsmop(right,NULL,ic,TRUE);
7145
7146     pic16_aopOp(left,ic,FALSE);
7147     pic16_aopOp(result,ic,FALSE);
7148
7149     size = getSize(operandType(result));
7150
7151 #if VIEW_SIZE
7152     pic16_emitcode("; shift left ","result %d, left %d",size,
7153              AOP_SIZE(left));
7154 #endif
7155
7156     /* I suppose that the left size >= result size */
7157     if(shCount == 0){
7158         while(size--){
7159             movLeft2Result(left, size, result, size);
7160         }
7161     }
7162
7163     else if(shCount >= (size * 8))
7164         while(size--)
7165             pic16_aopPut(AOP(result),zero,size);
7166     else{
7167         switch (size) {
7168             case 1:
7169                 genlshOne (result,left,shCount);
7170                 break;
7171
7172             case 2:
7173             case 3:
7174                 genlshTwo (result,left,shCount);
7175                 break;
7176
7177             case 4:
7178                 genlshFour (result,left,shCount);
7179                 break;
7180         }
7181     }
7182     pic16_freeAsmop(left,NULL,ic,TRUE);
7183     pic16_freeAsmop(result,NULL,ic,TRUE);
7184 }
7185
7186 /*-----------------------------------------------------------------*
7187  * genMultiAsm - repeat assembly instruction for size of register.
7188  * if endian == 1, then the high byte (i.e base address + size of 
7189  * register) is used first else the low byte is used first;
7190  *-----------------------------------------------------------------*/
7191 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7192 {
7193
7194   int offset = 0;
7195
7196   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7197
7198   if(!reg)
7199     return;
7200
7201   if(!endian) {
7202     endian = 1;
7203   } else {
7204     endian = -1;
7205     offset = size-1;
7206   }
7207
7208   while(size--) {
7209     pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
7210     offset += endian;
7211   }
7212
7213 }
7214 /*-----------------------------------------------------------------*/
7215 /* genLeftShift - generates code for left shifting                 */
7216 /*-----------------------------------------------------------------*/
7217 static void genLeftShift (iCode *ic)
7218 {
7219   operand *left,*right, *result;
7220   int size, offset;
7221   char *l;
7222   symbol *tlbl , *tlbl1;
7223   pCodeOp *pctemp;
7224
7225   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7226
7227   right = IC_RIGHT(ic);
7228   left  = IC_LEFT(ic);
7229   result = IC_RESULT(ic);
7230
7231   pic16_aopOp(right,ic,FALSE);
7232
7233   /* if the shift count is known then do it 
7234      as efficiently as possible */
7235   if (AOP_TYPE(right) == AOP_LIT) {
7236     genLeftShiftLiteral (left,right,result,ic);
7237     return ;
7238   }
7239
7240   /* shift count is unknown then we have to form 
7241      a loop get the loop count in B : Note: we take
7242      only the lower order byte since shifting
7243      more that 32 bits make no sense anyway, ( the
7244      largest size of an object can be only 32 bits ) */  
7245
7246     
7247   pic16_aopOp(left,ic,FALSE);
7248   pic16_aopOp(result,ic,FALSE);
7249
7250   /* now move the left to the result if they are not the
7251      same */
7252   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7253       AOP_SIZE(result) > 1) {
7254
7255     size = AOP_SIZE(result);
7256     offset=0;
7257     while (size--) {
7258       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7259       if (*l == '@' && (IS_AOP_PREG(result))) {
7260
7261         pic16_emitcode("mov","a,%s",l);
7262         pic16_aopPut(AOP(result),"a",offset);
7263       } else {
7264         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7265         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7266         //pic16_aopPut(AOP(result),l,offset);
7267       }
7268       offset++;
7269     }
7270   }
7271
7272   size = AOP_SIZE(result);
7273
7274   /* if it is only one byte then */
7275   if (size == 1) {
7276     if(optimized_for_speed) {
7277       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7278       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
7279       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7280       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7281       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7282       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7283       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7284       pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
7285       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
7286       pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
7287       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7288       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7289     } else {
7290
7291       tlbl = newiTempLabel(NULL);
7292       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7293         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7294         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7295       }
7296
7297       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7298       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7299       pic16_emitpLabel(tlbl->key);
7300       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7301       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7302       emitSKPC;
7303       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7304     }
7305     goto release ;
7306   }
7307     
7308   if (pic16_sameRegs(AOP(left),AOP(result))) {
7309
7310     tlbl = newiTempLabel(NULL);
7311     pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7312     genMultiAsm(POC_RRCF, result, size,1);
7313     pic16_emitpLabel(tlbl->key);
7314     genMultiAsm(POC_RLCF, result, size,0);
7315     pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7316     emitSKPC;
7317     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7318     goto release;
7319   }
7320
7321   //tlbl = newiTempLabel(NULL);
7322   //offset = 0 ;   
7323   //tlbl1 = newiTempLabel(NULL);
7324
7325   //reAdjustPreg(AOP(result));    
7326     
7327   //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7328   //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7329   //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7330   //MOVA(l);
7331   //pic16_emitcode("add","a,acc");         
7332   //pic16_aopPut(AOP(result),"a",offset++);
7333   //while (--size) {
7334   //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7335   //  MOVA(l);
7336   //  pic16_emitcode("rlc","a");         
7337   //  pic16_aopPut(AOP(result),"a",offset++);
7338   //}
7339   //reAdjustPreg(AOP(result));
7340
7341   //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7342   //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7343
7344
7345   tlbl = newiTempLabel(NULL);
7346   tlbl1= newiTempLabel(NULL);
7347
7348   size = AOP_SIZE(result);
7349   offset = 1;
7350
7351   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7352
7353   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7354
7355   /* offset should be 0, 1 or 3 */
7356   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7357   emitSKPNZ;
7358   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7359
7360   pic16_emitpcode(POC_MOVWF, pctemp);
7361
7362
7363   pic16_emitpLabel(tlbl->key);
7364
7365   emitCLRC;
7366   pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
7367   while(--size)
7368     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
7369
7370   pic16_emitpcode(POC_DECFSZ,  pctemp);
7371   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7372   pic16_emitpLabel(tlbl1->key);
7373
7374   pic16_popReleaseTempReg(pctemp);
7375
7376
7377  release:
7378   pic16_freeAsmop (right,NULL,ic,TRUE);
7379   pic16_freeAsmop(left,NULL,ic,TRUE);
7380   pic16_freeAsmop(result,NULL,ic,TRUE);
7381 }
7382
7383 /*-----------------------------------------------------------------*/
7384 /* genrshOne - right shift a one byte quantity by known count      */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshOne (operand *result, operand *left,
7387                        int shCount, int sign)
7388 {
7389     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7390     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7391 }
7392
7393 /*-----------------------------------------------------------------*/
7394 /* genrshTwo - right shift two bytes by known amount != 0          */
7395 /*-----------------------------------------------------------------*/
7396 static void genrshTwo (operand *result,operand *left,
7397                        int shCount, int sign)
7398 {
7399   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7400   /* if shCount >= 8 */
7401   if (shCount >= 8) {
7402     shCount -= 8 ;
7403     if (shCount)
7404       shiftR1Left2Result(left, MSB16, result, LSB,
7405                          shCount, sign);
7406     else
7407       movLeft2Result(left, MSB16, result, LSB);
7408
7409     pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7410
7411     if(sign) {
7412       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7413       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7414     }
7415   }
7416
7417   /*  1 <= shCount <= 7 */
7418   else
7419     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7420 }
7421
7422 /*-----------------------------------------------------------------*/
7423 /* shiftRLong - shift right one long from left to result           */
7424 /* offl = LSB or MSB16                                             */
7425 /*-----------------------------------------------------------------*/
7426 static void shiftRLong (operand *left, int offl,
7427                         operand *result, int sign)
7428 {
7429     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7430     if(!sign)
7431         pic16_emitcode("clr","c");
7432     MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7433     if(sign)
7434         pic16_emitcode("mov","c,acc.7");
7435     pic16_emitcode("rrc","a");
7436     pic16_aopPut(AOP(result),"a",MSB32-offl);
7437     if(offl == MSB16)
7438         /* add sign of "a" */
7439         pic16_addSign(result, MSB32, sign);
7440
7441     MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7442     pic16_emitcode("rrc","a");
7443     pic16_aopPut(AOP(result),"a",MSB24-offl);
7444
7445     MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7446     pic16_emitcode("rrc","a");
7447     pic16_aopPut(AOP(result),"a",MSB16-offl);
7448
7449     if(offl == LSB){
7450         MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7451         pic16_emitcode("rrc","a");
7452         pic16_aopPut(AOP(result),"a",LSB);
7453     }
7454 }
7455
7456 /*-----------------------------------------------------------------*/
7457 /* genrshFour - shift four byte by a known amount != 0             */
7458 /*-----------------------------------------------------------------*/
7459 static void genrshFour (operand *result, operand *left,
7460                         int shCount, int sign)
7461 {
7462   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7463   /* if shifting more that 3 bytes */
7464   if(shCount >= 24 ) {
7465     shCount -= 24;
7466     if(shCount)
7467       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7468     else
7469       movLeft2Result(left, MSB32, result, LSB);
7470
7471     pic16_addSign(result, MSB16, sign);
7472   }
7473   else if(shCount >= 16){
7474     shCount -= 16;
7475     if(shCount)
7476       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7477     else{
7478       movLeft2Result(left, MSB24, result, LSB);
7479       movLeft2Result(left, MSB32, result, MSB16);
7480     }
7481     pic16_addSign(result, MSB24, sign);
7482   }
7483   else if(shCount >= 8){
7484     shCount -= 8;
7485     if(shCount == 1)
7486       shiftRLong(left, MSB16, result, sign);
7487     else if(shCount == 0){
7488       movLeft2Result(left, MSB16, result, LSB);
7489       movLeft2Result(left, MSB24, result, MSB16);
7490       movLeft2Result(left, MSB32, result, MSB24);
7491       pic16_addSign(result, MSB32, sign);
7492     }
7493     else{
7494       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7495       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7496       /* the last shift is signed */
7497       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7498       pic16_addSign(result, MSB32, sign);
7499     }
7500   }
7501   else{   /* 1 <= shCount <= 7 */
7502     if(shCount <= 2){
7503       shiftRLong(left, LSB, result, sign);
7504       if(shCount == 2)
7505         shiftRLong(result, LSB, result, sign);
7506     }
7507     else{
7508       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7509       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7510       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7511     }
7512   }
7513 }
7514
7515 /*-----------------------------------------------------------------*/
7516 /* genRightShiftLiteral - right shifting by known count            */
7517 /*-----------------------------------------------------------------*/
7518 static void genRightShiftLiteral (operand *left,
7519                                   operand *right,
7520                                   operand *result,
7521                                   iCode *ic,
7522                                   int sign)
7523 {    
7524   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7525   int lsize,res_size;
7526
7527   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7528   pic16_freeAsmop(right,NULL,ic,TRUE);
7529
7530   pic16_aopOp(left,ic,FALSE);
7531   pic16_aopOp(result,ic,FALSE);
7532
7533 #if VIEW_SIZE
7534   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7535                  AOP_SIZE(left));
7536 #endif
7537
7538   lsize = pic16_getDataSize(left);
7539   res_size = pic16_getDataSize(result);
7540   /* test the LEFT size !!! */
7541
7542   /* I suppose that the left size >= result size */
7543   if(shCount == 0){
7544     while(res_size--)
7545       movLeft2Result(left, lsize, result, res_size);
7546   }
7547
7548   else if(shCount >= (lsize * 8)){
7549
7550     if(res_size == 1) {
7551       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7552       if(sign) {
7553         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7554         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7555       }
7556     } else {
7557
7558       if(sign) {
7559         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7560         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7561         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7562         while(res_size--)
7563           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7564
7565       } else {
7566
7567         while(res_size--)
7568           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7569       }
7570     }
7571   } else {
7572
7573     switch (res_size) {
7574     case 1:
7575       genrshOne (result,left,shCount,sign);
7576       break;
7577
7578     case 2:
7579       genrshTwo (result,left,shCount,sign);
7580       break;
7581
7582     case 4:
7583       genrshFour (result,left,shCount,sign);
7584       break;
7585     default :
7586       break;
7587     }
7588
7589   }
7590
7591   pic16_freeAsmop(left,NULL,ic,TRUE);
7592   pic16_freeAsmop(result,NULL,ic,TRUE);
7593 }
7594
7595 /*-----------------------------------------------------------------*/
7596 /* genSignedRightShift - right shift of signed number              */
7597 /*-----------------------------------------------------------------*/
7598 static void genSignedRightShift (iCode *ic)
7599 {
7600   operand *right, *left, *result;
7601   int size, offset;
7602   //  char *l;
7603   symbol *tlbl, *tlbl1 ;
7604   pCodeOp *pctemp;
7605
7606   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7607
7608   /* we do it the hard way put the shift count in b
7609      and loop thru preserving the sign */
7610   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7611
7612   right = IC_RIGHT(ic);
7613   left  = IC_LEFT(ic);
7614   result = IC_RESULT(ic);
7615
7616   pic16_aopOp(right,ic,FALSE);  
7617   pic16_aopOp(left,ic,FALSE);
7618   pic16_aopOp(result,ic,FALSE);
7619
7620
7621   if ( AOP_TYPE(right) == AOP_LIT) {
7622     genRightShiftLiteral (left,right,result,ic,1);
7623     return ;
7624   }
7625   /* shift count is unknown then we have to form 
7626      a loop get the loop count in B : Note: we take
7627      only the lower order byte since shifting
7628      more that 32 bits make no sense anyway, ( the
7629      largest size of an object can be only 32 bits ) */  
7630
7631   //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7632   //pic16_emitcode("inc","b");
7633   //pic16_freeAsmop (right,NULL,ic,TRUE);
7634   //pic16_aopOp(left,ic,FALSE);
7635   //pic16_aopOp(result,ic,FALSE);
7636
7637   /* now move the left to the result if they are not the
7638      same */
7639   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7640       AOP_SIZE(result) > 1) {
7641
7642     size = AOP_SIZE(result);
7643     offset=0;
7644     while (size--) { 
7645       /*
7646         l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7647         if (*l == '@' && IS_AOP_PREG(result)) {
7648
7649         pic16_emitcode("mov","a,%s",l);
7650         pic16_aopPut(AOP(result),"a",offset);
7651         } else
7652         pic16_aopPut(AOP(result),l,offset);
7653       */
7654       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7655       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7656
7657       offset++;
7658     }
7659   }
7660
7661   /* mov the highest order bit to OVR */    
7662   tlbl = newiTempLabel(NULL);
7663   tlbl1= newiTempLabel(NULL);
7664
7665   size = AOP_SIZE(result);
7666   offset = size - 1;
7667
7668   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7669
7670   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7671
7672   /* offset should be 0, 1 or 3 */
7673   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7674   emitSKPNZ;
7675   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7676
7677   pic16_emitpcode(POC_MOVWF, pctemp);
7678
7679
7680   pic16_emitpLabel(tlbl->key);
7681
7682   pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
7683   pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
7684
7685   while(--size) {
7686     pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
7687   }
7688
7689   pic16_emitpcode(POC_DECFSZ,  pctemp);
7690   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7691   pic16_emitpLabel(tlbl1->key);
7692
7693   pic16_popReleaseTempReg(pctemp);
7694 #if 0
7695   size = AOP_SIZE(result);
7696   offset = size - 1;
7697   pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7698   pic16_emitcode("rlc","a");
7699   pic16_emitcode("mov","ov,c");
7700   /* if it is only one byte then */
7701   if (size == 1) {
7702     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7703     MOVA(l);
7704     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7706     pic16_emitcode("mov","c,ov");
7707     pic16_emitcode("rrc","a");
7708     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7709     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7710     pic16_aopPut(AOP(result),"a",0);
7711     goto release ;
7712   }
7713
7714   reAdjustPreg(AOP(result));
7715   pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7716   pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7717   pic16_emitcode("mov","c,ov");
7718   while (size--) {
7719     l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7720     MOVA(l);
7721     pic16_emitcode("rrc","a");         
7722     pic16_aopPut(AOP(result),"a",offset--);
7723   }
7724   reAdjustPreg(AOP(result));
7725   pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7726   pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7727
7728  release:
7729 #endif
7730
7731   pic16_freeAsmop(left,NULL,ic,TRUE);
7732   pic16_freeAsmop(result,NULL,ic,TRUE);
7733   pic16_freeAsmop(right,NULL,ic,TRUE);
7734 }
7735
7736 /*-----------------------------------------------------------------*/
7737 /* genRightShift - generate code for right shifting                */
7738 /*-----------------------------------------------------------------*/
7739 static void genRightShift (iCode *ic)
7740 {
7741     operand *right, *left, *result;
7742     sym_link *retype ;
7743     int size, offset;
7744     char *l;
7745     symbol *tlbl, *tlbl1 ;
7746
7747     /* if signed then we do it the hard way preserve the
7748     sign bit moving it inwards */
7749     retype = getSpec(operandType(IC_RESULT(ic)));
7750     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7751
7752     if (!SPEC_USIGN(retype)) {
7753         genSignedRightShift (ic);
7754         return ;
7755     }
7756
7757     /* signed & unsigned types are treated the same : i.e. the
7758     signed is NOT propagated inwards : quoting from the
7759     ANSI - standard : "for E1 >> E2, is equivalent to division
7760     by 2**E2 if unsigned or if it has a non-negative value,
7761     otherwise the result is implementation defined ", MY definition
7762     is that the sign does not get propagated */
7763
7764     right = IC_RIGHT(ic);
7765     left  = IC_LEFT(ic);
7766     result = IC_RESULT(ic);
7767
7768     pic16_aopOp(right,ic,FALSE);
7769
7770     /* if the shift count is known then do it 
7771     as efficiently as possible */
7772     if (AOP_TYPE(right) == AOP_LIT) {
7773         genRightShiftLiteral (left,right,result,ic, 0);
7774         return ;
7775     }
7776
7777     /* shift count is unknown then we have to form 
7778     a loop get the loop count in B : Note: we take
7779     only the lower order byte since shifting
7780     more that 32 bits make no sense anyway, ( the
7781     largest size of an object can be only 32 bits ) */  
7782
7783     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7784     pic16_emitcode("inc","b");
7785     pic16_aopOp(left,ic,FALSE);
7786     pic16_aopOp(result,ic,FALSE);
7787
7788     /* now move the left to the result if they are not the
7789     same */
7790     if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7791         AOP_SIZE(result) > 1) {
7792
7793         size = AOP_SIZE(result);
7794         offset=0;
7795         while (size--) {
7796             l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7797             if (*l == '@' && IS_AOP_PREG(result)) {
7798
7799                 pic16_emitcode("mov","a,%s",l);
7800                 pic16_aopPut(AOP(result),"a",offset);
7801             } else
7802                 pic16_aopPut(AOP(result),l,offset);
7803             offset++;
7804         }
7805     }
7806
7807     tlbl = newiTempLabel(NULL);
7808     tlbl1= newiTempLabel(NULL);
7809     size = AOP_SIZE(result);
7810     offset = size - 1;
7811
7812     /* if it is only one byte then */
7813     if (size == 1) {
7814
7815       tlbl = newiTempLabel(NULL);
7816       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7817         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7818         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7819       }
7820
7821       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7822       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7823       pic16_emitpLabel(tlbl->key);
7824       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7825       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7826       emitSKPC;
7827       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7828
7829       goto release ;
7830     }
7831
7832     reAdjustPreg(AOP(result));
7833     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7834     pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7835     CLRC;
7836     while (size--) {
7837         l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7838         MOVA(l);
7839         pic16_emitcode("rrc","a");         
7840         pic16_aopPut(AOP(result),"a",offset--);
7841     }
7842     reAdjustPreg(AOP(result));
7843
7844     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7845     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7846
7847 release:
7848     pic16_freeAsmop(left,NULL,ic,TRUE);
7849     pic16_freeAsmop (right,NULL,ic,TRUE);
7850     pic16_freeAsmop(result,NULL,ic,TRUE);
7851 }
7852
7853 /*-----------------------------------------------------------------*/
7854 /* genUnpackBits - generates code for unpacking bits               */
7855 /*-----------------------------------------------------------------*/
7856 static void genUnpackBits (operand *result, char *rname, int ptype)
7857 {    
7858     int shCnt ;
7859     int rlen = 0 ;
7860     sym_link *etype;
7861     int offset = 0 ;
7862
7863     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7864     etype = getSpec(operandType(result));
7865
7866     /* read the first byte  */
7867     switch (ptype) {
7868
7869     case POINTER:
7870     case IPOINTER:
7871         pic16_emitcode("mov","a,@%s",rname);
7872         break;
7873         
7874     case PPOINTER:
7875         pic16_emitcode("movx","a,@%s",rname);
7876         break;
7877         
7878     case FPOINTER:
7879         pic16_emitcode("movx","a,@dptr");
7880         break;
7881
7882     case CPOINTER:
7883         pic16_emitcode("clr","a");
7884         pic16_emitcode("movc","a","@a+dptr");
7885         break;
7886
7887     case GPOINTER:
7888         pic16_emitcode("lcall","__gptrget");
7889         break;
7890     }
7891
7892     /* if we have bitdisplacement then it fits   */
7893     /* into this byte completely or if length is */
7894     /* less than a byte                          */
7895     if ((shCnt = SPEC_BSTR(etype)) || 
7896         (SPEC_BLEN(etype) <= 8))  {
7897
7898         /* shift right acc */
7899         AccRsh(shCnt);
7900
7901         pic16_emitcode("anl","a,#0x%02x",
7902                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7903         pic16_aopPut(AOP(result),"a",offset);
7904         return ;
7905     }
7906
7907     /* bit field did not fit in a byte  */
7908     rlen = SPEC_BLEN(etype) - 8;
7909     pic16_aopPut(AOP(result),"a",offset++);
7910
7911     while (1)  {
7912
7913         switch (ptype) {
7914         case POINTER:
7915         case IPOINTER:
7916             pic16_emitcode("inc","%s",rname);
7917             pic16_emitcode("mov","a,@%s",rname);
7918             break;
7919             
7920         case PPOINTER:
7921             pic16_emitcode("inc","%s",rname);
7922             pic16_emitcode("movx","a,@%s",rname);
7923             break;
7924
7925         case FPOINTER:
7926             pic16_emitcode("inc","dptr");
7927             pic16_emitcode("movx","a,@dptr");
7928             break;
7929             
7930         case CPOINTER:
7931             pic16_emitcode("clr","a");
7932             pic16_emitcode("inc","dptr");
7933             pic16_emitcode("movc","a","@a+dptr");
7934             break;
7935             
7936         case GPOINTER:
7937             pic16_emitcode("inc","dptr");
7938             pic16_emitcode("lcall","__gptrget");
7939             break;
7940         }
7941
7942         rlen -= 8;            
7943         /* if we are done */
7944         if ( rlen <= 0 )
7945             break ;
7946         
7947         pic16_aopPut(AOP(result),"a",offset++);
7948                               
7949     }
7950     
7951     if (rlen) {
7952         pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7953         pic16_aopPut(AOP(result),"a",offset);          
7954     }
7955     
7956     return ;
7957 }
7958
7959 #if 0
7960 /*-----------------------------------------------------------------*/
7961 /* genDataPointerGet - generates code when ptr offset is known     */
7962 /*-----------------------------------------------------------------*/
7963 static void genDataPointerGet (operand *left, 
7964                                operand *result, 
7965                                iCode *ic)
7966 {
7967   int size , offset = 0;
7968
7969
7970   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7971
7972
7973   /* optimization - most of the time, left and result are the same
7974    * address, but different types. for the pic code, we could omit
7975    * the following
7976    */
7977
7978   pic16_aopOp(result,ic,TRUE);
7979
7980   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7981
7982   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7983
7984   size = AOP_SIZE(result);
7985
7986   while (size--) {
7987     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7988     offset++;
7989   }
7990
7991   pic16_freeAsmop(left,NULL,ic,TRUE);
7992   pic16_freeAsmop(result,NULL,ic,TRUE);
7993 }
7994 #endif
7995 /*-----------------------------------------------------------------*/
7996 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
7997 /*-----------------------------------------------------------------*/
7998 static void genNearPointerGet (operand *left, 
7999                                operand *result, 
8000                                iCode *ic)
8001 {
8002     asmop *aop = NULL;
8003     //regs *preg = NULL ;
8004     char *rname ;
8005     sym_link *rtype, *retype;
8006     sym_link *ltype = operandType(left);    
8007     //char buffer[80];
8008
8009     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8010
8011     rtype = operandType(result);
8012     retype= getSpec(rtype);
8013     
8014     pic16_aopOp(left,ic,FALSE);
8015     
8016     /* if left is rematerialisable and
8017        result is not bit variable type and
8018        the left is pointer to data space i.e
8019        lower 128 bytes of space */
8020     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8021         !IS_BITVAR(retype)         &&
8022         DCL_TYPE(ltype) == POINTER) {
8023       //genDataPointerGet (left,result,ic);
8024         return ;
8025     }
8026     
8027     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8028
8029         /* if the value is already in a pointer register
8030        then don't need anything more */
8031     if (!AOP_INPREG(AOP(left))) {
8032         /* otherwise get a free pointer register */
8033     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8034 /*
8035         aop = newAsmop(0);
8036         preg = getFreePtr(ic,&aop,FALSE);
8037         pic16_emitcode("mov","%s,%s",
8038                 preg->name,
8039                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8040         rname = preg->name ;
8041 */
8042     rname ="BAD";
8043     } else
8044         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8045     
8046     pic16_aopOp (result,ic,FALSE);
8047     
8048       /* if bitfield then unpack the bits */
8049     if (IS_BITVAR(retype)) 
8050         genUnpackBits (result,rname,POINTER);
8051     else {
8052         /* we have can just get the values */
8053       int size = AOP_SIZE(result);
8054       int offset = 0 ;  
8055         
8056       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8057
8058       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8059       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8060       while(size--) {
8061         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8062         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8063         if(size)
8064           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8065       }
8066 /*
8067         while (size--) {
8068             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8069
8070                 pic16_emitcode("mov","a,@%s",rname);
8071                 pic16_aopPut(AOP(result),"a",offset);
8072             } else {
8073                 sprintf(buffer,"@%s",rname);
8074                 pic16_aopPut(AOP(result),buffer,offset);
8075             }
8076             offset++ ;
8077             if (size)
8078                 pic16_emitcode("inc","%s",rname);
8079         }
8080 */
8081     }
8082
8083     /* now some housekeeping stuff */
8084     if (aop) {
8085         /* we had to allocate for this iCode */
8086     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8087         pic16_freeAsmop(NULL,aop,ic,TRUE);
8088     } else { 
8089         /* we did not allocate which means left
8090            already in a pointer register, then
8091            if size > 0 && this could be used again
8092            we have to point it back to where it 
8093            belongs */
8094     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8095         if (AOP_SIZE(result) > 1 &&
8096             !OP_SYMBOL(left)->remat &&
8097             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8098               ic->depth )) {
8099             int size = AOP_SIZE(result) - 1;
8100             while (size--)
8101                 pic16_emitcode("dec","%s",rname);
8102         }
8103     }
8104
8105     /* done */
8106     pic16_freeAsmop(left,NULL,ic,TRUE);
8107     pic16_freeAsmop(result,NULL,ic,TRUE);
8108      
8109 }
8110
8111 /*-----------------------------------------------------------------*/
8112 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
8113 /*-----------------------------------------------------------------*/
8114 static void genPagedPointerGet (operand *left, 
8115                                operand *result, 
8116                                iCode *ic)
8117 {
8118     asmop *aop = NULL;
8119     regs *preg = NULL ;
8120     char *rname ;
8121     sym_link *rtype, *retype;    
8122
8123     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8124
8125     rtype = operandType(result);
8126     retype= getSpec(rtype);
8127     
8128     pic16_aopOp(left,ic,FALSE);
8129
8130   /* if the value is already in a pointer register
8131        then don't need anything more */
8132     if (!AOP_INPREG(AOP(left))) {
8133         /* otherwise get a free pointer register */
8134         aop = newAsmop(0);
8135         preg = getFreePtr(ic,&aop,FALSE);
8136         pic16_emitcode("mov","%s,%s",
8137                 preg->name,
8138                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8139         rname = preg->name ;
8140     } else
8141         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8142     
8143     pic16_freeAsmop(left,NULL,ic,TRUE);
8144     pic16_aopOp (result,ic,FALSE);
8145
8146     /* if bitfield then unpack the bits */
8147     if (IS_BITVAR(retype)) 
8148         genUnpackBits (result,rname,PPOINTER);
8149     else {
8150         /* we have can just get the values */
8151         int size = AOP_SIZE(result);
8152         int offset = 0 ;        
8153         
8154         while (size--) {
8155             
8156             pic16_emitcode("movx","a,@%s",rname);
8157             pic16_aopPut(AOP(result),"a",offset);
8158             
8159             offset++ ;
8160             
8161             if (size)
8162                 pic16_emitcode("inc","%s",rname);
8163         }
8164     }
8165
8166     /* now some housekeeping stuff */
8167     if (aop) {
8168         /* we had to allocate for this iCode */
8169         pic16_freeAsmop(NULL,aop,ic,TRUE);
8170     } else { 
8171         /* we did not allocate which means left
8172            already in a pointer register, then
8173            if size > 0 && this could be used again
8174            we have to point it back to where it 
8175            belongs */
8176         if (AOP_SIZE(result) > 1 &&
8177             !OP_SYMBOL(left)->remat &&
8178             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8179               ic->depth )) {
8180             int size = AOP_SIZE(result) - 1;
8181             while (size--)
8182                 pic16_emitcode("dec","%s",rname);
8183         }
8184     }
8185
8186     /* done */
8187     pic16_freeAsmop(result,NULL,ic,TRUE);
8188     
8189         
8190 }
8191
8192 /*-----------------------------------------------------------------*/
8193 /* genFarPointerGet - gget value from far space                    */
8194 /*-----------------------------------------------------------------*/
8195 static void genFarPointerGet (operand *left,
8196                               operand *result, iCode *ic)
8197 {
8198     int size, offset ;
8199     sym_link *retype = getSpec(operandType(result));
8200
8201     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8202
8203     pic16_aopOp(left,ic,FALSE);
8204
8205     /* if the operand is already in dptr 
8206     then we do nothing else we move the value to dptr */
8207     if (AOP_TYPE(left) != AOP_STR) {
8208         /* if this is remateriazable */
8209         if (AOP_TYPE(left) == AOP_IMMD)
8210             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8211         else { /* we need to get it byte by byte */
8212             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8213             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8214             if (options.model == MODEL_FLAT24)
8215             {
8216                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8217             }
8218         }
8219     }
8220     /* so dptr know contains the address */
8221     pic16_freeAsmop(left,NULL,ic,TRUE);
8222     pic16_aopOp(result,ic,FALSE);
8223
8224     /* if bit then unpack */
8225     if (IS_BITVAR(retype)) 
8226         genUnpackBits(result,"dptr",FPOINTER);
8227     else {
8228         size = AOP_SIZE(result);
8229         offset = 0 ;
8230
8231         while (size--) {
8232             pic16_emitcode("movx","a,@dptr");
8233             pic16_aopPut(AOP(result),"a",offset++);
8234             if (size)
8235                 pic16_emitcode("inc","dptr");
8236         }
8237     }
8238
8239     pic16_freeAsmop(result,NULL,ic,TRUE);
8240 }
8241 #if 0
8242 /*-----------------------------------------------------------------*/
8243 /* genCodePointerGet - get value from code space                  */
8244 /*-----------------------------------------------------------------*/
8245 static void genCodePointerGet (operand *left,
8246                                 operand *result, iCode *ic)
8247 {
8248     int size, offset ;
8249     sym_link *retype = getSpec(operandType(result));
8250
8251     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8252
8253     pic16_aopOp(left,ic,FALSE);
8254
8255     /* if the operand is already in dptr 
8256     then we do nothing else we move the value to dptr */
8257     if (AOP_TYPE(left) != AOP_STR) {
8258         /* if this is remateriazable */
8259         if (AOP_TYPE(left) == AOP_IMMD)
8260             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8261         else { /* we need to get it byte by byte */
8262             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8263             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8264             if (options.model == MODEL_FLAT24)
8265             {
8266                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8267             }
8268         }
8269     }
8270     /* so dptr know contains the address */
8271     pic16_freeAsmop(left,NULL,ic,TRUE);
8272     pic16_aopOp(result,ic,FALSE);
8273
8274     /* if bit then unpack */
8275     if (IS_BITVAR(retype)) 
8276         genUnpackBits(result,"dptr",CPOINTER);
8277     else {
8278         size = AOP_SIZE(result);
8279         offset = 0 ;
8280
8281         while (size--) {
8282             pic16_emitcode("clr","a");
8283             pic16_emitcode("movc","a,@a+dptr");
8284             pic16_aopPut(AOP(result),"a",offset++);
8285             if (size)
8286                 pic16_emitcode("inc","dptr");
8287         }
8288     }
8289
8290     pic16_freeAsmop(result,NULL,ic,TRUE);
8291 }
8292 #endif
8293 /*-----------------------------------------------------------------*/
8294 /* genGenPointerGet - gget value from generic pointer space        */
8295 /*-----------------------------------------------------------------*/
8296 static void genGenPointerGet (operand *left,
8297                               operand *result, iCode *ic)
8298 {
8299   int size, offset ;
8300   sym_link *retype = getSpec(operandType(result));
8301
8302   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8303   pic16_aopOp(left,ic,FALSE);
8304   pic16_aopOp(result,ic,FALSE);
8305
8306
8307   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8308
8309   /* if the operand is already in dptr 
8310      then we do nothing else we move the value to dptr */
8311   //  if (AOP_TYPE(left) != AOP_STR) {
8312     /* if this is remateriazable */
8313     if (AOP_TYPE(left) == AOP_IMMD) {
8314       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8315       pic16_emitcode("mov","b,#%d",pointerCode(retype));
8316     }
8317     else { /* we need to get it byte by byte */
8318
8319       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8320       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8321
8322       size = AOP_SIZE(result);
8323       offset = 0 ;
8324
8325       while(size--) {
8326         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8327         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8328         if(size)
8329           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8330       }
8331       goto release;
8332     }
8333     //}
8334   /* so dptr know contains the address */
8335
8336   /* if bit then unpack */
8337   //if (IS_BITVAR(retype)) 
8338   //  genUnpackBits(result,"dptr",GPOINTER);
8339
8340  release:
8341   pic16_freeAsmop(left,NULL,ic,TRUE);
8342   pic16_freeAsmop(result,NULL,ic,TRUE);
8343
8344 }
8345
8346 /*-----------------------------------------------------------------*/
8347 /* genConstPointerGet - get value from const generic pointer space */
8348 /*-----------------------------------------------------------------*/
8349 static void genConstPointerGet (operand *left,
8350                                 operand *result, iCode *ic)
8351 {
8352   //sym_link *retype = getSpec(operandType(result));
8353   symbol *albl = newiTempLabel(NULL);
8354   symbol *blbl = newiTempLabel(NULL);
8355   PIC_OPCODE poc;
8356
8357   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8358   pic16_aopOp(left,ic,FALSE);
8359   pic16_aopOp(result,ic,FALSE);
8360
8361
8362   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8363
8364   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8365
8366   pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8367   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8368   pic16_emitpLabel(albl->key);
8369
8370   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8371     
8372   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8373   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8374   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8375   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8376
8377   pic16_emitpLabel(blbl->key);
8378
8379   pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8380
8381
8382   pic16_freeAsmop(left,NULL,ic,TRUE);
8383   pic16_freeAsmop(result,NULL,ic,TRUE);
8384
8385 }
8386 /*-----------------------------------------------------------------*/
8387 /* genPointerGet - generate code for pointer get                   */
8388 /*-----------------------------------------------------------------*/
8389 static void genPointerGet (iCode *ic)
8390 {
8391     operand *left, *result ;
8392     sym_link *type, *etype;
8393     int p_type;
8394
8395     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8396
8397     left = IC_LEFT(ic);
8398     result = IC_RESULT(ic) ;
8399
8400     /* depending on the type of pointer we need to
8401     move it to the correct pointer register */
8402     type = operandType(left);
8403     etype = getSpec(type);
8404
8405     if (IS_PTR_CONST(type))
8406       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8407
8408     /* if left is of type of pointer then it is simple */
8409     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8410         p_type = DCL_TYPE(type);
8411     else {
8412         /* we have to go by the storage class */
8413         p_type = PTR_TYPE(SPEC_OCLS(etype));
8414
8415         DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8416
8417         if (SPEC_OCLS(etype)->codesp ) {
8418           DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8419           //p_type = CPOINTER ; 
8420         }
8421         else
8422             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8423               DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8424                /*p_type = FPOINTER ;*/ 
8425             else
8426                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8427                   DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8428 /*                  p_type = PPOINTER; */
8429                 else
8430                     if (SPEC_OCLS(etype) == idata )
8431                       DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8432 /*                      p_type = IPOINTER; */
8433                     else
8434                       DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8435 /*                      p_type = POINTER ; */
8436     }
8437
8438     /* now that we have the pointer type we assign
8439     the pointer values */
8440     switch (p_type) {
8441
8442     case POINTER:       
8443     case IPOINTER:
8444         genNearPointerGet (left,result,ic);
8445         break;
8446
8447     case PPOINTER:
8448         genPagedPointerGet(left,result,ic);
8449         break;
8450
8451     case FPOINTER:
8452         genFarPointerGet (left,result,ic);
8453         break;
8454
8455     case CPOINTER:
8456         genConstPointerGet (left,result,ic);
8457         //pic16_emitcodePointerGet (left,result,ic);
8458         break;
8459
8460     case GPOINTER:
8461       if (IS_PTR_CONST(type))
8462         genConstPointerGet (left,result,ic);
8463       else
8464         genGenPointerGet (left,result,ic);
8465       break;
8466     }
8467
8468 }
8469
8470 /*-----------------------------------------------------------------*/
8471 /* genPackBits - generates code for packed bit storage             */
8472 /*-----------------------------------------------------------------*/
8473 static void genPackBits (sym_link    *etype ,
8474                          operand *right ,
8475                          char *rname, int p_type)
8476 {
8477     int shCount = 0 ;
8478     int offset = 0  ;
8479     int rLen = 0 ;
8480     int blen, bstr ;   
8481     char *l ;
8482
8483     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8484     blen = SPEC_BLEN(etype);
8485     bstr = SPEC_BSTR(etype);
8486
8487     l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8488     MOVA(l);   
8489
8490     /* if the bit lenth is less than or    */
8491     /* it exactly fits a byte then         */
8492     if (SPEC_BLEN(etype) <= 8 )  {
8493         shCount = SPEC_BSTR(etype) ;
8494
8495         /* shift left acc */
8496         AccLsh(shCount);
8497
8498         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8499
8500
8501             switch (p_type) {
8502                 case POINTER:
8503                     pic16_emitcode ("mov","b,a");
8504                     pic16_emitcode("mov","a,@%s",rname);
8505                     break;
8506
8507                 case FPOINTER:
8508                     pic16_emitcode ("mov","b,a");
8509                     pic16_emitcode("movx","a,@dptr");
8510                     break;
8511
8512                 case GPOINTER:
8513                     pic16_emitcode ("push","b");
8514                     pic16_emitcode ("push","acc");
8515                     pic16_emitcode ("lcall","__gptrget");
8516                     pic16_emitcode ("pop","b");
8517                     break;
8518             }
8519
8520             pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8521                       ((unsigned char)(0xFF << (blen+bstr)) | 
8522                        (unsigned char)(0xFF >> (8-bstr)) ) );
8523             pic16_emitcode ("orl","a,b");
8524             if (p_type == GPOINTER)
8525                 pic16_emitcode("pop","b");
8526         }
8527     }
8528
8529     switch (p_type) {
8530         case POINTER:
8531             pic16_emitcode("mov","@%s,a",rname);
8532             break;
8533
8534         case FPOINTER:
8535             pic16_emitcode("movx","@dptr,a");
8536             break;
8537
8538         case GPOINTER:
8539             DEBUGpic16_emitcode(";lcall","__gptrput");
8540             break;
8541     }
8542
8543     /* if we r done */
8544     if ( SPEC_BLEN(etype) <= 8 )
8545         return ;
8546
8547     pic16_emitcode("inc","%s",rname);
8548     rLen = SPEC_BLEN(etype) ;     
8549
8550     /* now generate for lengths greater than one byte */
8551     while (1) {
8552
8553         l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8554
8555         rLen -= 8 ;
8556         if (rLen <= 0 )
8557             break ;
8558
8559         switch (p_type) {
8560             case POINTER:
8561                 if (*l == '@') {
8562                     MOVA(l);
8563                     pic16_emitcode("mov","@%s,a",rname);
8564                 } else
8565                     pic16_emitcode("mov","@%s,%s",rname,l);
8566                 break;
8567
8568             case FPOINTER:
8569                 MOVA(l);
8570                 pic16_emitcode("movx","@dptr,a");
8571                 break;
8572
8573             case GPOINTER:
8574                 MOVA(l);
8575                 DEBUGpic16_emitcode(";lcall","__gptrput");
8576                 break;  
8577         }   
8578         pic16_emitcode ("inc","%s",rname);
8579     }
8580
8581     MOVA(l);
8582
8583     /* last last was not complete */
8584     if (rLen)   {
8585         /* save the byte & read byte */
8586         switch (p_type) {
8587             case POINTER:
8588                 pic16_emitcode ("mov","b,a");
8589                 pic16_emitcode("mov","a,@%s",rname);
8590                 break;
8591
8592             case FPOINTER:
8593                 pic16_emitcode ("mov","b,a");
8594                 pic16_emitcode("movx","a,@dptr");
8595                 break;
8596
8597             case GPOINTER:
8598                 pic16_emitcode ("push","b");
8599                 pic16_emitcode ("push","acc");
8600                 pic16_emitcode ("lcall","__gptrget");
8601                 pic16_emitcode ("pop","b");
8602                 break;
8603         }
8604
8605         pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8606         pic16_emitcode ("orl","a,b");
8607     }
8608
8609     if (p_type == GPOINTER)
8610         pic16_emitcode("pop","b");
8611
8612     switch (p_type) {
8613
8614     case POINTER:
8615         pic16_emitcode("mov","@%s,a",rname);
8616         break;
8617         
8618     case FPOINTER:
8619         pic16_emitcode("movx","@dptr,a");
8620         break;
8621         
8622     case GPOINTER:
8623         DEBUGpic16_emitcode(";lcall","__gptrput");
8624         break;                  
8625     }
8626 }
8627 /*-----------------------------------------------------------------*/
8628 /* genDataPointerSet - remat pointer to data space                 */
8629 /*-----------------------------------------------------------------*/
8630 static void genDataPointerSet(operand *right,
8631                               operand *result,
8632                               iCode *ic)
8633 {
8634     int size, offset = 0 ;
8635     char *l, buffer[256];
8636
8637     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8638     pic16_aopOp(right,ic,FALSE);
8639     
8640     l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8641     size = AOP_SIZE(right);
8642 /*
8643     if ( AOP_TYPE(result) == AOP_PCODE) {
8644       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8645               AOP(result)->aopu.pcop->name,
8646               PCOI(AOP(result)->aopu.pcop)->offset);
8647     }
8648 */
8649
8650     // tsd, was l+1 - the underline `_' prefix was being stripped
8651     while (size--) {
8652       if (offset) {
8653         sprintf(buffer,"(%s + %d)",l,offset);
8654         fprintf(stderr,"oops  %s\n",buffer);
8655       } else
8656         sprintf(buffer,"%s",l);
8657
8658         if (AOP_TYPE(right) == AOP_LIT) {
8659           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8660           lit = lit >> (8*offset);
8661           if(lit&0xff) {
8662             pic16_emitcode("movlw","%d",lit);
8663             pic16_emitcode("movwf","%s",buffer);
8664
8665             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8666             //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8667             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8668
8669           } else {
8670             pic16_emitcode("clrf","%s",buffer);
8671             //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8672             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8673           }
8674         }else {
8675           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8676           pic16_emitcode("movwf","%s",buffer);
8677
8678           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8679           //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8680           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8681
8682         }
8683
8684         offset++;
8685     }
8686
8687     pic16_freeAsmop(right,NULL,ic,TRUE);
8688     pic16_freeAsmop(result,NULL,ic,TRUE);
8689 }
8690
8691 /*-----------------------------------------------------------------*/
8692 /* genNearPointerSet - pic16_emitcode for near pointer put                */
8693 /*-----------------------------------------------------------------*/
8694 static void genNearPointerSet (operand *right,
8695                                operand *result, 
8696                                iCode *ic)
8697 {
8698   asmop *aop = NULL;
8699   char *l;
8700   sym_link *retype;
8701   sym_link *ptype = operandType(result);
8702
8703     
8704   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8705   retype= getSpec(operandType(right));
8706
8707   pic16_aopOp(result,ic,FALSE);
8708
8709     
8710   /* if the result is rematerializable &
8711      in data space & not a bit variable */
8712   //if (AOP_TYPE(result) == AOP_IMMD &&
8713   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8714       DCL_TYPE(ptype) == POINTER   &&
8715       !IS_BITVAR(retype)) {
8716     genDataPointerSet (right,result,ic);
8717     pic16_freeAsmop(result,NULL,ic,TRUE);
8718     return;
8719   }
8720
8721   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8722   pic16_aopOp(right,ic,FALSE);
8723   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8724
8725   /* if the value is already in a pointer register
8726      then don't need anything more */
8727   if (!AOP_INPREG(AOP(result))) {
8728     /* otherwise get a free pointer register */
8729     //aop = newAsmop(0);
8730     //preg = getFreePtr(ic,&aop,FALSE);
8731     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8732     //pic16_emitcode("mov","%s,%s",
8733     //         preg->name,
8734     //         pic16_aopGet(AOP(result),0,FALSE,TRUE));
8735     //rname = preg->name ;
8736     //pic16_emitcode("movwf","fsr0");
8737     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8738     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8739     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8740     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8741     goto release;
8742
8743   }// else
8744   //   rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8745
8746
8747   /* if bitfield then unpack the bits */
8748   if (IS_BITVAR(retype)) {
8749     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8750            "The programmer is obviously confused");
8751     //genPackBits (retype,right,rname,POINTER);
8752     exit(1);
8753   }
8754   else {
8755     /* we have can just get the values */
8756     int size = AOP_SIZE(right);
8757     int offset = 0 ;    
8758
8759     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8760     while (size--) {
8761       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8762       if (*l == '@' ) {
8763         //MOVA(l);
8764         //pic16_emitcode("mov","@%s,a",rname);
8765         pic16_emitcode("movf","indf0,w ;1");
8766       } else {
8767
8768         if (AOP_TYPE(right) == AOP_LIT) {
8769           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8770           if(lit) {
8771             pic16_emitcode("movlw","%s",l);
8772             pic16_emitcode("movwf","indf0 ;2");
8773           } else 
8774             pic16_emitcode("clrf","indf0");
8775         }else {
8776           pic16_emitcode("movf","%s,w",l);
8777           pic16_emitcode("movwf","indf0 ;2");
8778         }
8779         //pic16_emitcode("mov","@%s,%s",rname,l);
8780       }
8781       if (size)
8782         pic16_emitcode("incf","fsr0,f ;3");
8783       //pic16_emitcode("inc","%s",rname);
8784       offset++;
8785     }
8786   }
8787
8788   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8789   /* now some housekeeping stuff */
8790   if (aop) {
8791     /* we had to allocate for this iCode */
8792     pic16_freeAsmop(NULL,aop,ic,TRUE);
8793   } else { 
8794     /* we did not allocate which means left
8795        already in a pointer register, then
8796        if size > 0 && this could be used again
8797        we have to point it back to where it 
8798        belongs */
8799     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8800     if (AOP_SIZE(right) > 1 &&
8801         !OP_SYMBOL(result)->remat &&
8802         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8803           ic->depth )) {
8804       int size = AOP_SIZE(right) - 1;
8805       while (size--)
8806         pic16_emitcode("decf","fsr0,f");
8807       //pic16_emitcode("dec","%s",rname);
8808     }
8809   }
8810
8811   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8812   /* done */
8813  release:
8814   pic16_freeAsmop(right,NULL,ic,TRUE);
8815   pic16_freeAsmop(result,NULL,ic,TRUE);
8816 }
8817
8818 /*-----------------------------------------------------------------*/
8819 /* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
8820 /*-----------------------------------------------------------------*/
8821 static void genPagedPointerSet (operand *right,
8822                                operand *result, 
8823                                iCode *ic)
8824 {
8825     asmop *aop = NULL;
8826     regs *preg = NULL ;
8827     char *rname , *l;
8828     sym_link *retype;
8829        
8830     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8831
8832     retype= getSpec(operandType(right));
8833     
8834     pic16_aopOp(result,ic,FALSE);
8835     
8836     /* if the value is already in a pointer register
8837        then don't need anything more */
8838     if (!AOP_INPREG(AOP(result))) {
8839         /* otherwise get a free pointer register */
8840         aop = newAsmop(0);
8841         preg = getFreePtr(ic,&aop,FALSE);
8842         pic16_emitcode("mov","%s,%s",
8843                 preg->name,
8844                 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8845         rname = preg->name ;
8846     } else
8847         rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8848     
8849     pic16_freeAsmop(result,NULL,ic,TRUE);
8850     pic16_aopOp (right,ic,FALSE);
8851
8852     /* if bitfield then unpack the bits */
8853     if (IS_BITVAR(retype)) 
8854         genPackBits (retype,right,rname,PPOINTER);
8855     else {
8856         /* we have can just get the values */
8857         int size = AOP_SIZE(right);
8858         int offset = 0 ;        
8859         
8860         while (size--) {
8861             l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8862             
8863             MOVA(l);
8864             pic16_emitcode("movx","@%s,a",rname);
8865
8866             if (size)
8867                 pic16_emitcode("inc","%s",rname);
8868
8869             offset++;
8870         }
8871     }
8872     
8873     /* now some housekeeping stuff */
8874     if (aop) {
8875         /* we had to allocate for this iCode */
8876         pic16_freeAsmop(NULL,aop,ic,TRUE);
8877     } else { 
8878         /* we did not allocate which means left
8879            already in a pointer register, then
8880            if size > 0 && this could be used again
8881            we have to point it back to where it 
8882            belongs */
8883         if (AOP_SIZE(right) > 1 &&
8884             !OP_SYMBOL(result)->remat &&
8885             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8886               ic->depth )) {
8887             int size = AOP_SIZE(right) - 1;
8888             while (size--)
8889                 pic16_emitcode("dec","%s",rname);
8890         }
8891     }
8892
8893     /* done */
8894     pic16_freeAsmop(right,NULL,ic,TRUE);
8895     
8896         
8897 }
8898
8899 /*-----------------------------------------------------------------*/
8900 /* genFarPointerSet - set value from far space                     */
8901 /*-----------------------------------------------------------------*/
8902 static void genFarPointerSet (operand *right,
8903                               operand *result, iCode *ic)
8904 {
8905     int size, offset ;
8906     sym_link *retype = getSpec(operandType(right));
8907
8908     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8909     pic16_aopOp(result,ic,FALSE);
8910
8911     /* if the operand is already in dptr 
8912     then we do nothing else we move the value to dptr */
8913     if (AOP_TYPE(result) != AOP_STR) {
8914         /* if this is remateriazable */
8915         if (AOP_TYPE(result) == AOP_IMMD)
8916             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8917         else { /* we need to get it byte by byte */
8918             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8919             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8920             if (options.model == MODEL_FLAT24)
8921             {
8922                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8923             }
8924         }
8925     }
8926     /* so dptr know contains the address */
8927     pic16_freeAsmop(result,NULL,ic,TRUE);
8928     pic16_aopOp(right,ic,FALSE);
8929
8930     /* if bit then unpack */
8931     if (IS_BITVAR(retype)) 
8932         genPackBits(retype,right,"dptr",FPOINTER);
8933     else {
8934         size = AOP_SIZE(right);
8935         offset = 0 ;
8936
8937         while (size--) {
8938             char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8939             MOVA(l);
8940             pic16_emitcode("movx","@dptr,a");
8941             if (size)
8942                 pic16_emitcode("inc","dptr");
8943         }
8944     }
8945
8946     pic16_freeAsmop(right,NULL,ic,TRUE);
8947 }
8948
8949 /*-----------------------------------------------------------------*/
8950 /* genGenPointerSet - set value from generic pointer space         */
8951 /*-----------------------------------------------------------------*/
8952 static void genGenPointerSet (operand *right,
8953                               operand *result, iCode *ic)
8954 {
8955   int size, offset ;
8956   sym_link *retype = getSpec(operandType(right));
8957
8958   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8959
8960   pic16_aopOp(result,ic,FALSE);
8961   pic16_aopOp(right,ic,FALSE);
8962   size = AOP_SIZE(right);
8963
8964   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8965
8966   /* if the operand is already in dptr 
8967      then we do nothing else we move the value to dptr */
8968   if (AOP_TYPE(result) != AOP_STR) {
8969     /* if this is remateriazable */
8970     if (AOP_TYPE(result) == AOP_IMMD) {
8971       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8972       pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8973     }
8974     else { /* we need to get it byte by byte */
8975       //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8976       size = AOP_SIZE(right);
8977       offset = 0 ;
8978
8979       /* hack hack! see if this the FSR. If so don't load W */
8980       if(AOP_TYPE(right) != AOP_ACC) {
8981
8982
8983         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8984         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8985
8986         if(AOP_SIZE(result) > 1) {
8987           pic16_emitpcode(POC_BCF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8988           pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8989           pic16_emitpcode(POC_BSF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8990
8991         }
8992
8993         //if(size==2)
8994         //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8995         //if(size==4) {
8996         //  pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
8997         //  pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
8998         //}
8999
9000         while(size--) {
9001           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9002           pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9003           
9004           if(size)
9005             pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9006         }
9007
9008
9009         goto release;
9010       } 
9011
9012       if(aopIdx(AOP(result),0) != 4) {
9013
9014         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9015         goto release;
9016       }
9017
9018       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9019       goto release;
9020
9021     }
9022   }
9023   /* so dptr know contains the address */
9024
9025
9026   /* if bit then unpack */
9027   if (IS_BITVAR(retype)) 
9028     genPackBits(retype,right,"dptr",GPOINTER);
9029   else {
9030     size = AOP_SIZE(right);
9031     offset = 0 ;
9032
9033   DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9034
9035     while (size--) {
9036
9037       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9038       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9039
9040       if (AOP_TYPE(right) == AOP_LIT) 
9041         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9042       else
9043         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9044
9045       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9046
9047       offset++;
9048     }
9049   }
9050
9051  release:
9052   pic16_freeAsmop(right,NULL,ic,TRUE);
9053   pic16_freeAsmop(result,NULL,ic,TRUE);
9054 }
9055
9056 /*-----------------------------------------------------------------*/
9057 /* genPointerSet - stores the value into a pointer location        */
9058 /*-----------------------------------------------------------------*/
9059 static void genPointerSet (iCode *ic)
9060 {    
9061     operand *right, *result ;
9062     sym_link *type, *etype;
9063     int p_type;
9064
9065     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9066
9067     right = IC_RIGHT(ic);
9068     result = IC_RESULT(ic) ;
9069
9070     /* depending on the type of pointer we need to
9071     move it to the correct pointer register */
9072     type = operandType(result);
9073     etype = getSpec(type);
9074     /* if left is of type of pointer then it is simple */
9075     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9076         p_type = DCL_TYPE(type);
9077     }
9078     else {
9079         /* we have to go by the storage class */
9080         p_type = PTR_TYPE(SPEC_OCLS(etype));
9081
9082 /*      if (SPEC_OCLS(etype)->codesp ) { */
9083 /*          p_type = CPOINTER ;  */
9084 /*      } */
9085 /*      else */
9086 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9087 /*              p_type = FPOINTER ; */
9088 /*          else */
9089 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9090 /*                  p_type = PPOINTER ; */
9091 /*              else */
9092 /*                  if (SPEC_OCLS(etype) == idata ) */
9093 /*                      p_type = IPOINTER ; */
9094 /*                  else */
9095 /*                      p_type = POINTER ; */
9096     }
9097
9098     /* now that we have the pointer type we assign
9099     the pointer values */
9100     switch (p_type) {
9101
9102     case POINTER:
9103     case IPOINTER:
9104         genNearPointerSet (right,result,ic);
9105         break;
9106
9107     case PPOINTER:
9108         genPagedPointerSet (right,result,ic);
9109         break;
9110
9111     case FPOINTER:
9112         genFarPointerSet (right,result,ic);
9113         break;
9114
9115     case GPOINTER:
9116         genGenPointerSet (right,result,ic);
9117         break;
9118
9119     default:
9120       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9121               "genPointerSet: illegal pointer type");
9122     }
9123 }
9124
9125 /*-----------------------------------------------------------------*/
9126 /* genIfx - generate code for Ifx statement                        */
9127 /*-----------------------------------------------------------------*/
9128 static void genIfx (iCode *ic, iCode *popIc)
9129 {
9130   operand *cond = IC_COND(ic);
9131   int isbit =0;
9132
9133   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9134
9135   pic16_aopOp(cond,ic,FALSE);
9136
9137   /* get the value into acc */
9138   if (AOP_TYPE(cond) != AOP_CRY)
9139     pic16_toBoolean(cond);
9140   else
9141     isbit = 1;
9142   /* the result is now in the accumulator */
9143   pic16_freeAsmop(cond,NULL,ic,TRUE);
9144
9145   /* if there was something to be popped then do it */
9146   if (popIc)
9147     genIpop(popIc);
9148
9149   /* if the condition is  a bit variable */
9150   if (isbit && IS_ITEMP(cond) && 
9151       SPIL_LOC(cond)) {
9152     genIfxJump(ic,SPIL_LOC(cond)->rname);
9153     DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9154   }
9155   else {
9156     if (isbit && !IS_ITEMP(cond))
9157       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9158     else
9159       genIfxJump(ic,"a");
9160   }
9161   ic->generated = 1;
9162
9163 }
9164
9165 /*-----------------------------------------------------------------*/
9166 /* genAddrOf - generates code for address of                       */
9167 /*-----------------------------------------------------------------*/
9168 static void genAddrOf (iCode *ic)
9169 {
9170   operand *right, *result, *left;
9171   int size, offset ;
9172
9173   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9174
9175
9176   //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9177
9178   pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9179   pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9180   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9181
9182   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9183
9184   size = AOP_SIZE(IC_RESULT(ic));
9185   offset = 0;
9186
9187
9188   while (size--) {
9189     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9190     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9191     offset++;
9192   }
9193
9194
9195   pic16_freeAsmop(left,NULL,ic,FALSE);
9196   pic16_freeAsmop(result,NULL,ic,TRUE);
9197
9198 }
9199
9200 #if 0
9201 /*-----------------------------------------------------------------*/
9202 /* genFarFarAssign - assignment when both are in far space         */
9203 /*-----------------------------------------------------------------*/
9204 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9205 {
9206     int size = AOP_SIZE(right);
9207     int offset = 0;
9208     char *l ;
9209     /* first push the right side on to the stack */
9210     while (size--) {
9211         l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9212         MOVA(l);
9213         pic16_emitcode ("push","acc");
9214     }
9215     
9216     pic16_freeAsmop(right,NULL,ic,FALSE);
9217     /* now assign DPTR to result */
9218     pic16_aopOp(result,ic,FALSE);
9219     size = AOP_SIZE(result);
9220     while (size--) {
9221         pic16_emitcode ("pop","acc");
9222         pic16_aopPut(AOP(result),"a",--offset);
9223     }
9224     pic16_freeAsmop(result,NULL,ic,FALSE);
9225         
9226 }
9227 #endif
9228
9229 /*-----------------------------------------------------------------*/
9230 /* genAssign - generate code for assignment                        */
9231 /*-----------------------------------------------------------------*/
9232 static void genAssign (iCode *ic)
9233 {
9234   operand *result, *right;
9235   int size, offset,know_W;
9236   unsigned long lit = 0L;
9237
9238   result = IC_RESULT(ic);
9239   right  = IC_RIGHT(ic) ;
9240
9241   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9242   
9243   /* if they are the same */
9244   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9245     return ;
9246
9247   pic16_aopOp(right,ic,FALSE);
9248   pic16_aopOp(result,ic,TRUE);
9249
9250   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9251
9252   /* if they are the same registers */
9253   if (pic16_sameRegs(AOP(right),AOP(result)))
9254     goto release;
9255
9256   /* if the result is a bit */
9257   if (AOP_TYPE(result) == AOP_CRY) {
9258     /* if the right size is a literal then
9259        we know what the value is */
9260     if (AOP_TYPE(right) == AOP_LIT) {
9261           
9262       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9263                   pic16_popGet(AOP(result),0));
9264
9265       if (((int) operandLitValue(right))) 
9266         pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9267                        AOP(result)->aopu.aop_dir,
9268                        AOP(result)->aopu.aop_dir);
9269       else
9270         pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9271                        AOP(result)->aopu.aop_dir,
9272                        AOP(result)->aopu.aop_dir);
9273       goto release;
9274     }
9275
9276     /* the right is also a bit variable */
9277     if (AOP_TYPE(right) == AOP_CRY) {
9278       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9279       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9280       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9281
9282       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9283                      AOP(result)->aopu.aop_dir,
9284                      AOP(result)->aopu.aop_dir);
9285       pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9286                      AOP(right)->aopu.aop_dir,
9287                      AOP(right)->aopu.aop_dir);
9288       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9289                      AOP(result)->aopu.aop_dir,
9290                      AOP(result)->aopu.aop_dir);
9291       goto release ;
9292     }
9293
9294     /* we need to or */
9295     pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9296     pic16_toBoolean(right);
9297     emitSKPZ;
9298     pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9299     //pic16_aopPut(AOP(result),"a",0);
9300     goto release ;
9301   }
9302
9303   /* bit variables done */
9304   /* general case */
9305   size = AOP_SIZE(result);
9306   offset = 0 ;
9307   if(AOP_TYPE(right) == AOP_LIT)
9308     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9309
9310 /* VR - What is this?! */
9311   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9312   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9313     if(aopIdx(AOP(result),0) == 4) {
9314   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9315       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9316       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9317       goto release;
9318     } else
9319       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9320   }
9321
9322   know_W=-1;
9323   while (size--) {
9324   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9325     if(AOP_TYPE(right) == AOP_LIT) {
9326       if(lit&0xff) {
9327         if(know_W != (lit&0xff))
9328           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9329         know_W = lit&0xff;
9330         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9331       } else
9332         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9333
9334       lit >>= 8;
9335
9336     } else if (AOP_TYPE(right) == AOP_CRY) {
9337       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9338       if(offset == 0) {
9339         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9340         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9341       }
9342     } else {
9343   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9344
9345 #if 1
9346         /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9347            normally should work, but mind that thw W register live range
9348            is not checked, so if the code generator assumes that the W
9349            is already loaded after such a pair, wrong code will be generated.
9350            
9351            Checking the live range is the next step.
9352            This is experimental code yet and has not been fully tested yet.
9353            USE WITH CARE. Revert to old code by setting 0 to the condition above.
9354            Vangelis Rokas 030603 (vrokas@otenet.gr) */
9355            
9356         
9357         pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9358 #else   
9359         /* This is the old code, which is assumed(?!) that works fine(!?) */
9360
9361         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9362         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9363 #endif
9364     }
9365             
9366     offset++;
9367   }
9368
9369     
9370  release:
9371   pic16_freeAsmop (right,NULL,ic,FALSE);
9372   pic16_freeAsmop (result,NULL,ic,TRUE);
9373 }   
9374
9375 /*-----------------------------------------------------------------*/
9376 /* genJumpTab - generates code for jump table                       */
9377 /*-----------------------------------------------------------------*/
9378 static void genJumpTab (iCode *ic)
9379 {
9380     symbol *jtab;
9381     char *l;
9382
9383     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9384
9385     pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9386     /* get the condition into accumulator */
9387     l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9388     MOVA(l);
9389     /* multiply by three */
9390     pic16_emitcode("add","a,acc");
9391     pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9392
9393     jtab = newiTempLabel(NULL);
9394     pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9395     pic16_emitcode("jmp","@a+dptr");
9396     pic16_emitcode("","%05d_DS_:",jtab->key+100);
9397
9398     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9399     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9400     emitSKPNC;
9401     pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9402     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9403     pic16_emitpLabel(jtab->key);
9404
9405     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9406
9407     /* now generate the jump labels */
9408     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9409          jtab = setNextItem(IC_JTLABELS(ic))) {
9410         pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9411         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9412         
9413     }
9414
9415 }
9416
9417 /*-----------------------------------------------------------------*/
9418 /* genMixedOperation - gen code for operators between mixed types  */
9419 /*-----------------------------------------------------------------*/
9420 /*
9421   TSD - Written for the PIC port - but this unfortunately is buggy.
9422   This routine is good in that it is able to efficiently promote 
9423   types to different (larger) sizes. Unfortunately, the temporary
9424   variables that are optimized out by this routine are sometimes
9425   used in other places. So until I know how to really parse the 
9426   iCode tree, I'm going to not be using this routine :(.
9427 */
9428 static int genMixedOperation (iCode *ic)
9429 {
9430 #if 0
9431   operand *result = IC_RESULT(ic);
9432   sym_link *ctype = operandType(IC_LEFT(ic));
9433   operand *right = IC_RIGHT(ic);
9434   int ret = 0;
9435   int big,small;
9436   int offset;
9437
9438   iCode *nextic;
9439   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9440
9441   pic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9442
9443   nextic = ic->next;
9444   if(!nextic)
9445     return 0;
9446
9447   nextright = IC_RIGHT(nextic);
9448   nextleft  = IC_LEFT(nextic);
9449   nextresult = IC_RESULT(nextic);
9450
9451   pic16_aopOp(right,ic,FALSE);
9452   pic16_aopOp(result,ic,FALSE);
9453   pic16_aopOp(nextright,  nextic, FALSE);
9454   pic16_aopOp(nextleft,   nextic, FALSE);
9455   pic16_aopOp(nextresult, nextic, FALSE);
9456
9457   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9458
9459     operand *t = right;
9460     right = nextright;
9461     nextright = t; 
9462
9463     pic16_emitcode(";remove right +","");
9464
9465   } else   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9466 /*
9467     operand *t = right;
9468     right = nextleft;
9469     nextleft = t; 
9470 */
9471     pic16_emitcode(";remove left +","");
9472   } else
9473     return 0;
9474
9475   big = AOP_SIZE(nextleft);
9476   small = AOP_SIZE(nextright);
9477
9478   switch(nextic->op) {
9479
9480   case '+':
9481     pic16_emitcode(";optimize a +","");
9482     /* if unsigned or not an integral type */
9483     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9484       pic16_emitcode(";add a bit to something","");
9485     } else {
9486
9487       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9488
9489       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9490         pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9491         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9492       } else
9493         pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9494
9495       offset = 0;
9496       while(--big) {
9497
9498         offset++;
9499
9500         if(--small) {
9501           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9502             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9503             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9504           }
9505
9506           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9507           emitSKPNC;
9508           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9509                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9510                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9511           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9512           pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9513
9514         } else {
9515           pic16_emitcode("rlf","known_zero,w");
9516
9517           /*
9518             if right is signed
9519               btfsc  right,7
9520                addlw ff
9521           */
9522           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9523             pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9524             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9525           } else {
9526             pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9527           }
9528         }
9529       }
9530       ret = 1;
9531     }
9532   }
9533   ret = 1;
9534
9535 release:
9536   pic16_freeAsmop(right,NULL,ic,TRUE);
9537   pic16_freeAsmop(result,NULL,ic,TRUE);
9538   pic16_freeAsmop(nextright,NULL,ic,TRUE);
9539   pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9540   if(ret)
9541     nextic->generated = 1;
9542
9543   return ret;
9544 #else
9545   return 0;
9546 #endif
9547 }
9548 /*-----------------------------------------------------------------*/
9549 /* genCast - gen code for casting                                  */
9550 /*-----------------------------------------------------------------*/
9551 static void genCast (iCode *ic)
9552 {
9553     operand *result = IC_RESULT(ic);
9554     sym_link *ctype = operandType(IC_LEFT(ic));
9555     sym_link *rtype = operandType(IC_RIGHT(ic));
9556     operand *right = IC_RIGHT(ic);
9557     int size, offset ;
9558
9559     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9560     /* if they are equivalent then do nothing */
9561     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9562         return ;
9563
9564     pic16_aopOp(right,ic,FALSE) ;
9565     pic16_aopOp(result,ic,FALSE);
9566
9567     DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9568
9569     /* if the result is a bit */
9570     if (AOP_TYPE(result) == AOP_CRY) {
9571         /* if the right size is a literal then
9572         we know what the value is */
9573       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9574         if (AOP_TYPE(right) == AOP_LIT) {
9575
9576           pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9577                       pic16_popGet(AOP(result),0));
9578
9579             if (((int) operandLitValue(right))) 
9580               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9581                        AOP(result)->aopu.aop_dir,
9582                        AOP(result)->aopu.aop_dir);
9583             else
9584               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9585                        AOP(result)->aopu.aop_dir,
9586                        AOP(result)->aopu.aop_dir);
9587
9588             goto release;
9589         }
9590
9591         /* the right is also a bit variable */
9592         if (AOP_TYPE(right) == AOP_CRY) {
9593
9594           emitCLRC;
9595           pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9596
9597           pic16_emitcode("clrc","");
9598           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9599                    AOP(right)->aopu.aop_dir,
9600                    AOP(right)->aopu.aop_dir);
9601             pic16_aopPut(AOP(result),"c",0);
9602             goto release ;
9603         }
9604
9605         /* we need to or */
9606         if (AOP_TYPE(right) == AOP_REG) {
9607           pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9608           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9609           pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9610         }
9611         pic16_toBoolean(right);
9612         pic16_aopPut(AOP(result),"a",0);
9613         goto release ;
9614     }
9615
9616     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9617       int offset = 1;
9618       size = AOP_SIZE(result);
9619
9620       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9621
9622       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
9623       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9624       pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
9625
9626       while (size--)
9627         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9628
9629       goto release;
9630     }
9631
9632     /* if they are the same size : or less */
9633     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9634
9635         /* if they are in the same place */
9636       if (pic16_sameRegs(AOP(right),AOP(result)))
9637         goto release;
9638
9639       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9640       if (IS_PTR_CONST(rtype))
9641         DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9642       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9643         DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9644
9645       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9646         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9647         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9648         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9649         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9650         if(AOP_SIZE(result) <2)
9651           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9652
9653       } else {
9654
9655         /* if they in different places then copy */
9656         size = AOP_SIZE(result);
9657         offset = 0 ;
9658         while (size--) {
9659           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9660           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9661
9662           //pic16_aopPut(AOP(result),
9663           // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9664           // offset);
9665
9666           offset++;
9667         }
9668       }
9669       goto release;
9670     }
9671
9672
9673     /* if the result is of type pointer */
9674     if (IS_PTR(ctype)) {
9675
9676         int p_type;
9677         sym_link *type = operandType(right);
9678         sym_link *etype = getSpec(type);
9679       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9680
9681         /* pointer to generic pointer */
9682         if (IS_GENPTR(ctype)) {
9683             char *l = zero;
9684             
9685             if (IS_PTR(type)) 
9686                 p_type = DCL_TYPE(type);
9687             else {
9688                 /* we have to go by the storage class */
9689                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9690
9691 /*              if (SPEC_OCLS(etype)->codesp )  */
9692 /*                  p_type = CPOINTER ;  */
9693 /*              else */
9694 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9695 /*                      p_type = FPOINTER ; */
9696 /*                  else */
9697 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9698 /*                          p_type = PPOINTER; */
9699 /*                      else */
9700 /*                          if (SPEC_OCLS(etype) == idata ) */
9701 /*                              p_type = IPOINTER ; */
9702 /*                          else */
9703 /*                              p_type = POINTER ; */
9704             }
9705                 
9706             /* the first two bytes are known */
9707       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9708             size = GPTRSIZE - 1; 
9709             offset = 0 ;
9710             while (size--) {
9711               if(offset < AOP_SIZE(right)) {
9712       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9713                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9714                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9715                   pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9716                   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9717                 } else { 
9718                   pic16_aopPut(AOP(result),
9719                          pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9720                          offset);
9721                 }
9722               } else 
9723                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9724               offset++;
9725             }
9726             /* the last byte depending on type */
9727             switch (p_type) {
9728             case IPOINTER:
9729             case POINTER:
9730                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9731                 break;
9732             case FPOINTER:
9733               pic16_emitcode(";BUG!? ","%d",__LINE__);
9734                 l = one;
9735                 break;
9736             case CPOINTER:
9737               pic16_emitcode(";BUG!? ","%d",__LINE__);
9738                 l = "#0x02";
9739                 break;                          
9740             case PPOINTER:
9741               pic16_emitcode(";BUG!? ","%d",__LINE__);
9742                 l = "#0x03";
9743                 break;
9744                 
9745             default:
9746                 /* this should never happen */
9747                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9748                        "got unknown pointer type");
9749                 exit(1);
9750             }
9751             //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
9752             goto release ;
9753         }
9754         
9755         /* just copy the pointers */
9756         size = AOP_SIZE(result);
9757         offset = 0 ;
9758         while (size--) {
9759             pic16_aopPut(AOP(result),
9760                    pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9761                    offset);
9762             offset++;
9763         }
9764         goto release ;
9765     }
9766     
9767
9768
9769     /* so we now know that the size of destination is greater
9770     than the size of the source.
9771     Now, if the next iCode is an operator then we might be
9772     able to optimize the operation without performing a cast.
9773     */
9774     if(genMixedOperation(ic))
9775       goto release;
9776
9777     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9778     
9779     /* we move to result for the size of source */
9780     size = AOP_SIZE(right);
9781     offset = 0 ;
9782     while (size--) {
9783       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(right),offset));
9784       pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset));
9785       offset++;
9786     }
9787
9788     /* now depending on the sign of the destination */
9789     size = AOP_SIZE(result) - AOP_SIZE(right);
9790     /* if unsigned or not an integral type */
9791     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9792       while (size--)
9793         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9794     } else {
9795       /* we need to extend the sign :{ */
9796
9797       if(size == 1) {
9798         /* Save one instruction of casting char to int */
9799         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
9800         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9801         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
9802       } else {
9803         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9804
9805         if(offset)
9806           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9807         else
9808           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9809         
9810         pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
9811
9812         while (size--)
9813           pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
9814       }
9815     }
9816
9817 release:
9818     pic16_freeAsmop(right,NULL,ic,TRUE);
9819     pic16_freeAsmop(result,NULL,ic,TRUE);
9820
9821 }
9822
9823 /*-----------------------------------------------------------------*/
9824 /* genDjnz - generate decrement & jump if not zero instrucion      */
9825 /*-----------------------------------------------------------------*/
9826 static int genDjnz (iCode *ic, iCode *ifx)
9827 {
9828     symbol *lbl, *lbl1;
9829     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9830
9831     if (!ifx)
9832         return 0;
9833     
9834     /* if the if condition has a false label
9835        then we cannot save */
9836     if (IC_FALSE(ifx))
9837         return 0;
9838
9839     /* if the minus is not of the form 
9840        a = a - 1 */
9841     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9842         !IS_OP_LITERAL(IC_RIGHT(ic)))
9843         return 0;
9844
9845     if (operandLitValue(IC_RIGHT(ic)) != 1)
9846         return 0;
9847
9848     /* if the size of this greater than one then no
9849        saving */
9850     if (getSize(operandType(IC_RESULT(ic))) > 1)
9851         return 0;
9852
9853     /* otherwise we can save BIG */
9854     lbl = newiTempLabel(NULL);
9855     lbl1= newiTempLabel(NULL);
9856
9857     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9858     
9859     if (IS_AOP_PREG(IC_RESULT(ic))) {
9860         pic16_emitcode("dec","%s",
9861                  pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9862         pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9863         pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9864     } else {    
9865
9866
9867       pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9868       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9869
9870       pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9871       pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9872
9873     }
9874 /*     pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9875 /*     pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9876 /*     pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9877 /*     pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9878
9879     
9880     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9881     ifx->generated = 1;
9882     return 1;
9883 }
9884
9885 /*-----------------------------------------------------------------*/
9886 /* genReceive - generate code for a receive iCode                  */
9887 /*-----------------------------------------------------------------*/
9888 static void genReceive (iCode *ic)
9889 {    
9890   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9891
9892   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9893       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9894         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9895
9896     int size = getSize(operandType(IC_RESULT(ic)));
9897     int offset =  pic16_fReturnSizePic - size;
9898     while (size--) {
9899       pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9900                                     fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9901       offset++;
9902     }
9903     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9904     size = AOP_SIZE(IC_RESULT(ic));
9905     offset = 0;
9906     while (size--) {
9907       pic16_emitcode ("pop","acc");
9908       pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9909     }
9910         
9911   } else {
9912     _G.accInUse++;
9913     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9914     _G.accInUse--;
9915     assignResultValue(IC_RESULT(ic));   
9916   }
9917
9918   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9919 }
9920
9921 /*-----------------------------------------------------------------*/
9922 /* genDummyRead - generate code for dummy read of volatiles        */
9923 /*-----------------------------------------------------------------*/
9924 static void
9925 genDummyRead (iCode * ic)
9926 {
9927   pic16_emitcode ("; genDummyRead","");
9928   pic16_emitcode ("; not implemented","");
9929
9930   ic = ic;
9931 }
9932
9933 /*-----------------------------------------------------------------*/
9934 /* genpic16Code - generate code for pic16 based controllers        */
9935 /*-----------------------------------------------------------------*/
9936 /*
9937  * At this point, ralloc.c has gone through the iCode and attempted
9938  * to optimize in a way suitable for a PIC. Now we've got to generate
9939  * PIC instructions that correspond to the iCode.
9940  *
9941  * Once the instructions are generated, we'll pass through both the
9942  * peep hole optimizer and the pCode optimizer.
9943  *-----------------------------------------------------------------*/
9944
9945 void genpic16Code (iCode *lic)
9946 {
9947     iCode *ic;
9948     int cln = 0;
9949
9950     lineHead = lineCurr = NULL;
9951
9952     pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9953     pic16_addpBlock(pb);
9954
9955 #if 0
9956     /* if debug information required */
9957     if (options.debug && currFunc) {
9958       if (currFunc) {
9959         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9960         _G.debugLine = 1;
9961         if (IS_STATIC(currFunc->etype)) {
9962           pic16_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9963           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9964         } else {
9965           pic16_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9966           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9967         }
9968         _G.debugLine = 0;
9969       }
9970     }
9971 #endif
9972
9973 //    dumpiCode(lic);
9974
9975     for (ic = lic ; ic ; ic = ic->next ) {
9976
9977 //      fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
9978 //      DEBUGpic16_emitcode("; VR", "");
9979       DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
9980         if ( cln != ic->lineno ) {
9981             if ( options.debug ) {
9982                 _G.debugLine = 1;
9983                 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9984                          FileBaseName(ic->filename),ic->lineno,
9985                          ic->level,ic->block);
9986                 _G.debugLine = 0;
9987             }
9988             /*
9989               pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9990               pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9991               printCLine(ic->filename, ic->lineno));
9992             */
9993             pic16_addpCode2pBlock(pb,
9994                             pic16_newpCodeCSource(ic->lineno, 
9995                                             ic->filename, 
9996                                             printCLine(ic->filename, ic->lineno)));
9997
9998             cln = ic->lineno ;
9999         }
10000         /* if the result is marked as
10001            spilt and rematerializable or code for
10002            this has already been generated then
10003            do nothing */
10004         if (resultRemat(ic) || ic->generated ) 
10005             continue ;
10006         
10007         /* depending on the operation */
10008         switch (ic->op) {
10009         case '!' :
10010             genNot(ic);
10011             break;
10012             
10013         case '~' :
10014             genCpl(ic);
10015             break;
10016             
10017         case UNARYMINUS:
10018             genUminus (ic);
10019             break;
10020             
10021         case IPUSH:
10022             genIpush (ic);
10023             break;
10024             
10025         case IPOP:
10026             /* IPOP happens only when trying to restore a 
10027                spilt live range, if there is an ifx statement
10028                following this pop then the if statement might
10029                be using some of the registers being popped which
10030                would destroy the contents of the register so
10031                we need to check for this condition and handle it */
10032             if (ic->next            && 
10033                 ic->next->op == IFX &&
10034                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10035                 genIfx (ic->next,ic);
10036             else
10037                 genIpop (ic);
10038             break; 
10039             
10040         case CALL:
10041             genCall (ic);
10042             break;
10043             
10044         case PCALL:
10045             genPcall (ic);
10046             break;
10047             
10048         case FUNCTION:
10049             genFunction (ic);
10050             break;
10051             
10052         case ENDFUNCTION:
10053             genEndFunction (ic);
10054             break;
10055             
10056         case RETURN:
10057             genRet (ic);
10058             break;
10059             
10060         case LABEL:
10061             genLabel (ic);
10062             break;
10063             
10064         case GOTO:
10065             genGoto (ic);
10066             break;
10067             
10068         case '+' :
10069             pic16_genPlus (ic) ;
10070             break;
10071             
10072         case '-' :
10073             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10074                 pic16_genMinus (ic);
10075             break;
10076             
10077         case '*' :
10078             genMult (ic);
10079             break;
10080             
10081         case '/' :
10082             genDiv (ic) ;
10083             break;
10084             
10085         case '%' :
10086             genMod (ic);
10087             break;
10088             
10089         case '>' :
10090             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10091             break;
10092             
10093         case '<' :
10094             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10095             break;
10096             
10097         case LE_OP:
10098         case GE_OP:
10099         case NE_OP:
10100             
10101             /* note these two are xlated by algebraic equivalence
10102                during parsing SDCC.y */
10103             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10104                    "got '>=' or '<=' shouldn't have come here");
10105             break;      
10106             
10107         case EQ_OP:
10108             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10109             break;          
10110             
10111         case AND_OP:
10112             genAndOp (ic);
10113             break;
10114             
10115         case OR_OP:
10116             genOrOp (ic);
10117             break;
10118             
10119         case '^' :
10120             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10121             break;
10122             
10123         case '|' :
10124                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10125             break;
10126             
10127         case BITWISEAND:
10128             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10129             break;
10130             
10131         case INLINEASM:
10132             genInline (ic);
10133             break;
10134             
10135         case RRC:
10136             genRRC (ic);
10137             break;
10138             
10139         case RLC:
10140             genRLC (ic);
10141             break;
10142             
10143         case GETHBIT:
10144             genGetHbit (ic);
10145             break;
10146             
10147         case LEFT_OP:
10148             genLeftShift (ic);
10149             break;
10150             
10151         case RIGHT_OP:
10152             genRightShift (ic);
10153             break;
10154             
10155         case GET_VALUE_AT_ADDRESS:
10156             genPointerGet(ic);
10157             break;
10158             
10159         case '=' :
10160             if (POINTER_SET(ic))
10161                 genPointerSet(ic);
10162             else
10163                 genAssign(ic);
10164             break;
10165             
10166         case IFX:
10167             genIfx (ic,NULL);
10168             break;
10169             
10170         case ADDRESS_OF:
10171             genAddrOf (ic);
10172             break;
10173             
10174         case JUMPTABLE:
10175             genJumpTab (ic);
10176             break;
10177             
10178         case CAST:
10179             genCast (ic);
10180             break;
10181             
10182         case RECEIVE:
10183             genReceive(ic);
10184             break;
10185             
10186         case SEND:
10187             addSet(&_G.sendSet,ic);
10188             break;
10189
10190         case DUMMY_READ_VOLATILE:
10191           genDummyRead (ic);
10192           break;
10193
10194         default :
10195             ic = ic;
10196         }
10197     }
10198
10199
10200     /* now we are ready to call the
10201        peep hole optimizer */
10202     if (!options.nopeep) {
10203       peepHole (&lineHead);
10204     }
10205     /* now do the actual printing */
10206     printLine (lineHead,codeOutFile);
10207
10208 #ifdef PCODE_DEBUG
10209     DFPRINTF((stderr,"printing pBlock\n\n"));
10210     pic16_printpBlock(stdout,pb);
10211 #endif
10212
10213     return;
10214 }
10215