PIC16 - Applied patch from Vangelis Rokas. Many fixes for the PIC16 port.
[fw/sdcc] / src / pic16 / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   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 /* max_key keeps track of the largest label number used in 
62    a function. This is then used to adjust the label offset
63    for the next function.
64 */
65 static int max_key=0;
66 static int GpsuedoStkPtr=0;
67
68 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
69 unsigned int pic16aopLiteral (value *val, int offset);
70 const char *pic16_AopType(short type);
71 static iCode *ifxForOp ( operand *op, iCode *ic );
72
73 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
74
75 /* this is the down and dirty file with all kinds of 
76    kludgy & hacky stuff. This is what it is all about
77    CODE GENERATION for a specific MCU . some of the
78    routines may be reusable, will have to see */
79
80 static char *zero = "#0x00";
81 static char *one  = "#0x01";
82 static char *spname = "sp";
83
84 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
85 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
86 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
87 static char **fReturn = fReturnpic16;
88
89 static char *accUse[] = {"a","b"};
90
91 //static short rbank = -1;
92
93 static struct {
94     short r0Pushed;
95     short r1Pushed;
96     short accInUse;
97     short inLine;
98     short debugLine;
99     short nRegsSaved;
100     set *sendSet;
101 } _G;
102
103 /* Resolved ifx structure. This structure stores information
104    about an iCode ifx that makes it easier to generate code.
105 */
106 typedef struct resolvedIfx {
107   symbol *lbl;     /* pointer to a label */
108   int condition;   /* true or false ifx */
109   int generated;   /* set true when the code associated with the ifx
110                     * is generated */
111 } resolvedIfx;
112
113 extern int pic16_ptrRegReq ;
114 extern int pic16_nRegs;
115 extern FILE *codeOutFile;
116 static void saverbank (int, iCode *,bool);
117
118 static lineNode *lineHead = NULL;
119 static lineNode *lineCurr = NULL;
120
121 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
122 0xE0, 0xC0, 0x80, 0x00};
123 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
124 0x07, 0x03, 0x01, 0x00};
125
126 static  pBlock *pb;
127
128 /*-----------------------------------------------------------------*/
129 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
130 /*                 exponent of 2 is returned, otherwise -1 is      */
131 /*                 returned.                                       */
132 /* note that this is similar to the function `powof2' in SDCCsymt  */
133 /* if(n == 2^y)                                                    */
134 /*   return y;                                                     */
135 /* return -1;                                                      */
136 /*-----------------------------------------------------------------*/
137 static int my_powof2 (unsigned long num)
138 {
139   if(num) {
140     if( (num & (num-1)) == 0) {
141       int nshifts = -1;
142       while(num) {
143         num>>=1;
144         nshifts++;
145       }
146       return nshifts;
147     }
148   }
149
150   return -1;
151 }
152
153 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
154 {
155
156   DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
157                        line_no,
158                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
159                        ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
160                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
161                        ((left)   ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
162                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
163                        ((right)  ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
164                        ((result) ? AOP_SIZE(result) : 0));
165
166 }
167
168 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
169 {
170
171   DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
172                        line_no,
173                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
174                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
175                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
176                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
177                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
178                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
179
180 }
181
182 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
183 {
184     va_list ap;
185     char lb[INITIAL_INLINEASM];  
186     char *lbp = lb;
187
188     if(!pic16_debug_verbose)
189       return;
190
191     va_start(ap,fmt);   
192
193     if (inst && *inst) {
194         if (fmt && *fmt)
195             sprintf(lb,"%s\t",inst);
196         else
197             sprintf(lb,"%s",inst);
198         vsprintf(lb+(strlen(lb)),fmt,ap);
199     }  else
200         vsprintf(lb,fmt,ap);
201
202     while (isspace(*lbp)) lbp++;
203
204     if (lbp && *lbp) 
205         lineCurr = (lineCurr ?
206                     connectLine(lineCurr,newLineNode(lb)) :
207                     (lineHead = newLineNode(lb)));
208     lineCurr->isInline = _G.inLine;
209     lineCurr->isDebug  = _G.debugLine;
210
211     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
212
213     va_end(ap);
214 }
215
216
217 void pic16_emitpLabel(int key)
218 {
219   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
220 }
221
222 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
223 {
224
225   if(pcop)
226     pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
227   else
228     DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
229 }
230
231 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
232 {
233
234   pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
235
236 }
237
238 /*-----------------------------------------------------------------*/
239 /* pic16_emitcode - writes the code into a file : for now it is simple    */
240 /*-----------------------------------------------------------------*/
241 void pic16_emitcode (char *inst,char *fmt, ...)
242 {
243     va_list ap;
244     char lb[INITIAL_INLINEASM];  
245     char *lbp = lb;
246
247     va_start(ap,fmt);   
248
249     if (inst && *inst) {
250         if (fmt && *fmt)
251             sprintf(lb,"%s\t",inst);
252         else
253             sprintf(lb,"%s",inst);
254         vsprintf(lb+(strlen(lb)),fmt,ap);
255     }  else
256         vsprintf(lb,fmt,ap);
257
258     while (isspace(*lbp)) lbp++;
259
260     if (lbp && *lbp) 
261         lineCurr = (lineCurr ?
262                     connectLine(lineCurr,newLineNode(lb)) :
263                     (lineHead = newLineNode(lb)));
264     lineCurr->isInline = _G.inLine;
265     lineCurr->isDebug  = _G.debugLine;
266
267 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
268
269     if(pic16_debug_verbose)
270       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
271
272     va_end(ap);
273 }
274
275
276 /*-----------------------------------------------------------------*/
277 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
278 /*-----------------------------------------------------------------*/
279 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
280 {
281     bool r0iu = FALSE , r1iu = FALSE;
282     bool r0ou = FALSE , r1ou = FALSE;
283
284     /* the logic: if r0 & r1 used in the instruction
285     then we are in trouble otherwise */
286
287     /* first check if r0 & r1 are used by this
288     instruction, in which case we are in trouble */
289     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
290         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
291     {
292         goto endOfWorld;      
293     }
294
295     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
296     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
297
298     /* if no usage of r0 then return it */
299     if (!r0iu && !r0ou) {
300         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
301         (*aopp)->type = AOP_R0;
302         
303         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
304     }
305
306     /* if no usage of r1 then return it */
307     if (!r1iu && !r1ou) {
308         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
309         (*aopp)->type = AOP_R1;
310
311         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
312     }    
313
314     /* now we know they both have usage */
315     /* if r0 not used in this instruction */
316     if (!r0iu) {
317         /* push it if not already pushed */
318         if (!_G.r0Pushed) {
319           //pic16_emitcode ("push","%s",
320           //          pic16_regWithIdx(R0_IDX)->dname);
321             _G.r0Pushed++ ;
322         }
323         
324         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
325         (*aopp)->type = AOP_R0;
326
327         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
328     }
329
330     /* if r1 not used then */
331
332     if (!r1iu) {
333         /* push it if not already pushed */
334         if (!_G.r1Pushed) {
335           //pic16_emitcode ("push","%s",
336           //          pic16_regWithIdx(R1_IDX)->dname);
337             _G.r1Pushed++ ;
338         }
339         
340         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
341         (*aopp)->type = AOP_R1;
342         return pic16_regWithIdx(R1_IDX);
343     }
344
345 endOfWorld :
346     /* I said end of world but not quite end of world yet */
347     /* if this is a result then we can push it on the stack*/
348     if (result) {
349         (*aopp)->type = AOP_STK;    
350         return NULL;
351     }
352
353     /* other wise this is true end of the world */
354     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
355            "getFreePtr should never reach here");
356     exit(0);
357 }
358
359 /*-----------------------------------------------------------------*/
360 /* newAsmop - creates a new asmOp                                  */
361 /*-----------------------------------------------------------------*/
362 static asmop *newAsmop (short type)
363 {
364     asmop *aop;
365
366     aop = Safe_calloc(1,sizeof(asmop));
367     aop->type = type;
368     return aop;
369 }
370
371 static void genSetDPTR(int n)
372 {
373     if (!n)
374     {
375         pic16_emitcode(";", "Select standard DPTR");
376         pic16_emitcode("mov", "dps, #0x00");
377     }
378     else
379     {
380         pic16_emitcode(";", "Select alternate DPTR");
381         pic16_emitcode("mov", "dps, #0x01");
382     }
383 }
384
385 /*-----------------------------------------------------------------*/
386 /* resolveIfx - converts an iCode ifx into a form more useful for  */
387 /*              generating code                                    */
388 /*-----------------------------------------------------------------*/
389 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
390 {
391   if(!resIfx) 
392     return;
393
394   //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
395
396   resIfx->condition = 1;    /* assume that the ifx is true */
397   resIfx->generated = 0;    /* indicate that the ifx has not been used */
398
399   if(!ifx) {
400     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
401 /*
402     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
403                         __FUNCTION__,__LINE__,resIfx->lbl->key);
404 */
405   } else {
406     if(IC_TRUE(ifx)) {
407       resIfx->lbl = IC_TRUE(ifx);
408     } else {
409       resIfx->lbl = IC_FALSE(ifx);
410       resIfx->condition = 0;
411     }
412 /*
413     if(IC_TRUE(ifx)) 
414       DEBUGpic16_emitcode("; ***","ifx true is non-null");
415     if(IC_FALSE(ifx)) 
416       DEBUGpic16_emitcode("; ***","ifx false is non-null");
417 */
418   }
419
420   //  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
421
422 }
423 /*-----------------------------------------------------------------*/
424 /* pointerCode - returns the code for a pointer type               */
425 /*-----------------------------------------------------------------*/
426 static int pointerCode (sym_link *etype)
427 {
428
429     return PTR_TYPE(SPEC_OCLS(etype));
430
431 }
432
433 /*-----------------------------------------------------------------*/
434 /* aopForSym - for a true symbol                                   */
435 /*-----------------------------------------------------------------*/
436 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
437 {
438     asmop *aop;
439     memmap *space= SPEC_OCLS(sym->etype);
440
441     DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
442     /* if already has one */
443     if (sym->aop)
444         return sym->aop;
445
446     /* assign depending on the storage class */
447     /* if it is on the stack or indirectly addressable */
448     /* space we need to assign either r0 or r1 to it   */    
449     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
450         sym->aop = aop = newAsmop(0);
451         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
452         aop->size = getSize(sym->type);
453
454         /* now assign the address of the variable to 
455         the pointer register */
456         if (aop->type != AOP_STK) {
457
458             if (sym->onStack) {
459                     if ( _G.accInUse )
460                         pic16_emitcode("push","acc");
461
462                     pic16_emitcode("mov","a,_bp");
463                     pic16_emitcode("add","a,#0x%02x",
464                              ((sym->stack < 0) ?
465                               ((char)(sym->stack - _G.nRegsSaved )) :
466                               ((char)sym->stack)) & 0xff);
467                     pic16_emitcode("mov","%s,a",
468                              aop->aopu.aop_ptr->name);
469
470                     if ( _G.accInUse )
471                         pic16_emitcode("pop","acc");
472             } else
473                 pic16_emitcode("mov","%s,#%s",
474                          aop->aopu.aop_ptr->name,
475                          sym->rname);
476             aop->paged = space->paged;
477         } else
478             aop->aopu.aop_stk = sym->stack;
479         return aop;
480     }
481     
482     if (sym->onStack && options.stack10bit)
483     {
484         /* It's on the 10 bit stack, which is located in
485          * far data space.
486          */
487          
488       //DEBUGpic16_emitcode(";","%d",__LINE__);
489
490         if ( _G.accInUse )
491                 pic16_emitcode("push","acc");
492
493         pic16_emitcode("mov","a,_bp");
494         pic16_emitcode("add","a,#0x%02x",
495                  ((sym->stack < 0) ?
496                    ((char)(sym->stack - _G.nRegsSaved )) :
497                    ((char)sym->stack)) & 0xff);
498         
499         genSetDPTR(1);
500         pic16_emitcode ("mov","dpx1,#0x40");
501         pic16_emitcode ("mov","dph1,#0x00");
502         pic16_emitcode ("mov","dpl1, a");
503         genSetDPTR(0);
504         
505         if ( _G.accInUse )
506             pic16_emitcode("pop","acc");
507             
508         sym->aop = aop = newAsmop(AOP_DPTR2);
509         aop->size = getSize(sym->type); 
510         return aop;
511     }
512
513     //DEBUGpic16_emitcode(";","%d",__LINE__);
514     /* if in bit space */
515     if (IN_BITSPACE(space)) {
516         sym->aop = aop = newAsmop (AOP_CRY);
517         aop->aopu.aop_dir = sym->rname ;
518         aop->size = getSize(sym->type);
519         //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
520         return aop;
521     }
522     /* if it is in direct space */
523     if (IN_DIRSPACE(space)) {
524         sym->aop = aop = newAsmop (AOP_DIR);
525         aop->aopu.aop_dir = sym->rname ;
526         aop->size = getSize(sym->type);
527         DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
528         return aop;
529     }
530
531     /* special case for a function */
532     if (IS_FUNC(sym->type)) {   
533         sym->aop = aop = newAsmop(AOP_IMMD);    
534         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
535         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536         strcpy(aop->aopu.aop_immd,sym->rname);
537         aop->size = FPTRSIZE; 
538         DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
539         return aop;
540     }
541
542
543     /* only remaining is far space */
544     /* in which case DPTR gets the address */
545     sym->aop = aop = newAsmop(AOP_PCODE);
546
547     aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
548     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
549     PCOI(aop->aopu.pcop)->index = 0;
550
551     DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
552                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
553
554     pic16_allocDirReg (IC_LEFT(ic));
555
556     aop->size = FPTRSIZE; 
557 /*
558     DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
559     sym->aop = aop = newAsmop(AOP_DPTR);
560     pic16_emitcode ("mov","dptr,#%s", sym->rname);
561     aop->size = getSize(sym->type);
562
563     DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
564 */
565
566     /* if it is in code space */
567     if (IN_CODESPACE(space))
568         aop->code = 1;
569
570     return aop;     
571 }
572
573 /*-----------------------------------------------------------------*/
574 /* aopForRemat - rematerialzes an object                           */
575 /*-----------------------------------------------------------------*/
576 static asmop *aopForRemat (operand *op) // x symbol *sym)
577 {
578   symbol *sym = OP_SYMBOL(op);
579   iCode *ic = NULL;
580   asmop *aop = newAsmop(AOP_PCODE);
581   int val = 0;
582   int offset = 0;
583
584   ic = sym->rematiCode;
585
586   DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
587   if(IS_OP_POINTER(op)) {
588     DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
589   }
590   for (;;) {
591     if (ic->op == '+') {
592       val += (int) operandLitValue(IC_RIGHT(ic));
593     } else if (ic->op == '-') {
594       val -= (int) operandLitValue(IC_RIGHT(ic));
595     } else
596       break;
597         
598     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
599   }
600
601   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
602   aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
603   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
604   PCOI(aop->aopu.pcop)->index = val;
605
606   DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
607                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
608                       val, IS_PTR_CONST(operandType(op)));
609
610   //    DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
611
612   pic16_allocDirReg (IC_LEFT(ic));
613
614   return aop;        
615 }
616
617 static int aopIdx (asmop *aop, int offset)
618 {
619   if(!aop)
620     return -1;
621
622   if(aop->type !=  AOP_REG)
623     return -2;
624         
625   return aop->aopu.aop_reg[offset]->rIdx;
626
627 }
628 /*-----------------------------------------------------------------*/
629 /* regsInCommon - two operands have some registers in common       */
630 /*-----------------------------------------------------------------*/
631 static bool regsInCommon (operand *op1, operand *op2)
632 {
633     symbol *sym1, *sym2;
634     int i;
635
636     /* if they have registers in common */
637     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
638         return FALSE ;
639
640     sym1 = OP_SYMBOL(op1);
641     sym2 = OP_SYMBOL(op2);
642
643     if (sym1->nRegs == 0 || sym2->nRegs == 0)
644         return FALSE ;
645
646     for (i = 0 ; i < sym1->nRegs ; i++) {
647         int j;
648         if (!sym1->regs[i])
649             continue ;
650
651         for (j = 0 ; j < sym2->nRegs ;j++ ) {
652             if (!sym2->regs[j])
653                 continue ;
654
655             if (sym2->regs[j] == sym1->regs[i])
656                 return TRUE ;
657         }
658     }
659
660     return FALSE ;
661 }
662
663 /*-----------------------------------------------------------------*/
664 /* operandsEqu - equivalent                                        */
665 /*-----------------------------------------------------------------*/
666 static bool operandsEqu ( operand *op1, operand *op2)
667 {
668     symbol *sym1, *sym2;
669
670     /* if they not symbols */
671     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
672         return FALSE;
673
674     sym1 = OP_SYMBOL(op1);
675     sym2 = OP_SYMBOL(op2);
676
677     /* if both are itemps & one is spilt
678        and the other is not then false */
679     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
680         sym1->isspilt != sym2->isspilt )
681         return FALSE ;
682
683     /* if they are the same */
684     if (sym1 == sym2)
685         return TRUE ;
686
687     if (strcmp(sym1->rname,sym2->rname) == 0)
688         return TRUE;
689
690
691     /* if left is a tmp & right is not */
692     if (IS_ITEMP(op1)  && 
693         !IS_ITEMP(op2) &&
694         sym1->isspilt  &&
695         (sym1->usl.spillLoc == sym2))
696         return TRUE;
697
698     if (IS_ITEMP(op2)  && 
699         !IS_ITEMP(op1) &&
700         sym2->isspilt  &&
701         sym1->level > 0 &&
702         (sym2->usl.spillLoc == sym1))
703         return TRUE ;
704
705     return FALSE ;
706 }
707
708 /*-----------------------------------------------------------------*/
709 /* pic16_sameRegs - two asmops have the same registers                   */
710 /*-----------------------------------------------------------------*/
711 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
712 {
713     int i;
714
715     if (aop1 == aop2)
716         return TRUE ;
717
718     if (aop1->type != AOP_REG ||
719         aop2->type != AOP_REG )
720         return FALSE ;
721
722     if (aop1->size != aop2->size )
723         return FALSE ;
724
725     for (i = 0 ; i < aop1->size ; i++ )
726         if (aop1->aopu.aop_reg[i] !=
727             aop2->aopu.aop_reg[i] )
728             return FALSE ;
729
730     return TRUE ;
731 }
732
733 /*-----------------------------------------------------------------*/
734 /* pic16_aopOp - allocates an asmop for an operand  :                    */
735 /*-----------------------------------------------------------------*/
736 void pic16_aopOp (operand *op, iCode *ic, bool result)
737 {
738     asmop *aop;
739     symbol *sym;
740     int i;
741
742     if (!op)
743         return ;
744
745     //    DEBUGpic16_emitcode(";","%d",__LINE__);
746     /* if this a literal */
747     if (IS_OP_LITERAL(op)) {
748         op->aop = aop = newAsmop(AOP_LIT);
749         aop->aopu.aop_lit = op->operand.valOperand;
750         aop->size = getSize(operandType(op));
751         return;
752     }
753
754     {
755       sym_link *type = operandType(op);
756       if(IS_PTR_CONST(type))
757         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
758     }
759
760     /* if already has a asmop then continue */
761     if (op->aop)
762         return ;
763
764     /* if the underlying symbol has a aop */
765     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
766       DEBUGpic16_emitcode(";","%d",__LINE__);
767         op->aop = OP_SYMBOL(op)->aop;
768         return;
769     }
770
771     /* if this is a true symbol */
772     if (IS_TRUE_SYMOP(op)) {    
773       //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
774       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
775       return ;
776     }
777
778     /* this is a temporary : this has
779     only four choices :
780     a) register
781     b) spillocation
782     c) rematerialize 
783     d) conditional   
784     e) can be a return use only */
785
786     sym = OP_SYMBOL(op);
787
788
789     /* if the type is a conditional */
790     if (sym->regType == REG_CND) {
791         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
792         aop->size = 0;
793         return;
794     }
795
796     /* if it is spilt then two situations
797     a) is rematerialize 
798     b) has a spill location */
799     if (sym->isspilt || sym->nRegs == 0) {
800
801       DEBUGpic16_emitcode(";","%d",__LINE__);
802         /* rematerialize it NOW */
803         if (sym->remat) {
804
805             sym->aop = op->aop = aop =
806                                       aopForRemat (op);
807             aop->size = getSize(sym->type);
808             //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
809             return;
810         }
811
812         if (sym->accuse) {
813             int i;
814             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
815             aop->size = getSize(sym->type);
816             for ( i = 0 ; i < 2 ; i++ )
817                 aop->aopu.aop_str[i] = accUse[i];
818             DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
819             return;  
820         }
821
822         if (sym->ruonly ) {
823           /*
824           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
825           aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
826           //pic16_allocDirReg (IC_LEFT(ic));
827           aop->size = getSize(sym->type);
828           */
829
830           unsigned i;
831
832           aop = op->aop = sym->aop = newAsmop(AOP_STR);
833           aop->size = getSize(sym->type);
834           for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
835             aop->aopu.aop_str[i] = fReturn[i];
836
837           DEBUGpic16_emitcode(";","%d",__LINE__);
838           return;
839         }
840
841         /* else spill location  */
842         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
843             /* force a new aop if sizes differ */
844             sym->usl.spillLoc->aop = NULL;
845         }
846         DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
847                             __FUNCTION__,__LINE__,
848                             sym->usl.spillLoc->rname,
849                             sym->rname, sym->usl.spillLoc->offset);
850
851         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
852         //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
853         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
854                                           getSize(sym->type), 
855                                           sym->usl.spillLoc->offset);
856         aop->size = getSize(sym->type);
857
858         return;
859     }
860
861     {
862       sym_link *type = operandType(op);
863       if(IS_PTR_CONST(type)) 
864         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
865     }
866
867     /* must be in a register */
868     DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
869     sym->aop = op->aop = aop = newAsmop(AOP_REG);
870     aop->size = sym->nRegs;
871     for ( i = 0 ; i < sym->nRegs ;i++)
872         aop->aopu.aop_reg[i] = sym->regs[i];
873 }
874
875 /*-----------------------------------------------------------------*/
876 /* pic16_freeAsmop - free up the asmop given to an operand               */
877 /*----------------------------------------------------------------*/
878 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
879 {   
880     asmop *aop ;
881
882     if (!op)
883         aop = aaop;
884     else 
885         aop = op->aop;
886
887     if (!aop)
888         return ;
889
890     if (aop->freed)
891         goto dealloc; 
892
893     aop->freed = 1;
894
895     /* depending on the asmop type only three cases need work AOP_RO
896        , AOP_R1 && AOP_STK */
897 #if 0
898     switch (aop->type) {
899         case AOP_R0 :
900             if (_G.r0Pushed ) {
901                 if (pop) {
902                     pic16_emitcode ("pop","ar0");     
903                     _G.r0Pushed--;
904                 }
905             }
906             bitVectUnSetBit(ic->rUsed,R0_IDX);
907             break;
908
909         case AOP_R1 :
910             if (_G.r1Pushed ) {
911                 if (pop) {
912                     pic16_emitcode ("pop","ar1");
913                     _G.r1Pushed--;
914                 }
915             }
916             bitVectUnSetBit(ic->rUsed,R1_IDX);          
917             break;
918
919         case AOP_STK :
920         {
921             int sz = aop->size;    
922             int stk = aop->aopu.aop_stk + aop->size;
923             bitVectUnSetBit(ic->rUsed,R0_IDX);
924             bitVectUnSetBit(ic->rUsed,R1_IDX);          
925
926             getFreePtr(ic,&aop,FALSE);
927             
928             if (options.stack10bit)
929             {
930                 /* I'm not sure what to do here yet... */
931                 /* #STUB */
932                 fprintf(stderr, 
933                         "*** Warning: probably generating bad code for "
934                         "10 bit stack mode.\n");
935             }
936             
937             if (stk) {
938                 pic16_emitcode ("mov","a,_bp");
939                 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
940                 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
941             } else {
942                 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
943             }
944
945             while (sz--) {
946                 pic16_emitcode("pop","acc");
947                 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
948                 if (!sz) break;
949                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
950             }
951             op->aop = aop;
952             pic16_freeAsmop(op,NULL,ic,TRUE);
953             if (_G.r0Pushed) {
954                 pic16_emitcode("pop","ar0");
955                 _G.r0Pushed--;
956             }
957
958             if (_G.r1Pushed) {
959                 pic16_emitcode("pop","ar1");
960                 _G.r1Pushed--;
961             }       
962         }
963     }
964 #endif
965
966 dealloc:
967     /* all other cases just dealloc */
968     if (op ) {
969         op->aop = NULL;
970         if (IS_SYMOP(op)) {
971             OP_SYMBOL(op)->aop = NULL;    
972             /* if the symbol has a spill */
973             if (SPIL_LOC(op))
974                 SPIL_LOC(op)->aop = NULL;
975         }
976     }
977 }
978
979 /*-----------------------------------------------------------------*/
980 /* pic16_aopGet - for fetching value of the aop                          */
981 /*-----------------------------------------------------------------*/
982 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
983 {
984     char *s = buffer ;
985     char *rs;
986
987     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
988     /* offset is greater than
989     size then zero */
990     if (offset > (aop->size - 1) &&
991         aop->type != AOP_LIT)
992         return zero;
993
994     /* depending on type */
995     switch (aop->type) {
996         
997     case AOP_R0:
998     case AOP_R1:
999         DEBUGpic16_emitcode(";","%d",__LINE__);
1000         /* if we need to increment it */       
1001         while (offset > aop->coff) {        
1002             pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1003             aop->coff++;
1004         }
1005         
1006         while (offset < aop->coff) {
1007             pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1008             aop->coff--;
1009         }
1010         
1011         aop->coff = offset ;
1012         if (aop->paged) {
1013             pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1014             return (dname ? "acc" : "a");
1015         }       
1016         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1017         rs = Safe_calloc(1,strlen(s)+1);
1018         strcpy(rs,s);   
1019         return rs;
1020         
1021     case AOP_DPTR:
1022     case AOP_DPTR2:
1023         DEBUGpic16_emitcode(";","%d",__LINE__);
1024     if (aop->type == AOP_DPTR2)
1025     {
1026         genSetDPTR(1);
1027     }
1028     
1029         while (offset > aop->coff) {
1030             pic16_emitcode ("inc","dptr");
1031             aop->coff++;
1032         }
1033         
1034         while (offset < aop->coff) {        
1035             pic16_emitcode("lcall","__decdptr");
1036             aop->coff--;
1037         }
1038         
1039         aop->coff = offset;
1040         if (aop->code) {
1041             pic16_emitcode("clr","a");
1042             pic16_emitcode("movc","a,@a+dptr");
1043         }
1044     else {
1045             pic16_emitcode("movx","a,@dptr");
1046     }
1047             
1048     if (aop->type == AOP_DPTR2)
1049     {
1050         genSetDPTR(0);
1051     }
1052             
1053     return (dname ? "acc" : "a");
1054         
1055         
1056     case AOP_IMMD:
1057         if (bit16) 
1058             sprintf (s,"%s",aop->aopu.aop_immd);
1059         else
1060             if (offset) 
1061                 sprintf(s,"(%s >> %d)",
1062                         aop->aopu.aop_immd,
1063                         offset*8);
1064             else
1065                 sprintf(s,"%s",
1066                         aop->aopu.aop_immd);
1067         DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1068         rs = Safe_calloc(1,strlen(s)+1);
1069         strcpy(rs,s);   
1070         return rs;
1071         
1072     case AOP_DIR:
1073       if (offset) {
1074         sprintf(s,"(%s + %d)",
1075                 aop->aopu.aop_dir,
1076                 offset);
1077         DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1078       } else
1079             sprintf(s,"%s",aop->aopu.aop_dir);
1080         rs = Safe_calloc(1,strlen(s)+1);
1081         strcpy(rs,s);   
1082         return rs;
1083         
1084     case AOP_REG:
1085       //if (dname) 
1086       //    return aop->aopu.aop_reg[offset]->dname;
1087       //else
1088             return aop->aopu.aop_reg[offset]->name;
1089         
1090     case AOP_CRY:
1091       //pic16_emitcode(";","%d",__LINE__);
1092       return aop->aopu.aop_dir;
1093         
1094     case AOP_ACC:
1095         DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1096         return "AOP_accumulator_bug";
1097
1098     case AOP_LIT:
1099         sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1100         rs = Safe_calloc(1,strlen(s)+1);
1101         strcpy(rs,s);   
1102         return rs;
1103         
1104     case AOP_STR:
1105         aop->coff = offset ;
1106         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1107             dname)
1108             return "acc";
1109         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1110         
1111         return aop->aopu.aop_str[offset];
1112         
1113     case AOP_PCODE:
1114       {
1115         pCodeOp *pcop = aop->aopu.pcop;
1116         DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1117         if(pcop->name) {
1118           DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1119           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1120           sprintf(s,"%s", pcop->name);
1121         } else
1122           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1123
1124       }
1125       rs = Safe_calloc(1,strlen(s)+1);
1126       strcpy(rs,s);   
1127       return rs;
1128
1129     }
1130
1131     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1132            "aopget got unsupported aop->type");
1133     exit(0);
1134 }
1135
1136
1137 /*-----------------------------------------------------------------*/
1138 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1139 /*-----------------------------------------------------------------*/
1140 pCodeOp *pic16_popGetTempReg(void)
1141 {
1142
1143   pCodeOp *pcop;
1144
1145   pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1146   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1147     PCOR(pcop)->r->wasUsed=1;
1148     PCOR(pcop)->r->isFree=0;
1149   }
1150
1151   return pcop;
1152 }
1153
1154 /*-----------------------------------------------------------------*/
1155 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1156 /*-----------------------------------------------------------------*/
1157 void pic16_popReleaseTempReg(pCodeOp *pcop)
1158 {
1159
1160   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1161     PCOR(pcop)->r->isFree = 1;
1162
1163 }
1164 /*-----------------------------------------------------------------*/
1165 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL             */
1166 /*-----------------------------------------------------------------*/
1167 pCodeOp *pic16_popGetLabel(unsigned int key)
1168 {
1169
1170   DEBUGpic16_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1171
1172   if(key>max_key)
1173     max_key = key;
1174
1175   return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1176 }
1177
1178 /*-----------------------------------------------------------------*/
1179 /* pic16_popCopyReg - copy a pcode operator                              */
1180 /*-----------------------------------------------------------------*/
1181 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1182 {
1183   pCodeOpReg *pcor;
1184
1185   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1186   pcor->pcop.type = pc->pcop.type;
1187   if(pc->pcop.name) {
1188     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1189       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1190   } else
1191     pcor->pcop.name = NULL;
1192
1193   pcor->r = pc->r;
1194   pcor->rIdx = pc->rIdx;
1195   pcor->r->wasUsed=1;
1196
1197   //DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1198
1199   return PCOP(pcor);
1200 }
1201 /*-----------------------------------------------------------------*/
1202 /* pic16_popGet - asm operator to pcode operator conversion              */
1203 /*-----------------------------------------------------------------*/
1204 pCodeOp *pic16_popGetLit(unsigned int lit)
1205 {
1206
1207   return pic16_newpCodeOpLit(lit);
1208 }
1209
1210
1211 /*-----------------------------------------------------------------*/
1212 /* pic16_popGetImmd - asm operator to pcode immediate conversion         */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1215 {
1216
1217   return pic16_newpCodeOpImmd(name, offset,index, 0);
1218 }
1219
1220
1221 /*-----------------------------------------------------------------*/
1222 /* pic16_popGet - asm operator to pcode operator conversion              */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *pic16_popGetWithString(char *str)
1225 {
1226   pCodeOp *pcop;
1227
1228
1229   if(!str) {
1230     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1231     exit (1);
1232   }
1233
1234   pcop = pic16_newpCodeOp(str,PO_STR);
1235
1236   return pcop;
1237 }
1238
1239 /*-----------------------------------------------------------------*/
1240 /* popRegFromString -                                              */
1241 /*-----------------------------------------------------------------*/
1242 static pCodeOp *popRegFromString(char *str, int size, int offset)
1243 {
1244
1245   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1246   pcop->type = PO_DIR;
1247
1248   DEBUGpic16_emitcode(";","%d",__LINE__);
1249
1250   if(!str)
1251     str = "BAD_STRING";
1252
1253   pcop->name = Safe_calloc(1,strlen(str)+1);
1254   strcpy(pcop->name,str);
1255
1256   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1257
1258   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1259   if(PCOR(pcop)->r == NULL) {
1260     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1261     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1262     DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1263   } else {
1264     DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1265   }
1266   PCOR(pcop)->instance = offset;
1267
1268   return pcop;
1269 }
1270
1271 static pCodeOp *popRegFromIdx(int rIdx)
1272 {
1273   pCodeOp *pcop;
1274
1275   DEBUGpic16_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1276                        __FUNCTION__,__LINE__,rIdx);
1277
1278   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1279
1280   PCOR(pcop)->rIdx = rIdx;
1281   PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1282   PCOR(pcop)->r->isFree = 0;
1283   PCOR(pcop)->r->wasUsed = 1;
1284
1285   pcop->type = PCOR(pcop)->r->pc_type;
1286
1287
1288   return pcop;
1289 }
1290 /*-----------------------------------------------------------------*/
1291 /* pic16_popGet - asm operator to pcode operator conversion              */
1292 /*-----------------------------------------------------------------*/
1293 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1294 {
1295   //char *s = buffer ;
1296     //char *rs;
1297
1298     pCodeOp *pcop;
1299
1300     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1301     /* offset is greater than
1302     size then zero */
1303
1304     if (offset > (aop->size - 1) &&
1305         aop->type != AOP_LIT)
1306       return NULL;  //zero;
1307
1308     /* depending on type */
1309     switch (aop->type) {
1310         
1311     case AOP_R0:
1312     case AOP_R1:
1313     case AOP_DPTR:
1314     case AOP_DPTR2:
1315     case AOP_ACC:
1316         DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1317         return NULL;
1318         
1319     case AOP_IMMD:
1320       DEBUGpic16_emitcode(";","%d",__LINE__);
1321       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1322
1323     case AOP_DIR:
1324       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1325 #if 0
1326         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1327         pcop->type = PO_DIR;
1328
1329         /*
1330         if (offset)
1331             sprintf(s,"(%s + %d)",
1332                     aop->aopu.aop_dir,
1333                     offset);
1334         else
1335             sprintf(s,"%s",aop->aopu.aop_dir);
1336         pcop->name = Safe_calloc(1,strlen(s)+1);
1337         strcpy(pcop->name,s);   
1338         */
1339         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1340         strcpy(pcop->name,aop->aopu.aop_dir);   
1341         PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1342         if(PCOR(pcop)->r == NULL) {
1343           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1344           PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1345           DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1346         } else {
1347           DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1348         }
1349         PCOR(pcop)->instance = offset;
1350
1351         return pcop;
1352 #endif
1353         
1354     case AOP_REG:
1355       {
1356         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1357
1358         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1359         PCOR(pcop)->rIdx = rIdx;
1360         PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1361         PCOR(pcop)->r->wasUsed=1;
1362         PCOR(pcop)->r->isFree=0;
1363
1364         PCOR(pcop)->instance = offset;
1365         pcop->type = PCOR(pcop)->r->pc_type;
1366         //rs = aop->aopu.aop_reg[offset]->name;
1367         //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1368         return pcop;
1369       }
1370
1371     case AOP_CRY:
1372       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1373       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1374       //if(PCOR(pcop)->r == NULL)
1375       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1376       return pcop;
1377         
1378     case AOP_LIT:
1379       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1380
1381     case AOP_STR:
1382       DEBUGpic16_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1383       return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1384       /*
1385       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1386       PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1387       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1388       pcop->type = PCOR(pcop)->r->pc_type;
1389       pcop->name = PCOR(pcop)->r->name;
1390
1391       return pcop;
1392       */
1393
1394     case AOP_PCODE:
1395       DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1396                           __LINE__, 
1397                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1398       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1399       PCOI(pcop)->offset = offset;
1400       return pcop;
1401     }
1402
1403     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1404            "pic16_popGet got unsupported aop->type");
1405     exit(0);
1406 }
1407 /*-----------------------------------------------------------------*/
1408 /* pic16_aopPut - puts a string for a aop                                */
1409 /*-----------------------------------------------------------------*/
1410 void pic16_aopPut (asmop *aop, char *s, int offset)
1411 {
1412     char *d = buffer ;
1413     symbol *lbl ;
1414
1415     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1416
1417     if (aop->size && offset > ( aop->size - 1)) {
1418         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1419                "pic16_aopPut got offset > aop->size");
1420         exit(0);
1421     }
1422
1423     /* will assign value to value */
1424     /* depending on where it is ofcourse */
1425     switch (aop->type) {
1426     case AOP_DIR:
1427       if (offset) {
1428         sprintf(d,"(%s + %d)",
1429                 aop->aopu.aop_dir,offset);
1430         fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1431
1432       } else
1433             sprintf(d,"%s",aop->aopu.aop_dir);
1434         
1435         if (strcmp(d,s)) {
1436           DEBUGpic16_emitcode(";","%d",__LINE__);
1437           if(strcmp(s,"W"))
1438             pic16_emitcode("movf","%s,w",s);
1439           pic16_emitcode("movwf","%s",d);
1440
1441           if(strcmp(s,"W")) {
1442             pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1443             if(offset >= aop->size) {
1444               pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1445               break;
1446             } else
1447               pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1448           }
1449
1450           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1451
1452
1453         }
1454         break;
1455         
1456     case AOP_REG:
1457       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1458         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1459           /*
1460             if (*s == '@'           ||
1461                 strcmp(s,"r0") == 0 ||
1462                 strcmp(s,"r1") == 0 ||
1463                 strcmp(s,"r2") == 0 ||
1464                 strcmp(s,"r3") == 0 ||
1465                 strcmp(s,"r4") == 0 ||
1466                 strcmp(s,"r5") == 0 ||
1467                 strcmp(s,"r6") == 0 || 
1468                 strcmp(s,"r7") == 0 )
1469                 pic16_emitcode("mov","%s,%s  ; %d",
1470                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1471             else
1472           */
1473
1474           if(strcmp(s,"W")==0 )
1475             pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
1476
1477           pic16_emitcode("movwf","%s",
1478                    aop->aopu.aop_reg[offset]->name);
1479
1480           if(strcmp(s,zero)==0) {
1481             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1482
1483           } else if(strcmp(s,"W")==0) {
1484             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1485             pcop->type = PO_GPR_REGISTER;
1486
1487             PCOR(pcop)->rIdx = -1;
1488             PCOR(pcop)->r = NULL;
1489
1490             DEBUGpic16_emitcode(";","%d",__LINE__);
1491             pcop->name = Safe_strdup(s);
1492             pic16_emitpcode(POC_MOVFW,pcop);
1493             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1494           } else if(strcmp(s,one)==0) {
1495             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1496             pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1497           } else {
1498             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1499           }
1500         }
1501         break;
1502         
1503     case AOP_DPTR:
1504     case AOP_DPTR2:
1505     
1506     if (aop->type == AOP_DPTR2)
1507     {
1508         genSetDPTR(1);
1509     }
1510     
1511         if (aop->code) {
1512             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1513                    "pic16_aopPut writting to code space");
1514             exit(0);
1515         }
1516         
1517         while (offset > aop->coff) {
1518             aop->coff++;
1519             pic16_emitcode ("inc","dptr");
1520         }
1521         
1522         while (offset < aop->coff) {
1523             aop->coff-- ;
1524             pic16_emitcode("lcall","__decdptr");
1525         }
1526         
1527         aop->coff = offset;
1528         
1529         /* if not in accumulater */
1530         MOVA(s);        
1531         
1532         pic16_emitcode ("movx","@dptr,a");
1533         
1534     if (aop->type == AOP_DPTR2)
1535     {
1536         genSetDPTR(0);
1537     }
1538         break;
1539         
1540     case AOP_R0:
1541     case AOP_R1:
1542         while (offset > aop->coff) {
1543             aop->coff++;
1544             pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1545         }
1546         while (offset < aop->coff) {
1547             aop->coff-- ;
1548             pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1549         }
1550         aop->coff = offset;
1551         
1552         if (aop->paged) {
1553             MOVA(s);           
1554             pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1555             
1556         } else
1557             if (*s == '@') {
1558                 MOVA(s);
1559                 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1560             } else
1561                 if (strcmp(s,"r0") == 0 ||
1562                     strcmp(s,"r1") == 0 ||
1563                     strcmp(s,"r2") == 0 ||
1564                     strcmp(s,"r3") == 0 ||
1565                     strcmp(s,"r4") == 0 ||
1566                     strcmp(s,"r5") == 0 ||
1567                     strcmp(s,"r6") == 0 || 
1568                     strcmp(s,"r7") == 0 ) {
1569                     char buffer[10];
1570                     sprintf(buffer,"a%s",s);
1571                     pic16_emitcode("mov","@%s,%s",
1572                              aop->aopu.aop_ptr->name,buffer);
1573                 } else
1574                     pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1575         
1576         break;
1577         
1578     case AOP_STK:
1579         if (strcmp(s,"a") == 0)
1580             pic16_emitcode("push","acc");
1581         else
1582             pic16_emitcode("push","%s",s);
1583         
1584         break;
1585         
1586     case AOP_CRY:
1587         /* if bit variable */
1588         if (!aop->aopu.aop_dir) {
1589             pic16_emitcode("clr","a");
1590             pic16_emitcode("rlc","a");
1591         } else {
1592             if (s == zero) 
1593                 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1594             else
1595                 if (s == one)
1596                     pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1597                 else
1598                     if (!strcmp(s,"c"))
1599                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1600                     else {
1601                         lbl = newiTempLabel(NULL);
1602                         
1603                         if (strcmp(s,"a")) {
1604                             MOVA(s);
1605                         }
1606                         pic16_emitcode("clr","c");
1607                         pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1608                         pic16_emitcode("cpl","c");
1609                         pic16_emitcode("","%05d_DS_:",lbl->key+100);
1610                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1611                     }
1612         }
1613         break;
1614         
1615     case AOP_STR:
1616         aop->coff = offset;
1617         if (strcmp(aop->aopu.aop_str[offset],s))
1618             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1619         break;
1620         
1621     case AOP_ACC:
1622         aop->coff = offset;
1623         if (!offset && (strcmp(s,"acc") == 0))
1624             break;
1625         
1626         if (strcmp(aop->aopu.aop_str[offset],s))
1627             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1628         break;
1629
1630     default :
1631         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1632                "pic16_aopPut got unsupported aop->type");
1633         exit(0);    
1634     }    
1635
1636 }
1637
1638 /*-----------------------------------------------------------------*/
1639 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1640 /*-----------------------------------------------------------------*/
1641 static void mov2w (asmop *aop, int offset)
1642 {
1643
1644   if(!aop)
1645     return;
1646
1647   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1648
1649   if ( aop->type == AOP_PCODE ||
1650        aop->type == AOP_LIT )
1651     pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1652   else
1653     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1654
1655 }
1656
1657 /*-----------------------------------------------------------------*/
1658 /* reAdjustPreg - points a register back to where it should        */
1659 /*-----------------------------------------------------------------*/
1660 static void reAdjustPreg (asmop *aop)
1661 {
1662     int size ;
1663
1664     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1665     aop->coff = 0;
1666     if ((size = aop->size) <= 1)
1667         return ;
1668     size-- ;
1669     switch (aop->type) {
1670         case AOP_R0 :
1671         case AOP_R1 :
1672             while (size--)
1673                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1674             break;          
1675         case AOP_DPTR :
1676         case AOP_DPTR2:
1677             if (aop->type == AOP_DPTR2)
1678             {
1679                 genSetDPTR(1);
1680             } 
1681             while (size--)
1682             {
1683                 pic16_emitcode("lcall","__decdptr");
1684             }
1685                 
1686             if (aop->type == AOP_DPTR2)
1687             {
1688                 genSetDPTR(0);
1689             }                
1690             break;  
1691
1692     }   
1693
1694 }
1695
1696 /*-----------------------------------------------------------------*/
1697 /* genNotFloat - generates not for float operations              */
1698 /*-----------------------------------------------------------------*/
1699 static void genNotFloat (operand *op, operand *res)
1700 {
1701     int size, offset;
1702     char *l;
1703     symbol *tlbl ;
1704
1705     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1706     /* we will put 127 in the first byte of 
1707     the result */
1708     pic16_aopPut(AOP(res),"#127",0);
1709     size = AOP_SIZE(op) - 1;
1710     offset = 1;
1711
1712     l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1713     MOVA(l);    
1714
1715     while(size--) {
1716         pic16_emitcode("orl","a,%s",
1717                  pic16_aopGet(op->aop,
1718                         offset++,FALSE,FALSE));
1719     }
1720     tlbl = newiTempLabel(NULL);
1721
1722     tlbl = newiTempLabel(NULL);
1723     pic16_aopPut(res->aop,one,1);
1724     pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1725     pic16_aopPut(res->aop,zero,1);
1726     pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1727
1728     size = res->aop->size - 2;
1729     offset = 2;    
1730     /* put zeros in the rest */
1731     while (size--) 
1732         pic16_aopPut(res->aop,zero,offset++);
1733 }
1734
1735 #if 0
1736 /*-----------------------------------------------------------------*/
1737 /* opIsGptr: returns non-zero if the passed operand is             */   
1738 /* a generic pointer type.                                         */
1739 /*-----------------------------------------------------------------*/ 
1740 static int opIsGptr(operand *op)
1741 {
1742     sym_link *type = operandType(op);
1743     
1744     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1745     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1746     {
1747         return 1;
1748     }
1749     return 0;        
1750 }
1751 #endif
1752
1753 /*-----------------------------------------------------------------*/
1754 /* pic16_getDataSize - get the operand data size                         */
1755 /*-----------------------------------------------------------------*/
1756 int pic16_getDataSize(operand *op)
1757 {
1758     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1759
1760
1761     return AOP_SIZE(op);
1762
1763     // tsd- in the pic port, the genptr size is 1, so this code here
1764     // fails. ( in the 8051 port, the size was 4).
1765 #if 0
1766     int size;
1767     size = AOP_SIZE(op);
1768     if (size == GPTRSIZE)
1769     {
1770         sym_link *type = operandType(op);
1771         if (IS_GENPTR(type))
1772         {
1773             /* generic pointer; arithmetic operations
1774              * should ignore the high byte (pointer type).
1775              */
1776             size--;
1777     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1778         }
1779     }
1780     return size;
1781 #endif
1782 }
1783
1784 /*-----------------------------------------------------------------*/
1785 /* pic16_outAcc - output Acc                                             */
1786 /*-----------------------------------------------------------------*/
1787 void pic16_outAcc(operand *result)
1788 {
1789   int size,offset;
1790   DEBUGpic16_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1791   DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1792
1793
1794   size = pic16_getDataSize(result);
1795   if(size){
1796     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1797     size--;
1798     offset = 1;
1799     /* unsigned or positive */
1800     while(size--)
1801       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1802   }
1803
1804 }
1805
1806 /*-----------------------------------------------------------------*/
1807 /* pic16_outBitC - output a bit C                                        */
1808 /*-----------------------------------------------------------------*/
1809 void pic16_outBitC(operand *result)
1810 {
1811
1812     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1813     /* if the result is bit */
1814     if (AOP_TYPE(result) == AOP_CRY) 
1815         pic16_aopPut(AOP(result),"c",0);
1816     else {
1817         pic16_emitcode("clr","a  ; %d", __LINE__);
1818         pic16_emitcode("rlc","a");
1819         pic16_outAcc(result);
1820     }
1821 }
1822
1823 /*-----------------------------------------------------------------*/
1824 /* pic16_toBoolean - emit code for orl a,operator(sizeop)                */
1825 /*-----------------------------------------------------------------*/
1826 void pic16_toBoolean(operand *oper)
1827 {
1828     int size = AOP_SIZE(oper) - 1;
1829     int offset = 1;
1830
1831     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1832
1833     if ( AOP_TYPE(oper) != AOP_ACC) {
1834       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1835     }
1836     while (size--) {
1837       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1838     }
1839 }
1840
1841
1842 /*-----------------------------------------------------------------*/
1843 /* genNot - generate code for ! operation                          */
1844 /*-----------------------------------------------------------------*/
1845 static void genNot (iCode *ic)
1846 {
1847   symbol *tlbl;
1848   sym_link *optype = operandType(IC_LEFT(ic));
1849   int size;
1850
1851   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1852   /* assign asmOps to operand & result */
1853   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1854   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1855
1856   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1857   /* if in bit space then a special case */
1858   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1859     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1860       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1861       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1862     } else {
1863       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1864       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1865       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1866     }
1867     goto release;
1868   }
1869
1870   /* if type float then do float */
1871   if (IS_FLOAT(optype)) {
1872     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1873     goto release;
1874   }
1875
1876   size = AOP_SIZE(IC_RESULT(ic));
1877   if(size == 1) {
1878     pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1879     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1880     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1881     goto release;
1882   }
1883   pic16_toBoolean(IC_LEFT(ic));
1884
1885   tlbl = newiTempLabel(NULL);
1886   pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1887   pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1888   pic16_outBitC(IC_RESULT(ic));
1889
1890  release:    
1891   /* release the aops */
1892   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1893   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1894 }
1895
1896
1897 /*-----------------------------------------------------------------*/
1898 /* genCpl - generate code for complement                           */
1899 /*-----------------------------------------------------------------*/
1900 static void genCpl (iCode *ic)
1901 {
1902     int offset = 0;
1903     int size ;
1904
1905
1906     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1907     /* assign asmOps to operand & result */
1908     pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1909     pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1910
1911     /* if both are in bit space then 
1912     a special case */
1913     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1914         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1915
1916         pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1917         pic16_emitcode("cpl","c"); 
1918         pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1919         goto release; 
1920     } 
1921
1922     size = AOP_SIZE(IC_RESULT(ic));
1923     while (size--) {
1924 /*
1925         char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1926         MOVA(l);       
1927         pic16_emitcode("cpl","a");
1928         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1929 */
1930         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1931               DEBUGpic16_emitcode("; ", "same registers");
1932               pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
1933         } else {
1934                 DEBUGpic16_emitcode(";",  "not sames registers!");
1935                 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1936                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1937         }
1938         offset++;
1939
1940     }
1941
1942
1943 release:
1944     /* release the aops */
1945     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1946     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1947 }
1948
1949 /*-----------------------------------------------------------------*/
1950 /* genUminusFloat - unary minus for floating points                */
1951 /*-----------------------------------------------------------------*/
1952 static void genUminusFloat(operand *op,operand *result)
1953 {
1954     int size ,offset =0 ;
1955     char *l;
1956
1957     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1958     /* for this we just need to flip the 
1959     first it then copy the rest in place */
1960     size = AOP_SIZE(op) - 1;
1961     l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1962
1963     MOVA(l);    
1964
1965     pic16_emitcode("cpl","acc.7");
1966     pic16_aopPut(AOP(result),"a",3);    
1967
1968     while(size--) {
1969         pic16_aopPut(AOP(result),
1970                pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1971                offset);
1972         offset++;
1973     }          
1974 }
1975
1976 /*-----------------------------------------------------------------*/
1977 /* genUminus - unary minus code generation                         */
1978 /*-----------------------------------------------------------------*/
1979 static void genUminus (iCode *ic)
1980 {
1981   int size, i;
1982   sym_link *optype, *rtype;
1983
1984
1985   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1986   /* assign asmops */
1987   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1988   pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1989
1990   /* if both in bit space then special
1991      case */
1992   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1993       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1994
1995     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1996     pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1997     pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1998
1999     goto release; 
2000   } 
2001
2002   optype = operandType(IC_LEFT(ic));
2003   rtype = operandType(IC_RESULT(ic));
2004
2005   /* if float then do float stuff */
2006   if (IS_FLOAT(optype)) {
2007     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2008     goto release;
2009   }
2010
2011   /* otherwise subtract from zero by taking the 2's complement */
2012   size = AOP_SIZE(IC_LEFT(ic));
2013
2014   for(i=0; i<size; i++) {
2015     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2016       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
2017     else {
2018       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2019       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2020     }
2021   }
2022
2023   pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
2024   for(i=1; i<size; i++) {
2025     emitSKPNZ;
2026     pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
2027   }
2028
2029  release:
2030   /* release the aops */
2031   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2032   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2033 }
2034
2035 /*-----------------------------------------------------------------*/
2036 /* saveRegisters - will look for a call and save the registers     */
2037 /*-----------------------------------------------------------------*/
2038 static void saveRegisters(iCode *lic) 
2039 {
2040     int i;
2041     iCode *ic;
2042     bitVect *rsave;
2043     sym_link *dtype;
2044
2045     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2046     /* look for call */
2047     for (ic = lic ; ic ; ic = ic->next) 
2048         if (ic->op == CALL || ic->op == PCALL)
2049             break;
2050
2051     if (!ic) {
2052         fprintf(stderr,"found parameter push with no function call\n");
2053         return ;
2054     }
2055
2056     /* if the registers have been saved already then
2057     do nothing */
2058     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2059         return ;
2060
2061     /* find the registers in use at this time 
2062     and push them away to safety */
2063     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064                           ic->rUsed);
2065
2066     ic->regsSaved = 1;
2067     if (options.useXstack) {
2068         if (bitVectBitValue(rsave,R0_IDX))
2069             pic16_emitcode("mov","b,r0");
2070         pic16_emitcode("mov","r0,%s",spname);
2071         for (i = 0 ; i < pic16_nRegs ; i++) {
2072             if (bitVectBitValue(rsave,i)) {
2073                 if (i == R0_IDX)
2074                     pic16_emitcode("mov","a,b");
2075                 else
2076                     pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2077                 pic16_emitcode("movx","@r0,a");
2078                 pic16_emitcode("inc","r0");
2079             }
2080         }
2081         pic16_emitcode("mov","%s,r0",spname);
2082         if (bitVectBitValue(rsave,R0_IDX))
2083             pic16_emitcode("mov","r0,b");           
2084     }// else
2085     //for (i = 0 ; i < pic16_nRegs ; i++) {
2086     //    if (bitVectBitValue(rsave,i))
2087     //  pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2088     //}
2089
2090     dtype = operandType(IC_LEFT(ic));
2091     if (currFunc && dtype && 
2092         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2093         IFFUNC_ISISR(currFunc->type) &&
2094         !ic->bankSaved) 
2095
2096         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2097
2098 }
2099 /*-----------------------------------------------------------------*/
2100 /* unsaveRegisters - pop the pushed registers                      */
2101 /*-----------------------------------------------------------------*/
2102 static void unsaveRegisters (iCode *ic)
2103 {
2104     int i;
2105     bitVect *rsave;
2106
2107     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2108     /* find the registers in use at this time 
2109     and push them away to safety */
2110     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2111                           ic->rUsed);
2112     
2113     if (options.useXstack) {
2114         pic16_emitcode("mov","r0,%s",spname);   
2115         for (i =  pic16_nRegs ; i >= 0 ; i--) {
2116             if (bitVectBitValue(rsave,i)) {
2117                 pic16_emitcode("dec","r0");
2118                 pic16_emitcode("movx","a,@r0");
2119                 if (i == R0_IDX)
2120                     pic16_emitcode("mov","b,a");
2121                 else
2122                     pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2123             }       
2124
2125         }
2126         pic16_emitcode("mov","%s,r0",spname);
2127         if (bitVectBitValue(rsave,R0_IDX))
2128             pic16_emitcode("mov","r0,b");
2129     } //else
2130     //for (i =  pic16_nRegs ; i >= 0 ; i--) {
2131     //    if (bitVectBitValue(rsave,i))
2132     //  pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2133     //}
2134
2135 }  
2136
2137
2138 /*-----------------------------------------------------------------*/
2139 /* pushSide -                                                      */
2140 /*-----------------------------------------------------------------*/
2141 static void pushSide(operand * oper, int size)
2142 {
2143 #if 0
2144         int offset = 0;
2145     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2146         while (size--) {
2147                 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2148                 if (AOP_TYPE(oper) != AOP_REG &&
2149                     AOP_TYPE(oper) != AOP_DIR &&
2150                     strcmp(l,"a") ) {
2151                         pic16_emitcode("mov","a,%s",l);
2152                         pic16_emitcode("push","acc");
2153                 } else
2154                         pic16_emitcode("push","%s",l);
2155         }
2156 #endif
2157 }
2158
2159 /*-----------------------------------------------------------------*/
2160 /* assignResultValue -                                             */
2161 /*-----------------------------------------------------------------*/
2162 static void assignResultValue(operand * oper)
2163 {
2164   int size = AOP_SIZE(oper);
2165
2166   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2167
2168   DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2169
2170   if(!GpsuedoStkPtr) {
2171     /* The last byte in the assignment is in W */
2172     size--;
2173     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2174     GpsuedoStkPtr++;
2175   }
2176
2177   while (size--) {
2178     pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2179     GpsuedoStkPtr++;
2180     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2181   }
2182 }
2183
2184
2185 /*-----------------------------------------------------------------*/
2186 /* genIpush - genrate code for pushing this gets a little complex  */
2187 /*-----------------------------------------------------------------*/
2188 static void genIpush (iCode *ic)
2189 {
2190
2191   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2192 #if 0
2193     int size, offset = 0 ;
2194     char *l;
2195
2196
2197     /* if this is not a parm push : ie. it is spill push 
2198     and spill push is always done on the local stack */
2199     if (!ic->parmPush) {
2200
2201         /* and the item is spilt then do nothing */
2202         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2203             return ;
2204
2205         pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2206         size = AOP_SIZE(IC_LEFT(ic));
2207         /* push it on the stack */
2208         while(size--) {
2209             l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2210             if (*l == '#') {
2211                 MOVA(l);
2212                 l = "acc";
2213             }
2214             pic16_emitcode("push","%s",l);
2215         }
2216         return ;        
2217     }
2218
2219     /* this is a paramter push: in this case we call
2220     the routine to find the call and save those
2221     registers that need to be saved */   
2222     saveRegisters(ic);
2223
2224     /* then do the push */
2225     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2226
2227
2228         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2229     size = AOP_SIZE(IC_LEFT(ic));
2230
2231     while (size--) {
2232         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2233         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2234             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2235             strcmp(l,"a") ) {
2236             pic16_emitcode("mov","a,%s",l);
2237             pic16_emitcode("push","acc");
2238         } else
2239             pic16_emitcode("push","%s",l);
2240     }       
2241
2242     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2243 #endif
2244 }
2245
2246 /*-----------------------------------------------------------------*/
2247 /* genIpop - recover the registers: can happen only for spilling   */
2248 /*-----------------------------------------------------------------*/
2249 static void genIpop (iCode *ic)
2250 {
2251   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2252 #if 0
2253     int size,offset ;
2254
2255
2256     /* if the temp was not pushed then */
2257     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2258         return ;
2259
2260     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2261     size = AOP_SIZE(IC_LEFT(ic));
2262     offset = (size-1);
2263     while (size--) 
2264         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2265                                    FALSE,TRUE));
2266
2267     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2268 #endif
2269 }
2270
2271 /*-----------------------------------------------------------------*/
2272 /* unsaverbank - restores the resgister bank from stack            */
2273 /*-----------------------------------------------------------------*/
2274 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2275 {
2276   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2277 #if 0
2278     int i;
2279     asmop *aop ;
2280     regs *r = NULL;
2281
2282     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2283     if (popPsw) {
2284         if (options.useXstack) {
2285             aop = newAsmop(0);
2286             r = getFreePtr(ic,&aop,FALSE);
2287             
2288             
2289             pic16_emitcode("mov","%s,_spx",r->name);
2290             pic16_emitcode("movx","a,@%s",r->name);
2291             pic16_emitcode("mov","psw,a");
2292             pic16_emitcode("dec","%s",r->name);
2293             
2294         }else
2295             pic16_emitcode ("pop","psw");
2296     }
2297
2298     for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2299         if (options.useXstack) {       
2300             pic16_emitcode("movx","a,@%s",r->name);
2301             //pic16_emitcode("mov","(%s+%d),a",
2302             //       regspic16[i].base,8*bank+regspic16[i].offset);
2303             pic16_emitcode("dec","%s",r->name);
2304
2305         } else 
2306           pic16_emitcode("pop",""); //"(%s+%d)",
2307         //regspic16[i].base,8*bank); //+regspic16[i].offset);
2308     }
2309
2310     if (options.useXstack) {
2311
2312         pic16_emitcode("mov","_spx,%s",r->name);
2313         pic16_freeAsmop(NULL,aop,ic,TRUE);
2314
2315     }
2316 #endif 
2317 }
2318
2319 /*-----------------------------------------------------------------*/
2320 /* saverbank - saves an entire register bank on the stack          */
2321 /*-----------------------------------------------------------------*/
2322 static void saverbank (int bank, iCode *ic, bool pushPsw)
2323 {
2324   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2325 #if 0
2326     int i;
2327     asmop *aop ;
2328     regs *r = NULL;
2329
2330     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2331     if (options.useXstack) {
2332
2333         aop = newAsmop(0);
2334         r = getFreePtr(ic,&aop,FALSE);  
2335         pic16_emitcode("mov","%s,_spx",r->name);
2336
2337     }
2338
2339     for (i = 0 ; i < pic16_nRegs ;i++) {
2340         if (options.useXstack) {
2341             pic16_emitcode("inc","%s",r->name);
2342             //pic16_emitcode("mov","a,(%s+%d)",
2343             //         regspic16[i].base,8*bank+regspic16[i].offset);
2344             pic16_emitcode("movx","@%s,a",r->name);           
2345         } else 
2346           pic16_emitcode("push","");// "(%s+%d)",
2347                      //regspic16[i].base,8*bank+regspic16[i].offset);
2348     }
2349     
2350     if (pushPsw) {
2351         if (options.useXstack) {
2352             pic16_emitcode("mov","a,psw");
2353             pic16_emitcode("movx","@%s,a",r->name);     
2354             pic16_emitcode("inc","%s",r->name);
2355             pic16_emitcode("mov","_spx,%s",r->name);       
2356             pic16_freeAsmop (NULL,aop,ic,TRUE);
2357             
2358         } else
2359             pic16_emitcode("push","psw");
2360         
2361         pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2362     }
2363     ic->bankSaved = 1;
2364 #endif
2365 }
2366
2367 /*-----------------------------------------------------------------*/
2368 /* genCall - generates a call statement                            */
2369 /*-----------------------------------------------------------------*/
2370 static void genCall (iCode *ic)
2371 {
2372   sym_link *dtype;   
2373
2374   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2375
2376   /* if caller saves & we have not saved then */
2377   if (!ic->regsSaved)
2378     saveRegisters(ic);
2379
2380   /* if we are calling a function that is not using
2381      the same register bank then we need to save the
2382      destination registers on the stack */
2383   dtype = operandType(IC_LEFT(ic));
2384   if (currFunc && dtype && 
2385       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2386       IFFUNC_ISISR(currFunc->type) &&
2387       !ic->bankSaved) 
2388
2389     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2390
2391   /* if send set is not empty the assign */
2392   if (_G.sendSet) {
2393     iCode *sic;
2394     /* For the Pic port, there is no data stack.
2395      * So parameters passed to functions are stored
2396      * in registers. (The pCode optimizer will get
2397      * rid of most of these :).
2398      */
2399     int psuedoStkPtr=-1; 
2400     int firstTimeThruLoop = 1;
2401
2402     _G.sendSet = reverseSet(_G.sendSet);
2403
2404     /* First figure how many parameters are getting passed */
2405     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2406          sic = setNextItem(_G.sendSet)) {
2407
2408       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2409       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2410       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2411     }
2412
2413     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2414          sic = setNextItem(_G.sendSet)) {
2415       int size, offset = 0;
2416
2417       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2418       size = AOP_SIZE(IC_LEFT(sic));
2419
2420       while (size--) {
2421         DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2422                              pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2423
2424         if(!firstTimeThruLoop) {
2425           /* If this is not the first time we've been through the loop
2426            * then we need to save the parameter in a temporary
2427            * register. The last byte of the last parameter is
2428            * passed in W. */
2429           pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2430
2431         }
2432         firstTimeThruLoop=0;
2433
2434         //if (strcmp(l,fReturn[offset])) {
2435         mov2w (AOP(IC_LEFT(sic)),  offset);
2436 /*
2437         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2438              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2439           pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2440         else
2441           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2442 */
2443         //}
2444         offset++;
2445       }
2446       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2447     }
2448     _G.sendSet = NULL;
2449   }
2450   /* make the call */
2451   pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2452                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2453                                       OP_SYMBOL(IC_LEFT(ic))->name));
2454
2455   GpsuedoStkPtr=0;
2456   /* if we need assign a result value */
2457   if ((IS_ITEMP(IC_RESULT(ic)) && 
2458        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2459         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2460       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2461
2462     _G.accInUse++;
2463     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2464     _G.accInUse--;
2465
2466     assignResultValue(IC_RESULT(ic));
2467
2468     DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2469                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2470                 
2471     pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2472   }
2473
2474   /* adjust the stack for parameters if 
2475      required */
2476   if (ic->parmBytes) {
2477     int i;
2478     if (ic->parmBytes > 3) {
2479       pic16_emitcode("mov","a,%s",spname);
2480       pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2481       pic16_emitcode("mov","%s,a",spname);
2482     } else 
2483       for ( i = 0 ; i <  ic->parmBytes ;i++)
2484         pic16_emitcode("dec","%s",spname);
2485
2486   }
2487
2488   /* if register bank was saved then pop them */
2489   if (ic->bankSaved)
2490     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2491
2492   /* if we hade saved some registers then unsave them */
2493   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2494     unsaveRegisters (ic);
2495
2496
2497 }
2498
2499 /*-----------------------------------------------------------------*/
2500 /* genPcall - generates a call by pointer statement                */
2501 /*-----------------------------------------------------------------*/
2502 static void genPcall (iCode *ic)
2503 {
2504     sym_link *dtype;
2505     symbol *rlbl = newiTempLabel(NULL);
2506
2507
2508     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2509     /* if caller saves & we have not saved then */
2510     if (!ic->regsSaved)
2511         saveRegisters(ic);
2512
2513     /* if we are calling a function that is not using
2514     the same register bank then we need to save the
2515     destination registers on the stack */
2516     dtype = operandType(IC_LEFT(ic));
2517     if (currFunc && dtype && 
2518         IFFUNC_ISISR(currFunc->type) &&
2519         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2520         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2521
2522
2523     /* push the return address on to the stack */
2524     pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2525     pic16_emitcode("push","acc");    
2526     pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2527     pic16_emitcode("push","acc");
2528     
2529     if (options.model == MODEL_FLAT24)
2530     {
2531         pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2532         pic16_emitcode("push","acc");    
2533     }
2534
2535     /* now push the calling address */
2536     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2537
2538     pushSide(IC_LEFT(ic), FPTRSIZE);
2539
2540     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2541
2542     /* if send set is not empty the assign */
2543     if (_G.sendSet) {
2544         iCode *sic ;
2545
2546         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2547              sic = setNextItem(_G.sendSet)) {
2548             int size, offset = 0;
2549             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2550             size = AOP_SIZE(IC_LEFT(sic));
2551             while (size--) {
2552                 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2553                                 FALSE,FALSE);
2554                 if (strcmp(l,fReturn[offset]))
2555                     pic16_emitcode("mov","%s,%s",
2556                              fReturn[offset],
2557                              l);
2558                 offset++;
2559             }
2560             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2561         }
2562         _G.sendSet = NULL;
2563     }
2564
2565     pic16_emitcode("ret","");
2566     pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2567
2568
2569     /* if we need assign a result value */
2570     if ((IS_ITEMP(IC_RESULT(ic)) &&
2571          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2572           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2573         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2574
2575         _G.accInUse++;
2576         pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2577         _G.accInUse--;
2578         
2579         assignResultValue(IC_RESULT(ic));
2580
2581         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2582     }
2583
2584     /* adjust the stack for parameters if 
2585     required */
2586     if (ic->parmBytes) {
2587         int i;
2588         if (ic->parmBytes > 3) {
2589             pic16_emitcode("mov","a,%s",spname);
2590             pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2591             pic16_emitcode("mov","%s,a",spname);
2592         } else 
2593             for ( i = 0 ; i <  ic->parmBytes ;i++)
2594                 pic16_emitcode("dec","%s",spname);
2595
2596     }
2597
2598     /* if register bank was saved then unsave them */
2599     if (currFunc && dtype && 
2600         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2601         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2602
2603     /* if we hade saved some registers then
2604     unsave them */
2605     if (ic->regsSaved)
2606         unsaveRegisters (ic);
2607
2608 }
2609
2610 /*-----------------------------------------------------------------*/
2611 /* resultRemat - result  is rematerializable                       */
2612 /*-----------------------------------------------------------------*/
2613 static int resultRemat (iCode *ic)
2614 {
2615   //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2616   if (SKIP_IC(ic) || ic->op == IFX)
2617     return 0;
2618
2619   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2620     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2621     if (sym->remat && !POINTER_SET(ic)) 
2622       return 1;
2623   }
2624
2625   return 0;
2626 }
2627
2628 #if defined(__BORLANDC__) || defined(_MSC_VER)
2629 #define STRCASECMP stricmp
2630 #else
2631 #define STRCASECMP strcasecmp
2632 #endif
2633
2634 #if 0
2635 /*-----------------------------------------------------------------*/
2636 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2637 /*-----------------------------------------------------------------*/
2638 static bool inExcludeList(char *s)
2639 {
2640   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2641     int i =0;
2642     
2643     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2644     if (options.excludeRegs[i] &&
2645     STRCASECMP(options.excludeRegs[i],"none") == 0)
2646         return FALSE ;
2647
2648     for ( i = 0 ; options.excludeRegs[i]; i++) {
2649         if (options.excludeRegs[i] &&
2650         STRCASECMP(s,options.excludeRegs[i]) == 0)
2651             return TRUE;
2652     }
2653     return FALSE ;
2654 }
2655 #endif
2656
2657 /*-----------------------------------------------------------------*/
2658 /* genFunction - generated code for function entry                 */
2659 /*-----------------------------------------------------------------*/
2660 static void genFunction (iCode *ic)
2661 {
2662     symbol *sym;
2663     sym_link *ftype;
2664
2665     DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2666
2667     labelOffset += (max_key+4);
2668     max_key=0;
2669     GpsuedoStkPtr=0;
2670     _G.nRegsSaved = 0;
2671     /* create the function header */
2672     pic16_emitcode(";","-----------------------------------------");
2673     pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2674     pic16_emitcode(";","-----------------------------------------");
2675
2676     pic16_emitcode("","%s:",sym->rname);
2677     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2678
2679     ftype = operandType(IC_LEFT(ic));
2680
2681     /* if critical function then turn interrupts off */
2682     if (IFFUNC_ISCRITICAL(ftype))
2683         pic16_emitcode("clr","ea");
2684
2685     /* here we need to generate the equates for the
2686        register bank if required */
2687 #if 0
2688     if (FUNC_REGBANK(ftype) != rbank) {
2689         int i ;
2690
2691         rbank = FUNC_REGBANK(ftype);
2692         for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2693             if (strcmp(regspic16[i].base,"0") == 0)
2694                 pic16_emitcode("","%s = 0x%02x",
2695                          regspic16[i].dname,
2696                          8*rbank+regspic16[i].offset);
2697             else
2698                 pic16_emitcode ("","%s = %s + 0x%02x",
2699                           regspic16[i].dname,
2700                           regspic16[i].base,
2701                           8*rbank+regspic16[i].offset);
2702         }
2703     }
2704 #endif
2705
2706     /* if this is an interrupt service routine then
2707     save acc, b, dpl, dph  */
2708     if (IFFUNC_ISISR(sym->type)) {
2709       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2710       pic16_emitpcodeNULLop(POC_NOP);
2711       pic16_emitpcodeNULLop(POC_NOP);
2712       pic16_emitpcodeNULLop(POC_NOP);
2713       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
2714       pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2715       pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2716       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
2717
2718       pic16_pBlockConvert2ISR(pb);
2719 #if 0  
2720         if (!inExcludeList("acc"))          
2721             pic16_emitcode ("push","acc");      
2722         if (!inExcludeList("b"))
2723             pic16_emitcode ("push","b");
2724         if (!inExcludeList("dpl"))
2725             pic16_emitcode ("push","dpl");
2726         if (!inExcludeList("dph"))
2727             pic16_emitcode ("push","dph");
2728         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2729         {
2730             pic16_emitcode ("push", "dpx");
2731             /* Make sure we're using standard DPTR */
2732             pic16_emitcode ("push", "dps");
2733             pic16_emitcode ("mov", "dps, #0x00");
2734             if (options.stack10bit)
2735             {   
2736                 /* This ISR could conceivably use DPTR2. Better save it. */
2737                 pic16_emitcode ("push", "dpl1");
2738                 pic16_emitcode ("push", "dph1");
2739                 pic16_emitcode ("push", "dpx1");
2740             }
2741         }
2742         /* if this isr has no bank i.e. is going to
2743            run with bank 0 , then we need to save more
2744            registers :-) */
2745         if (!FUNC_REGBANK(sym->type)) {
2746
2747             /* if this function does not call any other
2748                function then we can be economical and
2749                save only those registers that are used */
2750             if (! IFFUNC_HASFCALL(sym->type)) {
2751                 int i;
2752
2753                 /* if any registers used */
2754                 if (sym->regsUsed) {
2755                     /* save the registers used */
2756                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2757                         if (bitVectBitValue(sym->regsUsed,i) ||
2758                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2759                           pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                         
2760                     }
2761                 }
2762                 
2763             } else {
2764                 /* this function has  a function call cannot
2765                    determines register usage so we will have the
2766                    entire bank */
2767                 saverbank(0,ic,FALSE);
2768             }       
2769         }
2770 #endif
2771     } else {
2772         /* if callee-save to be used for this function
2773            then save the registers being used in this function */
2774         if (IFFUNC_CALLEESAVES(sym->type)) {
2775             int i;
2776             
2777             /* if any registers used */
2778             if (sym->regsUsed) {
2779                 /* save the registers used */
2780                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2781                     if (bitVectBitValue(sym->regsUsed,i) ||
2782                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2783                       //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2784                         _G.nRegsSaved++;
2785                     }
2786                 }
2787             }
2788         }
2789     }
2790
2791     /* set the register bank to the desired value */
2792     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2793         pic16_emitcode("push","psw");
2794         pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2795     }
2796
2797     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2798
2799         if (options.useXstack) {
2800             pic16_emitcode("mov","r0,%s",spname);
2801             pic16_emitcode("mov","a,_bp");
2802             pic16_emitcode("movx","@r0,a");
2803             pic16_emitcode("inc","%s",spname);
2804         }
2805         else
2806         {
2807             /* set up the stack */
2808             pic16_emitcode ("push","_bp");     /* save the callers stack  */
2809         }
2810         pic16_emitcode ("mov","_bp,%s",spname);
2811     }
2812
2813     /* adjust the stack for the function */
2814     if (sym->stack) {
2815
2816         int i = sym->stack;
2817         if (i > 256 ) 
2818             werror(W_STACK_OVERFLOW,sym->name);
2819
2820         if (i > 3 && sym->recvSize < 4) {              
2821
2822             pic16_emitcode ("mov","a,sp");
2823             pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2824             pic16_emitcode ("mov","sp,a");
2825            
2826         }
2827         else
2828             while(i--)
2829                 pic16_emitcode("inc","sp");
2830     }
2831
2832      if (sym->xstack) {
2833
2834         pic16_emitcode ("mov","a,_spx");
2835         pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2836         pic16_emitcode ("mov","_spx,a");
2837     }    
2838
2839 }
2840
2841 /*-----------------------------------------------------------------*/
2842 /* genEndFunction - generates epilogue for functions               */
2843 /*-----------------------------------------------------------------*/
2844 static void genEndFunction (iCode *ic)
2845 {
2846     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2847
2848     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2849
2850     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2851     {
2852         pic16_emitcode ("mov","%s,_bp",spname);
2853     }
2854
2855     /* if use external stack but some variables were
2856     added to the local stack then decrement the
2857     local stack */
2858     if (options.useXstack && sym->stack) {      
2859         pic16_emitcode("mov","a,sp");
2860         pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2861         pic16_emitcode("mov","sp,a");
2862     }
2863
2864
2865     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2866         if (options.useXstack) {
2867             pic16_emitcode("mov","r0,%s",spname);
2868             pic16_emitcode("movx","a,@r0");
2869             pic16_emitcode("mov","_bp,a");
2870             pic16_emitcode("dec","%s",spname);
2871         }
2872         else
2873         {
2874             pic16_emitcode ("pop","_bp");
2875         }
2876     }
2877
2878     /* restore the register bank  */    
2879     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2880         pic16_emitcode ("pop","psw");
2881
2882     if (IFFUNC_ISISR(sym->type)) {
2883
2884         /* now we need to restore the registers */
2885         /* if this isr has no bank i.e. is going to
2886            run with bank 0 , then we need to save more
2887            registers :-) */
2888         if (!FUNC_REGBANK(sym->type)) {
2889             
2890             /* if this function does not call any other
2891                function then we can be economical and
2892                save only those registers that are used */
2893             if (! IFFUNC_HASFCALL(sym->type)) {
2894                 int i;
2895                 
2896                 /* if any registers used */
2897                 if (sym->regsUsed) {
2898                     /* save the registers used */
2899                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2900                         if (bitVectBitValue(sym->regsUsed,i) ||
2901                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2902                           pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2903                     }
2904                 }
2905                 
2906             } else {
2907                 /* this function has  a function call cannot
2908                    determines register usage so we will have the
2909                    entire bank */
2910                 unsaverbank(0,ic,FALSE);
2911             }       
2912         }
2913 #if 0
2914         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2915         {
2916             if (options.stack10bit)
2917             {
2918                 pic16_emitcode ("pop", "dpx1");
2919                 pic16_emitcode ("pop", "dph1");
2920                 pic16_emitcode ("pop", "dpl1");
2921             }   
2922             pic16_emitcode ("pop", "dps");
2923             pic16_emitcode ("pop", "dpx");
2924         }
2925         if (!inExcludeList("dph"))
2926             pic16_emitcode ("pop","dph");
2927         if (!inExcludeList("dpl"))
2928             pic16_emitcode ("pop","dpl");
2929         if (!inExcludeList("b"))
2930             pic16_emitcode ("pop","b");
2931         if (!inExcludeList("acc"))
2932             pic16_emitcode ("pop","acc");
2933
2934         if (IFFUNC_ISCRITICAL(sym->type))
2935             pic16_emitcode("setb","ea");
2936 #endif
2937
2938         /* if debug then send end of function */
2939 /*      if (options.debug && currFunc) { */
2940         if (currFunc) {
2941             _G.debugLine = 1;
2942             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2943                      FileBaseName(ic->filename),currFunc->lastLine,
2944                      ic->level,ic->block); 
2945             if (IS_STATIC(currFunc->etype))         
2946                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2947             else
2948                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2949             _G.debugLine = 0;
2950         }
2951         
2952         pic16_emitcode ("reti","");
2953
2954         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2955         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2956         pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
2957         pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
2958         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2959         pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2960
2961         pic16_emitpcodeNULLop(POC_RETFIE);
2962
2963     }
2964     else {
2965         if (IFFUNC_ISCRITICAL(sym->type))
2966             pic16_emitcode("setb","ea");
2967         
2968         if (IFFUNC_CALLEESAVES(sym->type)) {
2969             int i;
2970             
2971             /* if any registers used */
2972             if (sym->regsUsed) {
2973                 /* save the registers used */
2974                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2975                     if (bitVectBitValue(sym->regsUsed,i) ||
2976                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2977                       pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2978                 }
2979             }
2980             
2981         }
2982
2983         /* if debug then send end of function */
2984         if (currFunc) {
2985             _G.debugLine = 1;
2986             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2987                      FileBaseName(ic->filename),currFunc->lastLine,
2988                      ic->level,ic->block); 
2989             if (IS_STATIC(currFunc->etype))         
2990                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2991             else
2992                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2993             _G.debugLine = 0;
2994         }
2995
2996         pic16_emitcode ("return","");
2997         pic16_emitpcodeNULLop(POC_RETURN);
2998
2999         /* Mark the end of a function */
3000         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3001     }
3002
3003 }
3004
3005 /*-----------------------------------------------------------------*/
3006 /* genRet - generate code for return statement                     */
3007 /*-----------------------------------------------------------------*/
3008 static void genRet (iCode *ic)
3009 {
3010   int size,offset = 0 , pushed = 0;
3011     
3012   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3013   /* if we have no return value then
3014      just generate the "ret" */
3015   if (!IC_LEFT(ic)) 
3016     goto jumpret;       
3017     
3018   /* we have something to return then
3019      move the return value into place */
3020   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3021   size = AOP_SIZE(IC_LEFT(ic));
3022     
3023   while (size--) {
3024     char *l ;
3025     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3026       /* #NOCHANGE */
3027       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3028                  FALSE,TRUE);
3029       pic16_emitcode("push","%s",l);
3030       pushed++;
3031     } else {
3032       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3033                  FALSE,FALSE);
3034       if (strcmp(fReturn[offset],l)) {
3035         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3036             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3037           pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3038         }else {
3039           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3040         }
3041         if(size) {
3042           pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3043         }
3044         offset++;
3045       }
3046     }
3047   }    
3048
3049   if (pushed) {
3050     while(pushed) {
3051       pushed--;
3052       if (strcmp(fReturn[pushed],"a"))
3053         pic16_emitcode("pop",fReturn[pushed]);
3054       else
3055         pic16_emitcode("pop","acc");
3056     }
3057   }
3058   pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3059     
3060  jumpret:
3061   /* generate a jump to the return label
3062      if the next is not the return statement */
3063   if (!(ic->next && ic->next->op == LABEL &&
3064         IC_LABEL(ic->next) == returnLabel)) {
3065         
3066     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3067     pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3068   }
3069     
3070 }
3071
3072 /*-----------------------------------------------------------------*/
3073 /* genLabel - generates a label                                    */
3074 /*-----------------------------------------------------------------*/
3075 static void genLabel (iCode *ic)
3076 {
3077     /* special case never generate */
3078     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3079     if (IC_LABEL(ic) == entryLabel)
3080         return ;
3081
3082     pic16_emitpLabel(IC_LABEL(ic)->key);
3083     pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3084 }
3085
3086 /*-----------------------------------------------------------------*/
3087 /* genGoto - generates a goto                                      */
3088 /*-----------------------------------------------------------------*/
3089 //tsd
3090 static void genGoto (iCode *ic)
3091 {
3092   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3093   pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3094 }
3095
3096
3097 /*-----------------------------------------------------------------*/
3098 /* genMultbits :- multiplication of bits                           */
3099 /*-----------------------------------------------------------------*/
3100 static void genMultbits (operand *left, 
3101                          operand *right, 
3102                          operand *result)
3103 {
3104   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3105
3106   if(!pic16_sameRegs(AOP(result),AOP(right)))
3107     pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),0));
3108
3109   pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3110   pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3111   pic16_emitpcode(POC_BCF,  pic16_popGet(AOP(result),0));
3112
3113 }
3114
3115
3116 /*-----------------------------------------------------------------*/
3117 /* genMultOneByte : 8 bit multiplication & division                */
3118 /*-----------------------------------------------------------------*/
3119 static void genMultOneByte (operand *left,
3120                             operand *right,
3121                             operand *result)
3122 {
3123   sym_link *opetype = operandType(result);
3124
3125   // symbol *lbl ;
3126   int size,offset;
3127
3128   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3129   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3130   DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3131
3132   /* (if two literals, the value is computed before) */
3133   /* if one literal, literal on the right */
3134   if (AOP_TYPE(left) == AOP_LIT){
3135     operand *t = right;
3136     right = left;
3137     left = t;
3138   }
3139
3140   size = AOP_SIZE(result);
3141   if(size == 1) {
3142
3143     if (AOP_TYPE(right) == AOP_LIT){
3144       pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3145                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3146                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3147                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3148       pic16_emitcode("call","genMultLit");
3149     } else {
3150       pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3151                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3152                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3153                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3154       pic16_emitcode("call","pic16_genMult8X8_8");
3155
3156     }
3157     pic16_genMult8X8_8 (left, right,result);
3158
3159
3160     /* signed or unsigned */
3161     //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3162     //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3163     //MOVA(l);       
3164     //pic16_emitcode("mul","ab");
3165     /* if result size = 1, mul signed = mul unsigned */
3166     //pic16_aopPut(AOP(result),"a",0);
3167
3168   } else {  // (size > 1)
3169
3170     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3171                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3172                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3173                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
3174
3175     if (SPEC_USIGN(opetype)){
3176       pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3177       pic16_genUMult8X8_16 (left, right, result, NULL);
3178
3179       if (size > 2) {
3180         /* for filling the MSBs */
3181         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),2));
3182         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),3));
3183       }
3184     }
3185     else{
3186       pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3187
3188       pic16_emitcode("mov","a,b");
3189
3190       /* adjust the MSB if left or right neg */
3191
3192       /* if one literal */
3193       if (AOP_TYPE(right) == AOP_LIT){
3194         pic16_emitcode("multiply ","right is a lit");
3195         /* AND literal negative */
3196         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3197           /* adjust MSB (c==0 after mul) */
3198           pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3199         }
3200       }
3201       else{
3202         pic16_genSMult8X8_16 (left, right, result, NULL);
3203       }
3204
3205       if(size > 2){
3206         pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3207         /* get the sign */
3208         pic16_emitcode("rlc","a");
3209         pic16_emitcode("subb","a,acc");
3210       }
3211     }
3212
3213     size -= 2;   
3214     offset = 2;
3215     if (size > 0)
3216       while (size--)
3217         pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3218     //pic16_aopPut(AOP(result),"a",offset++);
3219   }
3220 }
3221
3222 /*-----------------------------------------------------------------*/
3223 /* genMult - generates code for multiplication                     */
3224 /*-----------------------------------------------------------------*/
3225 static void genMult (iCode *ic)
3226 {
3227     operand *left = IC_LEFT(ic);
3228     operand *right = IC_RIGHT(ic);
3229     operand *result= IC_RESULT(ic);   
3230
3231     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3232     /* assign the amsops */
3233     pic16_aopOp (left,ic,FALSE);
3234     pic16_aopOp (right,ic,FALSE);
3235     pic16_aopOp (result,ic,TRUE);
3236
3237   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3238
3239     /* special cases first */
3240     /* both are bits */
3241     if (AOP_TYPE(left) == AOP_CRY &&
3242         AOP_TYPE(right)== AOP_CRY) {
3243         genMultbits(left,right,result);
3244         goto release ;
3245     }
3246
3247     /* if both are of size == 1 */
3248     if (AOP_SIZE(left) == 1 &&
3249         AOP_SIZE(right) == 1 ) {
3250         genMultOneByte(left,right,result);
3251         goto release ;
3252     }
3253
3254     pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3255
3256     /* should have been converted to function call */
3257     //assert(0) ;
3258
3259 release :
3260     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3261     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3262     pic16_freeAsmop(result,NULL,ic,TRUE); 
3263 }
3264
3265 /*-----------------------------------------------------------------*/
3266 /* genDivbits :- division of bits                                  */
3267 /*-----------------------------------------------------------------*/
3268 static void genDivbits (operand *left, 
3269                         operand *right, 
3270                         operand *result)
3271 {
3272
3273     char *l;
3274
3275     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3276     /* the result must be bit */    
3277     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3278     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3279
3280     MOVA(l);    
3281
3282     pic16_emitcode("div","ab");
3283     pic16_emitcode("rrc","a");
3284     pic16_aopPut(AOP(result),"c",0);
3285 }
3286
3287 /*-----------------------------------------------------------------*/
3288 /* genDivOneByte : 8 bit division                                  */
3289 /*-----------------------------------------------------------------*/
3290 static void genDivOneByte (operand *left,
3291                            operand *right,
3292                            operand *result)
3293 {
3294     sym_link *opetype = operandType(result);
3295     char *l ;
3296     symbol *lbl ;
3297     int size,offset;
3298
3299     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3300     size = AOP_SIZE(result) - 1;
3301     offset = 1;
3302     /* signed or unsigned */
3303     if (SPEC_USIGN(opetype)) {
3304         /* unsigned is easy */
3305         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3306         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3307         MOVA(l);        
3308         pic16_emitcode("div","ab");
3309         pic16_aopPut(AOP(result),"a",0);
3310         while (size--)
3311             pic16_aopPut(AOP(result),zero,offset++);
3312         return ;
3313     }
3314
3315     /* signed is a little bit more difficult */
3316
3317     /* save the signs of the operands */
3318     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3319     MOVA(l);    
3320     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3321     pic16_emitcode("push","acc"); /* save it on the stack */
3322
3323     /* now sign adjust for both left & right */
3324     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3325     MOVA(l);       
3326     lbl = newiTempLabel(NULL);
3327     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3328     pic16_emitcode("cpl","a");   
3329     pic16_emitcode("inc","a");
3330     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3331     pic16_emitcode("mov","b,a");
3332
3333     /* sign adjust left side */
3334     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3335     MOVA(l);
3336
3337     lbl = newiTempLabel(NULL);
3338     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3339     pic16_emitcode("cpl","a");
3340     pic16_emitcode("inc","a");
3341     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3342
3343     /* now the division */
3344     pic16_emitcode("div","ab");
3345     /* we are interested in the lower order
3346     only */
3347     pic16_emitcode("mov","b,a");
3348     lbl = newiTempLabel(NULL);
3349     pic16_emitcode("pop","acc");   
3350     /* if there was an over flow we don't 
3351     adjust the sign of the result */
3352     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3353     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3354     CLRC;
3355     pic16_emitcode("clr","a");
3356     pic16_emitcode("subb","a,b");
3357     pic16_emitcode("mov","b,a");
3358     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3359
3360     /* now we are done */
3361     pic16_aopPut(AOP(result),"b",0);
3362     if(size > 0){
3363         pic16_emitcode("mov","c,b.7");
3364         pic16_emitcode("subb","a,acc");   
3365     }
3366     while (size--)
3367         pic16_aopPut(AOP(result),"a",offset++);
3368
3369 }
3370
3371 /*-----------------------------------------------------------------*/
3372 /* genDiv - generates code for division                            */
3373 /*-----------------------------------------------------------------*/
3374 static void genDiv (iCode *ic)
3375 {
3376     operand *left = IC_LEFT(ic);
3377     operand *right = IC_RIGHT(ic);
3378     operand *result= IC_RESULT(ic);   
3379
3380     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3381     /* assign the amsops */
3382     pic16_aopOp (left,ic,FALSE);
3383     pic16_aopOp (right,ic,FALSE);
3384     pic16_aopOp (result,ic,TRUE);
3385
3386     /* special cases first */
3387     /* both are bits */
3388     if (AOP_TYPE(left) == AOP_CRY &&
3389         AOP_TYPE(right)== AOP_CRY) {
3390         genDivbits(left,right,result);
3391         goto release ;
3392     }
3393
3394     /* if both are of size == 1 */
3395     if (AOP_SIZE(left) == 1 &&
3396         AOP_SIZE(right) == 1 ) {
3397         genDivOneByte(left,right,result);
3398         goto release ;
3399     }
3400
3401     /* should have been converted to function call */
3402     assert(0);
3403 release :
3404     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3405     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3406     pic16_freeAsmop(result,NULL,ic,TRUE); 
3407 }
3408
3409 /*-----------------------------------------------------------------*/
3410 /* genModbits :- modulus of bits                                   */
3411 /*-----------------------------------------------------------------*/
3412 static void genModbits (operand *left, 
3413                         operand *right, 
3414                         operand *result)
3415 {
3416
3417     char *l;
3418
3419     /* the result must be bit */    
3420     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3421     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3422
3423     MOVA(l);       
3424
3425     pic16_emitcode("div","ab");
3426     pic16_emitcode("mov","a,b");
3427     pic16_emitcode("rrc","a");
3428     pic16_aopPut(AOP(result),"c",0);
3429 }
3430
3431 /*-----------------------------------------------------------------*/
3432 /* genModOneByte : 8 bit modulus                                   */
3433 /*-----------------------------------------------------------------*/
3434 static void genModOneByte (operand *left,
3435                            operand *right,
3436                            operand *result)
3437 {
3438     sym_link *opetype = operandType(result);
3439     char *l ;
3440     symbol *lbl ;
3441
3442     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3443     /* signed or unsigned */
3444     if (SPEC_USIGN(opetype)) {
3445         /* unsigned is easy */
3446         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3447         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3448         MOVA(l);    
3449         pic16_emitcode("div","ab");
3450         pic16_aopPut(AOP(result),"b",0);
3451         return ;
3452     }
3453
3454     /* signed is a little bit more difficult */
3455
3456     /* save the signs of the operands */
3457     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3458     MOVA(l);
3459
3460     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3461     pic16_emitcode("push","acc"); /* save it on the stack */
3462
3463     /* now sign adjust for both left & right */
3464     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3465     MOVA(l);
3466
3467     lbl = newiTempLabel(NULL);
3468     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3469     pic16_emitcode("cpl","a");   
3470     pic16_emitcode("inc","a");
3471     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3472     pic16_emitcode("mov","b,a"); 
3473
3474     /* sign adjust left side */
3475     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3476     MOVA(l);
3477
3478     lbl = newiTempLabel(NULL);
3479     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3480     pic16_emitcode("cpl","a");   
3481     pic16_emitcode("inc","a");
3482     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3483
3484     /* now the multiplication */
3485     pic16_emitcode("div","ab");
3486     /* we are interested in the lower order
3487     only */
3488     lbl = newiTempLabel(NULL);
3489     pic16_emitcode("pop","acc");   
3490     /* if there was an over flow we don't 
3491     adjust the sign of the result */
3492     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3493     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3494     CLRC ;
3495     pic16_emitcode("clr","a");
3496     pic16_emitcode("subb","a,b");
3497     pic16_emitcode("mov","b,a");
3498     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3499
3500     /* now we are done */
3501     pic16_aopPut(AOP(result),"b",0);
3502
3503 }
3504
3505 /*-----------------------------------------------------------------*/
3506 /* genMod - generates code for division                            */
3507 /*-----------------------------------------------------------------*/
3508 static void genMod (iCode *ic)
3509 {
3510     operand *left = IC_LEFT(ic);
3511     operand *right = IC_RIGHT(ic);
3512     operand *result= IC_RESULT(ic);  
3513
3514     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3515     /* assign the amsops */
3516     pic16_aopOp (left,ic,FALSE);
3517     pic16_aopOp (right,ic,FALSE);
3518     pic16_aopOp (result,ic,TRUE);
3519
3520     /* special cases first */
3521     /* both are bits */
3522     if (AOP_TYPE(left) == AOP_CRY &&
3523         AOP_TYPE(right)== AOP_CRY) {
3524         genModbits(left,right,result);
3525         goto release ;
3526     }
3527
3528     /* if both are of size == 1 */
3529     if (AOP_SIZE(left) == 1 &&
3530         AOP_SIZE(right) == 1 ) {
3531         genModOneByte(left,right,result);
3532         goto release ;
3533     }
3534
3535     /* should have been converted to function call */
3536     assert(0);
3537
3538 release :
3539     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3540     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3541     pic16_freeAsmop(result,NULL,ic,TRUE); 
3542 }
3543
3544 /*-----------------------------------------------------------------*/
3545 /* genIfxJump :- will create a jump depending on the ifx           */
3546 /*-----------------------------------------------------------------*/
3547 /*
3548   note: May need to add parameter to indicate when a variable is in bit space.
3549 */
3550 static void genIfxJump (iCode *ic, char *jval)
3551 {
3552
3553     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3554     /* if true label then we jump if condition
3555     supplied is true */
3556     if ( IC_TRUE(ic) ) {
3557
3558         if(strcmp(jval,"a") == 0)
3559           emitSKPZ;
3560         else if (strcmp(jval,"c") == 0)
3561           emitSKPC;
3562         else {
3563           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3564           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1));
3565         }
3566
3567         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3568         pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3569
3570     }
3571     else {
3572         /* false label is present */
3573         if(strcmp(jval,"a") == 0)
3574           emitSKPNZ;
3575         else if (strcmp(jval,"c") == 0)
3576           emitSKPNC;
3577         else {
3578           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3579           pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1));
3580         }
3581
3582         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3583         pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3584
3585     }
3586
3587
3588     /* mark the icode as generated */
3589     ic->generated = 1;
3590 }
3591
3592 /*-----------------------------------------------------------------*/
3593 /* genSkip                                                         */
3594 /*-----------------------------------------------------------------*/
3595 static void genSkip(iCode *ifx,int status_bit)
3596 {
3597   if(!ifx)
3598     return;
3599
3600   if ( IC_TRUE(ifx) ) {
3601     switch(status_bit) {
3602     case 'z':
3603       emitSKPNZ;
3604       break;
3605
3606     case 'c':
3607       emitSKPNC;
3608       break;
3609
3610     case 'd':
3611       emitSKPDC;
3612       break;
3613
3614     }
3615
3616     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3617     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3618
3619   } else {
3620
3621     switch(status_bit) {
3622
3623     case 'z':
3624       emitSKPZ;
3625       break;
3626
3627     case 'c':
3628       emitSKPC;
3629       break;
3630
3631     case 'd':
3632       emitSKPDC;
3633       break;
3634     }
3635     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3636     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3637
3638   }
3639
3640 }
3641
3642 /*-----------------------------------------------------------------*/
3643 /* genSkipc                                                        */
3644 /*-----------------------------------------------------------------*/
3645 static void genSkipc(resolvedIfx *rifx)
3646 {
3647   if(!rifx)
3648     return;
3649
3650   if(rifx->condition)
3651     emitSKPC;
3652   else
3653     emitSKPNC;
3654
3655   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3656   rifx->generated = 1;
3657 }
3658
3659 /*-----------------------------------------------------------------*/
3660 /* genSkipz2                                                       */
3661 /*-----------------------------------------------------------------*/
3662 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3663 {
3664   if(!rifx)
3665     return;
3666
3667   if( (rifx->condition ^ invert_condition) & 1)
3668     emitSKPZ;
3669   else
3670     emitSKPNZ;
3671
3672   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3673   rifx->generated = 1;
3674 }
3675
3676 /*-----------------------------------------------------------------*/
3677 /* genSkipz                                                        */
3678 /*-----------------------------------------------------------------*/
3679 static void genSkipz(iCode *ifx, int condition)
3680 {
3681   if(!ifx)
3682     return;
3683
3684   if(condition)
3685     emitSKPNZ;
3686   else
3687     emitSKPZ;
3688
3689   if ( IC_TRUE(ifx) )
3690     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3691   else
3692     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3693
3694   if ( IC_TRUE(ifx) )
3695     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3696   else
3697     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3698
3699 }
3700 /*-----------------------------------------------------------------*/
3701 /* genSkipCond                                                     */
3702 /*-----------------------------------------------------------------*/
3703 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3704 {
3705   if(!rifx)
3706     return;
3707
3708   if(rifx->condition)
3709     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3710   else
3711     pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3712
3713
3714   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3715   rifx->generated = 1;
3716 }
3717
3718 #if 0
3719 /*-----------------------------------------------------------------*/
3720 /* genChkZeroes :- greater or less than comparison                 */
3721 /*     For each byte in a literal that is zero, inclusive or the   */
3722 /*     the corresponding byte in the operand with W                */
3723 /*     returns true if any of the bytes are zero                   */
3724 /*-----------------------------------------------------------------*/
3725 static int genChkZeroes(operand *op, int lit,  int size)
3726 {
3727
3728   int i;
3729   int flag =1;
3730
3731   while(size--) {
3732     i = (lit >> (size*8)) & 0xff;
3733
3734     if(i==0) {
3735       if(flag) 
3736         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3737       else
3738         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3739       flag = 0;
3740     }
3741   }
3742
3743   return (flag==0);
3744 }
3745 #endif
3746
3747 /*-----------------------------------------------------------------*/
3748 /* genCmp :- greater or less than comparison                       */
3749 /*-----------------------------------------------------------------*/
3750 static void genCmp (operand *left,operand *right,
3751                     operand *result, iCode *ifx, int sign)
3752 {
3753   int size; //, offset = 0 ;
3754   unsigned long lit = 0L,i = 0;
3755   resolvedIfx rFalseIfx;
3756   //  resolvedIfx rTrueIfx;
3757   symbol *truelbl;
3758   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3759 /*
3760   if(ifx) {
3761     DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3762     DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3763   }
3764 */
3765
3766   resolveIfx(&rFalseIfx,ifx);
3767   truelbl  = newiTempLabel(NULL);
3768   size = max(AOP_SIZE(left),AOP_SIZE(right));
3769
3770   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3771
3772 #define _swapp
3773
3774   /* if literal is on the right then swap with left */
3775   if ((AOP_TYPE(right) == AOP_LIT)) {
3776     operand *tmp = right ;
3777     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3778     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3779 #ifdef _swapp
3780
3781     lit = (lit - 1) & mask;
3782     right = left;
3783     left = tmp;
3784     rFalseIfx.condition ^= 1;
3785 #endif
3786
3787   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3788     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3789   }
3790
3791
3792   //if(IC_TRUE(ifx) == NULL)
3793   /* if left & right are bit variables */
3794   if (AOP_TYPE(left) == AOP_CRY &&
3795       AOP_TYPE(right) == AOP_CRY ) {
3796     pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3797     pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3798   } else {
3799     /* subtract right from left if at the
3800        end the carry flag is set then we know that
3801        left is greater than right */
3802
3803     //    {
3804
3805     symbol *lbl  = newiTempLabel(NULL);
3806
3807 #ifndef _swapp
3808     if(AOP_TYPE(right) == AOP_LIT) {
3809
3810       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3811
3812       DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3813
3814       /* special cases */
3815
3816       if(lit == 0) {
3817
3818         if(sign != 0) 
3819           genSkipCond(&rFalseIfx,left,size-1,7);
3820         else 
3821           /* no need to compare to 0...*/
3822           /* NOTE: this is a de-generate compare that most certainly 
3823            *       creates some dead code. */
3824           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3825
3826         if(ifx) ifx->generated = 1;
3827         return;
3828
3829       }
3830       size--;
3831
3832       if(size == 0) {
3833         //i = (lit >> (size*8)) & 0xff;
3834         DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3835         
3836         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3837
3838         i = ((0-lit) & 0xff);
3839         if(sign) {
3840           if( i == 0x81) { 
3841             /* lit is 0x7f, all signed chars are less than
3842              * this except for 0x7f itself */
3843             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3844             genSkipz2(&rFalseIfx,0);
3845           } else {
3846             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3847             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3848             genSkipc(&rFalseIfx);
3849           }
3850
3851         } else {
3852           if(lit == 1) {
3853             genSkipz2(&rFalseIfx,1);
3854           } else {
3855             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3856             genSkipc(&rFalseIfx);
3857           }
3858         }
3859
3860         if(ifx) ifx->generated = 1;
3861         return;
3862       }
3863
3864       /* chars are out of the way. now do ints and longs */
3865
3866
3867       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3868         
3869       /* special cases */
3870
3871       if(sign) {
3872
3873         if(lit == 0) {
3874           genSkipCond(&rFalseIfx,left,size,7);
3875           if(ifx) ifx->generated = 1;
3876           return;
3877         }
3878
3879         if(lit <0x100) {
3880           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3881
3882           //rFalseIfx.condition ^= 1;
3883           //genSkipCond(&rFalseIfx,left,size,7);
3884           //rFalseIfx.condition ^= 1;
3885
3886           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3887           if(rFalseIfx.condition)
3888             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3889           else
3890             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3891
3892           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3893           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3894           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3895
3896           while(size > 1)
3897             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3898
3899           if(rFalseIfx.condition) {
3900             emitSKPZ;
3901             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3902
3903           } else {
3904             emitSKPNZ;
3905           }
3906
3907           genSkipc(&rFalseIfx);
3908           pic16_emitpLabel(truelbl->key);
3909           if(ifx) ifx->generated = 1;
3910           return;
3911
3912         }
3913
3914         if(size == 1) {
3915
3916           if( (lit & 0xff) == 0) {
3917             /* lower byte is zero */
3918             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3919             i = ((lit >> 8) & 0xff) ^0x80;
3920             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3921             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3922             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3923             genSkipc(&rFalseIfx);
3924
3925
3926             if(ifx) ifx->generated = 1;
3927             return;
3928
3929           }
3930         } else {
3931           /* Special cases for signed longs */
3932           if( (lit & 0xffffff) == 0) {
3933             /* lower byte is zero */
3934             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3935             i = ((lit >> 8*3) & 0xff) ^0x80;
3936             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3937             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3938             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3939             genSkipc(&rFalseIfx);
3940
3941
3942             if(ifx) ifx->generated = 1;
3943             return;
3944
3945           }
3946
3947         }
3948
3949
3950         if(lit & (0x80 << (size*8))) {
3951           /* lit is negative */
3952           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3953
3954           //genSkipCond(&rFalseIfx,left,size,7);
3955
3956           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3957
3958           if(rFalseIfx.condition)
3959             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3960           else
3961             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3962
3963
3964         } else {
3965           /* lit is positive */
3966           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3967           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3968           if(rFalseIfx.condition)
3969             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3970           else
3971             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3972
3973         }
3974
3975         /*
3976           This works, but is only good for ints.
3977           It also requires a "known zero" register.
3978           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3979           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3980           pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
3981           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3982           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3983           genSkipc(&rFalseIfx);
3984
3985           pic16_emitpLabel(truelbl->key);
3986           if(ifx) ifx->generated = 1;
3987           return;
3988         **/
3989           
3990         /* There are no more special cases, so perform a general compare */
3991   
3992         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3993         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3994
3995         while(size--) {
3996
3997           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3998           emitSKPNZ;
3999           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4000         }
4001         //rFalseIfx.condition ^= 1;
4002         genSkipc(&rFalseIfx);
4003
4004         pic16_emitpLabel(truelbl->key);
4005
4006         if(ifx) ifx->generated = 1;
4007         return;
4008
4009
4010       }
4011
4012
4013       /* sign is out of the way. So now do an unsigned compare */
4014       DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4015
4016
4017       /* General case - compare to an unsigned literal on the right.*/
4018
4019       i = (lit >> (size*8)) & 0xff;
4020       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4021       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4022       while(size--) {
4023         i = (lit >> (size*8)) & 0xff;
4024
4025         if(i) {
4026           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4027           emitSKPNZ;
4028           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4029         } else {
4030           /* this byte of the lit is zero, 
4031            *if it's not the last then OR in the variable */
4032           if(size)
4033             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4034         }
4035       }
4036
4037
4038       pic16_emitpLabel(lbl->key);
4039       //if(emitFinalCheck)
4040       genSkipc(&rFalseIfx);
4041       if(sign)
4042         pic16_emitpLabel(truelbl->key);
4043
4044       if(ifx) ifx->generated = 1;
4045       return;
4046
4047
4048     }
4049 #endif  // _swapp
4050
4051     if(AOP_TYPE(left) == AOP_LIT) {
4052       //symbol *lbl = newiTempLabel(NULL);
4053
4054       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4055
4056
4057       DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4058
4059       /* Special cases */
4060       if((lit == 0) && (sign == 0)){
4061
4062         size--;
4063         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4064         while(size) 
4065           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4066
4067         genSkipz2(&rFalseIfx,0);
4068         if(ifx) ifx->generated = 1;
4069         return;
4070       }
4071
4072       if(size==1) {
4073         /* Special cases */
4074         lit &= 0xff;
4075         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4076           /* degenerate compare can never be true */
4077           if(rFalseIfx.condition == 0)
4078             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4079
4080           if(ifx) ifx->generated = 1;
4081           return;
4082         }
4083
4084         if(sign) {
4085           /* signed comparisons to a literal byte */
4086
4087           int lp1 = (lit+1) & 0xff;
4088
4089           DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4090           switch (lp1) {
4091           case 0:
4092             rFalseIfx.condition ^= 1;
4093             genSkipCond(&rFalseIfx,right,0,7);
4094             break;
4095           case 0x7f:
4096             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4097             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4098             genSkipz2(&rFalseIfx,1);
4099             break;
4100           default:
4101             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4102             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4103             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4104             rFalseIfx.condition ^= 1;
4105             genSkipc(&rFalseIfx);
4106             break;
4107           }
4108         } else {
4109           /* unsigned comparisons to a literal byte */
4110
4111           switch(lit & 0xff ) {
4112           case 0:
4113             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4114             genSkipz2(&rFalseIfx,0);
4115             break;
4116           case 0x7f:
4117             rFalseIfx.condition ^= 1;
4118             genSkipCond(&rFalseIfx,right,0,7);
4119             break;
4120
4121           default:
4122             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4123             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4124             DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4125             rFalseIfx.condition ^= 1;
4126             if (AOP_TYPE(result) == AOP_CRY)
4127               genSkipc(&rFalseIfx);
4128             else {
4129               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4130               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4131             }         
4132             break;
4133           }
4134         }
4135
4136         if(ifx) ifx->generated = 1;
4137         //goto check_carry;
4138         return;
4139
4140       } else {
4141
4142         /* Size is greater than 1 */
4143
4144         if(sign) {
4145           int lp1 = lit+1;
4146
4147           size--;
4148
4149           if(lp1 == 0) {
4150             /* this means lit = 0xffffffff, or -1 */
4151
4152
4153             DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4154             rFalseIfx.condition ^= 1;
4155             genSkipCond(&rFalseIfx,right,size,7);
4156             if(ifx) ifx->generated = 1;
4157             return;
4158           }
4159
4160           if(lit == 0) {
4161             int s = size;
4162
4163             if(rFalseIfx.condition) {
4164               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4165               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4166             }
4167
4168             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4169             while(size--)
4170               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4171
4172
4173             emitSKPZ;
4174             if(rFalseIfx.condition) {
4175               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4176               pic16_emitpLabel(truelbl->key);
4177             }else {
4178               rFalseIfx.condition ^= 1;
4179               genSkipCond(&rFalseIfx,right,s,7);
4180             }
4181
4182             if(ifx) ifx->generated = 1;
4183             return;
4184           }
4185
4186           if((size == 1) &&  (0 == (lp1&0xff))) {
4187             /* lower byte of signed word is zero */
4188             DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4189             i = ((lp1 >> 8) & 0xff) ^0x80;
4190             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4191             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4192             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4193             rFalseIfx.condition ^= 1;
4194             genSkipc(&rFalseIfx);
4195
4196
4197             if(ifx) ifx->generated = 1;
4198             return;
4199           }
4200
4201           if(lit & (0x80 << (size*8))) {
4202             /* Lit is less than zero */
4203             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4204             //rFalseIfx.condition ^= 1;
4205             //genSkipCond(&rFalseIfx,left,size,7);
4206             //rFalseIfx.condition ^= 1;
4207             pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4208             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4209
4210             if(rFalseIfx.condition)
4211               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4212             else
4213               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4214
4215
4216           } else {
4217             /* Lit is greater than or equal to zero */
4218             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4219             //rFalseIfx.condition ^= 1;
4220             //genSkipCond(&rFalseIfx,right,size,7);
4221             //rFalseIfx.condition ^= 1;
4222
4223             //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4224             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4225
4226             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4227             if(rFalseIfx.condition)
4228               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4229             else
4230               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4231
4232           }
4233
4234
4235           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4236           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4237
4238           while(size--) {
4239
4240             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4241             emitSKPNZ;
4242             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4243           }
4244           rFalseIfx.condition ^= 1;
4245           //rFalseIfx.condition = 1;
4246           genSkipc(&rFalseIfx);
4247
4248           pic16_emitpLabel(truelbl->key);
4249
4250           if(ifx) ifx->generated = 1;
4251           return;
4252           // end of if (sign)
4253         } else {
4254
4255           /* compare word or long to an unsigned literal on the right.*/
4256
4257
4258           size--;
4259           if(lit < 0xff) {
4260             DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4261             switch (lit) {
4262             case 0:
4263               break; /* handled above */
4264 /*
4265             case 0xff:
4266               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4267               while(size--)
4268                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4269               genSkipz2(&rFalseIfx,0);
4270               break;
4271 */
4272             default:
4273               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4274               while(--size)
4275                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4276
4277               emitSKPZ;
4278               if(rFalseIfx.condition)
4279                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4280               else
4281                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4282
4283
4284               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4285               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4286
4287               rFalseIfx.condition ^= 1;
4288               genSkipc(&rFalseIfx);
4289             }
4290
4291             pic16_emitpLabel(truelbl->key);
4292
4293             if(ifx) ifx->generated = 1;
4294             return;
4295           }
4296
4297
4298           lit++;
4299           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4300           i = (lit >> (size*8)) & 0xff;
4301
4302           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4303           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4304
4305           while(size--) {
4306             i = (lit >> (size*8)) & 0xff;
4307
4308             if(i) {
4309               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4310               emitSKPNZ;
4311               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4312             } else {
4313               /* this byte of the lit is zero, 
4314                *if it's not the last then OR in the variable */
4315               if(size)
4316                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4317             }
4318           }
4319
4320
4321           pic16_emitpLabel(lbl->key);
4322
4323           rFalseIfx.condition ^= 1;
4324           genSkipc(&rFalseIfx);
4325         }
4326
4327         if(sign)
4328           pic16_emitpLabel(truelbl->key);
4329         if(ifx) ifx->generated = 1;
4330         return;
4331       }
4332     }
4333     /* Compare two variables */
4334
4335     DEBUGpic16_emitcode(";sign","%d",sign);
4336
4337     size--;
4338     if(sign) {
4339       /* Sigh. thus sucks... */
4340       if(size) {
4341         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4342         pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4343         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4344         pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4345         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4346         pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4347       } else {
4348         /* Signed char comparison */
4349         /* Special thanks to Nikolai Golovchenko for this snippet */
4350         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4351         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4352         pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
4353         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4354         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4355         pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4356
4357         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4358         genSkipc(&rFalseIfx);
4359           
4360         if(ifx) ifx->generated = 1;
4361         return;
4362       }
4363
4364     } else {
4365
4366       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4367       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4368     }
4369
4370
4371     /* The rest of the bytes of a multi-byte compare */
4372     while (size) {
4373
4374       emitSKPZ;
4375       pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
4376       size--;
4377
4378       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4379       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4380
4381
4382     }
4383
4384     pic16_emitpLabel(lbl->key);
4385
4386     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4387     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4388         (AOP_TYPE(result) == AOP_REG)) {
4389       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4390       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4391     } else {
4392       genSkipc(&rFalseIfx);
4393     }         
4394     //genSkipc(&rFalseIfx);
4395     if(ifx) ifx->generated = 1;
4396
4397     return;
4398
4399   }
4400
4401   // check_carry:
4402   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4403     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4404     pic16_outBitC(result);
4405   } else {
4406     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4407     /* if the result is used in the next
4408        ifx conditional branch then generate
4409        code a little differently */
4410     if (ifx )
4411       genIfxJump (ifx,"c");
4412     else
4413       pic16_outBitC(result);
4414     /* leave the result in acc */
4415   }
4416
4417 }
4418
4419 /*-----------------------------------------------------------------*/
4420 /* genCmpGt :- greater than comparison                             */
4421 /*-----------------------------------------------------------------*/
4422 static void genCmpGt (iCode *ic, iCode *ifx)
4423 {
4424     operand *left, *right, *result;
4425     sym_link *letype , *retype;
4426     int sign ;
4427
4428     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4429     left = IC_LEFT(ic);
4430     right= IC_RIGHT(ic);
4431     result = IC_RESULT(ic);
4432
4433     letype = getSpec(operandType(left));
4434     retype =getSpec(operandType(right));
4435     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4436     /* assign the amsops */
4437     pic16_aopOp (left,ic,FALSE);
4438     pic16_aopOp (right,ic,FALSE);
4439     pic16_aopOp (result,ic,TRUE);
4440
4441     genCmp(right, left, result, ifx, sign);
4442
4443     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4444     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4445     pic16_freeAsmop(result,NULL,ic,TRUE); 
4446 }
4447
4448 /*-----------------------------------------------------------------*/
4449 /* genCmpLt - less than comparisons                                */
4450 /*-----------------------------------------------------------------*/
4451 static void genCmpLt (iCode *ic, iCode *ifx)
4452 {
4453     operand *left, *right, *result;
4454     sym_link *letype , *retype;
4455     int sign ;
4456
4457     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4458     left = IC_LEFT(ic);
4459     right= IC_RIGHT(ic);
4460     result = IC_RESULT(ic);
4461
4462     letype = getSpec(operandType(left));
4463     retype =getSpec(operandType(right));
4464     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4465
4466     /* assign the amsops */
4467     pic16_aopOp (left,ic,FALSE);
4468     pic16_aopOp (right,ic,FALSE);
4469     pic16_aopOp (result,ic,TRUE);
4470
4471     genCmp(left, right, result, ifx, sign);
4472
4473     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4474     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4475     pic16_freeAsmop(result,NULL,ic,TRUE); 
4476 }
4477
4478 /*-----------------------------------------------------------------*/
4479 /* genc16bit2lit - compare a 16 bit value to a literal             */
4480 /*-----------------------------------------------------------------*/
4481 static void genc16bit2lit(operand *op, int lit, int offset)
4482 {
4483   int i;
4484
4485   DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4486   if( (lit&0xff) == 0) 
4487     i=1;
4488   else
4489     i=0;
4490
4491   switch( BYTEofLONG(lit,i)) { 
4492   case 0:
4493     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4494     break;
4495   case 1:
4496     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4497     break;
4498   case 0xff:
4499     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4500     break;
4501   default:
4502     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4503     pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4504   }
4505
4506   i ^= 1;
4507
4508   switch( BYTEofLONG(lit,i)) { 
4509   case 0:
4510     pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4511     break;
4512   case 1:
4513     emitSKPNZ;
4514     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4515     break;
4516   case 0xff:
4517     emitSKPNZ;
4518     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4519     break;
4520   default:
4521     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4522     emitSKPNZ;
4523     pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4524
4525   }
4526
4527 }
4528
4529 /*-----------------------------------------------------------------*/
4530 /* gencjneshort - compare and jump if not equal                    */
4531 /*-----------------------------------------------------------------*/
4532 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4533 {
4534   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4535   int offset = 0;
4536   int res_offset = 0;  /* the result may be a different size then left or right */
4537   int res_size = AOP_SIZE(result);
4538   resolvedIfx rIfx;
4539   symbol *lbl;
4540
4541   unsigned long lit = 0L;
4542   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4543   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4544   if(result)
4545     DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4546   resolveIfx(&rIfx,ifx);
4547   lbl =  newiTempLabel(NULL);
4548
4549
4550   /* if the left side is a literal or 
4551      if the right is in a pointer register and left 
4552      is not */
4553   if ((AOP_TYPE(left) == AOP_LIT) || 
4554       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4555     operand *t = right;
4556     right = left;
4557     left = t;
4558   }
4559   if(AOP_TYPE(right) == AOP_LIT)
4560     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4561
4562   /* if the right side is a literal then anything goes */
4563   if (AOP_TYPE(right) == AOP_LIT &&
4564       AOP_TYPE(left) != AOP_DIR ) {
4565     switch(size) {
4566     case 2:
4567       genc16bit2lit(left, lit, 0);
4568       emitSKPNZ;
4569       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4570       break;
4571     default:
4572       while (size--) {
4573         if(lit & 0xff) {
4574           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4575           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4576         } else {
4577           pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4578         }
4579
4580         emitSKPNZ;
4581         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4582         offset++;
4583         if(res_offset < res_size-1)
4584           res_offset++;
4585         lit >>= 8;
4586       }
4587       break;
4588     }
4589   }
4590
4591   /* if the right side is in a register or in direct space or
4592      if the left is a pointer register & right is not */    
4593   else if (AOP_TYPE(right) == AOP_REG ||
4594            AOP_TYPE(right) == AOP_DIR || 
4595            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4596            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4597     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4598     int lbl_key = lbl->key;
4599
4600     if(result) {
4601       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4602       //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4603     }else {
4604       DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4605       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4606               __FUNCTION__,__LINE__);
4607       return;
4608     }
4609
4610 /*     switch(size) { */
4611 /*     case 2: */
4612 /*       genc16bit2lit(left, lit, 0); */
4613 /*       emitSKPNZ; */
4614 /*       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4615 /*       break; */
4616 /*     default: */
4617     while (size--) {
4618       int emit_skip=1;
4619       if((AOP_TYPE(left) == AOP_DIR) && 
4620          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4621
4622         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4623         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4624
4625       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4626             
4627         switch (lit & 0xff) {
4628         case 0:
4629           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4630           break;
4631         case 1:
4632           pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4633           pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4634           //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4635           emit_skip=0;
4636           break;
4637         case 0xff:
4638           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4639           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4640           //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4641           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4642           emit_skip=0;
4643           break;
4644         default:
4645           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4646           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4647         }
4648         lit >>= 8;
4649
4650       } else {
4651         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4652       }
4653       if(emit_skip) {
4654         if(AOP_TYPE(result) == AOP_CRY) {
4655           pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4656           if(rIfx.condition)
4657             emitSKPNZ;
4658           else
4659             emitSKPZ;
4660           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4661         } else {
4662           /* fix me. probably need to check result size too */
4663           //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4664           if(rIfx.condition)
4665             emitSKPZ;
4666           else
4667             emitSKPNZ;
4668           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4669           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4670         }
4671         if(ifx)
4672           ifx->generated=1;
4673       }
4674       emit_skip++;
4675       offset++;
4676       if(res_offset < res_size-1)
4677         res_offset++;
4678     }
4679 /*       break; */
4680 /*     } */
4681   } else if(AOP_TYPE(right) == AOP_REG &&
4682             AOP_TYPE(left) != AOP_DIR){
4683
4684     while(size--) {
4685       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4686       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4687       pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4688       if(rIfx.condition)
4689         emitSKPNZ;
4690       else
4691         emitSKPZ;
4692       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4693       offset++;
4694       if(res_offset < res_size-1)
4695         res_offset++;
4696     }
4697       
4698   }else{
4699     /* right is a pointer reg need both a & b */
4700     while(size--) {
4701       char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4702       if(strcmp(l,"b"))
4703         pic16_emitcode("mov","b,%s",l);
4704       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4705       pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4706       offset++;
4707     }
4708   }
4709
4710   pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4711   if(!rIfx.condition)
4712     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4713
4714   pic16_emitpLabel(lbl->key);
4715
4716   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4717
4718   if(ifx)
4719     ifx->generated = 1;
4720 }
4721
4722 #if 0
4723 /*-----------------------------------------------------------------*/
4724 /* gencjne - compare and jump if not equal                         */
4725 /*-----------------------------------------------------------------*/
4726 static void gencjne(operand *left, operand *right, iCode *ifx)
4727 {
4728     symbol *tlbl  = newiTempLabel(NULL);
4729
4730     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4731     gencjneshort(left, right, lbl);
4732
4733     pic16_emitcode("mov","a,%s",one);
4734     pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4735     pic16_emitcode("","%05d_DS_:",lbl->key+100);
4736     pic16_emitcode("clr","a");
4737     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4738
4739     pic16_emitpLabel(lbl->key);
4740     pic16_emitpLabel(tlbl->key);
4741
4742 }
4743 #endif
4744
4745 /*-----------------------------------------------------------------*/
4746 /* genCmpEq - generates code for equal to                          */
4747 /*-----------------------------------------------------------------*/
4748 static void genCmpEq (iCode *ic, iCode *ifx)
4749 {
4750     operand *left, *right, *result;
4751     unsigned long lit = 0L;
4752     int size,offset=0;
4753
4754     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4755
4756     if(ifx)
4757       DEBUGpic16_emitcode ("; ifx is non-null","");
4758     else
4759       DEBUGpic16_emitcode ("; ifx is null","");
4760
4761     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4762     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4763     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4764
4765     size = max(AOP_SIZE(left),AOP_SIZE(right));
4766
4767     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4768
4769     /* if literal, literal on the right or 
4770     if the right is in a pointer register and left 
4771     is not */
4772     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4773         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4774       operand *tmp = right ;
4775       right = left;
4776       left = tmp;
4777     }
4778
4779
4780     if(ifx && !AOP_SIZE(result)){
4781         symbol *tlbl;
4782         /* if they are both bit variables */
4783         if (AOP_TYPE(left) == AOP_CRY &&
4784             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4785             if(AOP_TYPE(right) == AOP_LIT){
4786                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4787                 if(lit == 0L){
4788                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789                     pic16_emitcode("cpl","c");
4790                 } else if(lit == 1L) {
4791                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4792                 } else {
4793                     pic16_emitcode("clr","c");
4794                 }
4795                 /* AOP_TYPE(right) == AOP_CRY */
4796             } else {
4797                 symbol *lbl = newiTempLabel(NULL);
4798                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4799                 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4800                 pic16_emitcode("cpl","c");
4801                 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4802             }
4803             /* if true label then we jump if condition
4804             supplied is true */
4805             tlbl = newiTempLabel(NULL);
4806             if ( IC_TRUE(ifx) ) {
4807                 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4808                 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4809             } else {
4810                 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4811                 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4812             }
4813             pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4814
4815             {
4816               /* left and right are both bit variables, result is carry */
4817               resolvedIfx rIfx;
4818               
4819               resolveIfx(&rIfx,ifx);
4820
4821               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4822               pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4823               pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4824               pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4825               genSkipz2(&rIfx,0);
4826             }
4827         } else {
4828
4829           /* They're not both bit variables. Is the right a literal? */
4830           if(AOP_TYPE(right) == AOP_LIT) {
4831             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4832             
4833             switch(size) {
4834
4835             case 1:
4836               switch(lit & 0xff) {
4837               case 1:
4838                 if ( IC_TRUE(ifx) ) {
4839                   pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4840                   emitSKPNZ;
4841                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4842                 } else {
4843                   pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4844                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4845                 }
4846                 break;
4847               case 0xff:
4848                 if ( IC_TRUE(ifx) ) {
4849                   pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4850                   emitSKPNZ;
4851                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4852                 } else {
4853                   pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4854                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4855                 }
4856                 break;
4857               default:
4858                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4859                 if(lit)
4860                   pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4861                 genSkip(ifx,'z');
4862               }
4863
4864
4865               /* end of size == 1 */
4866               break;
4867               
4868             case 2:
4869               genc16bit2lit(left,lit,offset);
4870               genSkip(ifx,'z');
4871               break;
4872               /* end of size == 2 */
4873
4874             default:
4875               /* size is 4 */
4876               if(lit==0) {
4877                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4878                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4879                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4880                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4881
4882               } else {
4883
4884                 /* search for patterns that can be optimized */
4885
4886                 genc16bit2lit(left,lit,0);
4887                 lit >>= 16;
4888                 if(lit) {
4889                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4890                   //genSkip(ifx,'z');
4891                   genc16bit2lit(left,lit,2);
4892                 } else {
4893                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4894                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4895
4896                 }
4897                 
4898               }
4899
4900               genSkip(ifx,'z');
4901             }
4902           
4903             ifx->generated = 1;
4904             goto release ;
4905             
4906
4907           } else if(AOP_TYPE(right) == AOP_CRY ) {
4908             /* we know the left is not a bit, but that the right is */
4909             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4910             pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4911                       pic16_popGet(AOP(right),offset));
4912             pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4913
4914             /* if the two are equal, then W will be 0 and the Z bit is set
4915              * we could test Z now, or go ahead and check the high order bytes if
4916              * the variable we're comparing is larger than a byte. */
4917
4918             while(--size)
4919               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4920
4921             if ( IC_TRUE(ifx) ) {
4922               emitSKPNZ;
4923               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4924               pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4925             } else {
4926               emitSKPZ;
4927               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4928               pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4929             }
4930
4931           } else {
4932             /* They're both variables that are larger than bits */
4933             int s = size;
4934
4935             tlbl = newiTempLabel(NULL);
4936
4937             while(size--) {
4938               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4939               pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4940
4941               if ( IC_TRUE(ifx) ) {
4942                 if(size) {
4943                   emitSKPZ;
4944                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4945                   pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4946                 } else {
4947                   emitSKPNZ;
4948                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4949                   pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4950                 }
4951               } else {
4952                 emitSKPZ;
4953                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4954                 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4955               }
4956               offset++;
4957             }
4958             if(s>1 && IC_TRUE(ifx)) {
4959               pic16_emitpLabel(tlbl->key);
4960               pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4961             }
4962           }
4963         }
4964         /* mark the icode as generated */
4965         ifx->generated = 1;
4966         goto release ;
4967     }
4968
4969     /* if they are both bit variables */
4970     if (AOP_TYPE(left) == AOP_CRY &&
4971         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4972         if(AOP_TYPE(right) == AOP_LIT){
4973             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4974             if(lit == 0L){
4975                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976                 pic16_emitcode("cpl","c");
4977             } else if(lit == 1L) {
4978                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4979             } else {
4980                 pic16_emitcode("clr","c");
4981             }
4982             /* AOP_TYPE(right) == AOP_CRY */
4983         } else {
4984             symbol *lbl = newiTempLabel(NULL);
4985             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4986             pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4987             pic16_emitcode("cpl","c");
4988             pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4989         }
4990         /* c = 1 if egal */
4991         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4992             pic16_outBitC(result);
4993             goto release ;
4994         }
4995         if (ifx) {
4996             genIfxJump (ifx,"c");
4997             goto release ;
4998         }
4999         /* if the result is used in an arithmetic operation
5000         then put the result in place */
5001         pic16_outBitC(result);
5002     } else {
5003       
5004       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5005       gencjne(left,right,result,ifx);
5006 /*
5007       if(ifx) 
5008         gencjne(left,right,newiTempLabel(NULL));
5009       else {
5010         if(IC_TRUE(ifx)->key)
5011           gencjne(left,right,IC_TRUE(ifx)->key);
5012         else
5013           gencjne(left,right,IC_FALSE(ifx)->key);
5014         ifx->generated = 1;
5015         goto release ;
5016       }
5017       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5018         pic16_aopPut(AOP(result),"a",0);
5019         goto release ;
5020       }
5021
5022       if (ifx) {
5023         genIfxJump (ifx,"a");
5024         goto release ;
5025       }
5026 */
5027       /* if the result is used in an arithmetic operation
5028          then put the result in place */
5029 /*
5030       if (AOP_TYPE(result) != AOP_CRY) 
5031         pic16_outAcc(result);
5032 */
5033       /* leave the result in acc */
5034     }
5035
5036 release:
5037     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5038     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5039     pic16_freeAsmop(result,NULL,ic,TRUE);
5040 }
5041
5042 /*-----------------------------------------------------------------*/
5043 /* ifxForOp - returns the icode containing the ifx for operand     */
5044 /*-----------------------------------------------------------------*/
5045 static iCode *ifxForOp ( operand *op, iCode *ic )
5046 {
5047     /* if true symbol then needs to be assigned */
5048     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5049     if (IS_TRUE_SYMOP(op))
5050         return NULL ;
5051
5052     /* if this has register type condition and
5053     the next instruction is ifx with the same operand
5054     and live to of the operand is upto the ifx only then */
5055     if (ic->next &&
5056         ic->next->op == IFX &&
5057         IC_COND(ic->next)->key == op->key &&
5058         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5059         return ic->next;
5060
5061     if (ic->next &&
5062         ic->next->op == IFX &&
5063         IC_COND(ic->next)->key == op->key) {
5064       DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5065       return ic->next;
5066     }
5067
5068     DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5069     if (ic->next &&
5070         ic->next->op == IFX)
5071       DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5072
5073     if (ic->next &&
5074         ic->next->op == IFX &&
5075         IC_COND(ic->next)->key == op->key) {
5076       DEBUGpic16_emitcode ("; "," key is okay");
5077       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5078                            OP_SYMBOL(op)->liveTo,
5079                            ic->next->seq);
5080     }
5081
5082
5083     return NULL;
5084 }
5085 /*-----------------------------------------------------------------*/
5086 /* genAndOp - for && operation                                     */
5087 /*-----------------------------------------------------------------*/
5088 static void genAndOp (iCode *ic)
5089 {
5090     operand *left,*right, *result;
5091 /*     symbol *tlbl; */
5092
5093     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5094     /* note here that && operations that are in an
5095     if statement are taken away by backPatchLabels
5096     only those used in arthmetic operations remain */
5097     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5098     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5099     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5100
5101     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5102
5103     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5104     pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5105     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5106
5107     /* if both are bit variables */
5108 /*     if (AOP_TYPE(left) == AOP_CRY && */
5109 /*         AOP_TYPE(right) == AOP_CRY ) { */
5110 /*         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5111 /*         pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5112 /*         pic16_outBitC(result); */
5113 /*     } else { */
5114 /*         tlbl = newiTempLabel(NULL); */
5115 /*         pic16_toBoolean(left);     */
5116 /*         pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5117 /*         pic16_toBoolean(right); */
5118 /*         pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5119 /*         pic16_outBitAcc(result); */
5120 /*     } */
5121
5122     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5123     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5124     pic16_freeAsmop(result,NULL,ic,TRUE);
5125 }
5126
5127
5128 /*-----------------------------------------------------------------*/
5129 /* genOrOp - for || operation                                      */
5130 /*-----------------------------------------------------------------*/
5131 /*
5132   tsd pic port -
5133   modified this code, but it doesn't appear to ever get called
5134 */
5135
5136 static void genOrOp (iCode *ic)
5137 {
5138     operand *left,*right, *result;
5139     symbol *tlbl;
5140
5141     /* note here that || operations that are in an
5142     if statement are taken away by backPatchLabels
5143     only those used in arthmetic operations remain */
5144     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5145     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5146     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5147     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5148
5149     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5150
5151     /* if both are bit variables */
5152     if (AOP_TYPE(left) == AOP_CRY &&
5153         AOP_TYPE(right) == AOP_CRY ) {
5154       pic16_emitcode("clrc","");
5155       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5156                AOP(left)->aopu.aop_dir,
5157                AOP(left)->aopu.aop_dir);
5158       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5159                AOP(right)->aopu.aop_dir,
5160                AOP(right)->aopu.aop_dir);
5161       pic16_emitcode("setc","");
5162
5163     } else {
5164         tlbl = newiTempLabel(NULL);
5165         pic16_toBoolean(left);
5166         emitSKPZ;
5167         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5168         pic16_toBoolean(right);
5169         pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5170
5171         pic16_outBitAcc(result);
5172     }
5173
5174     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5175     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5176     pic16_freeAsmop(result,NULL,ic,TRUE);            
5177 }
5178
5179 /*-----------------------------------------------------------------*/
5180 /* isLiteralBit - test if lit == 2^n                               */
5181 /*-----------------------------------------------------------------*/
5182 static int isLiteralBit(unsigned long lit)
5183 {
5184     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5185     0x100L,0x200L,0x400L,0x800L,
5186     0x1000L,0x2000L,0x4000L,0x8000L,
5187     0x10000L,0x20000L,0x40000L,0x80000L,
5188     0x100000L,0x200000L,0x400000L,0x800000L,
5189     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5190     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5191     int idx;
5192     
5193     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5194     for(idx = 0; idx < 32; idx++)
5195         if(lit == pw[idx])
5196             return idx+1;
5197     return 0;
5198 }
5199
5200 /*-----------------------------------------------------------------*/
5201 /* continueIfTrue -                                                */
5202 /*-----------------------------------------------------------------*/
5203 static void continueIfTrue (iCode *ic)
5204 {
5205     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5206     if(IC_TRUE(ic))
5207         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5208     ic->generated = 1;
5209 }
5210
5211 /*-----------------------------------------------------------------*/
5212 /* jmpIfTrue -                                                     */
5213 /*-----------------------------------------------------------------*/
5214 static void jumpIfTrue (iCode *ic)
5215 {
5216     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5217     if(!IC_TRUE(ic))
5218         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5219     ic->generated = 1;
5220 }
5221
5222 /*-----------------------------------------------------------------*/
5223 /* jmpTrueOrFalse -                                                */
5224 /*-----------------------------------------------------------------*/
5225 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5226 {
5227     // ugly but optimized by peephole
5228     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5229     if(IC_TRUE(ic)){
5230         symbol *nlbl = newiTempLabel(NULL);
5231         pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5232         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5233         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5234         pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5235     }
5236     else{
5237         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5238         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5239     }
5240     ic->generated = 1;
5241 }
5242
5243 /*-----------------------------------------------------------------*/
5244 /* genAnd  - code for and                                          */
5245 /*-----------------------------------------------------------------*/
5246 static void genAnd (iCode *ic, iCode *ifx)
5247 {
5248   operand *left, *right, *result;
5249   int size, offset=0;  
5250   unsigned long lit = 0L;
5251   int bytelit = 0;
5252   resolvedIfx rIfx;
5253
5254
5255   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5256   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5257   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5258   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5259
5260   resolveIfx(&rIfx,ifx);
5261
5262   /* if left is a literal & right is not then exchange them */
5263   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5264       AOP_NEEDSACC(left)) {
5265     operand *tmp = right ;
5266     right = left;
5267     left = tmp;
5268   }
5269
5270   /* if result = right then exchange them */
5271   if(pic16_sameRegs(AOP(result),AOP(right))){
5272     operand *tmp = right ;
5273     right = left;
5274     left = tmp;
5275   }
5276
5277   /* if right is bit then exchange them */
5278   if (AOP_TYPE(right) == AOP_CRY &&
5279       AOP_TYPE(left) != AOP_CRY){
5280     operand *tmp = right ;
5281     right = left;
5282     left = tmp;
5283   }
5284   if(AOP_TYPE(right) == AOP_LIT)
5285     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5286
5287   size = AOP_SIZE(result);
5288
5289   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5290
5291   // if(bit & yy)
5292   // result = bit & yy;
5293   if (AOP_TYPE(left) == AOP_CRY){
5294     // c = bit & literal;
5295     if(AOP_TYPE(right) == AOP_LIT){
5296       if(lit & 1) {
5297         if(size && pic16_sameRegs(AOP(result),AOP(left)))
5298           // no change
5299           goto release;
5300         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5301       } else {
5302         // bit(result) = 0;
5303         if(size && (AOP_TYPE(result) == AOP_CRY)){
5304           pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5305           goto release;
5306         }
5307         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5308           jumpIfTrue(ifx);
5309           goto release;
5310         }
5311         pic16_emitcode("clr","c");
5312       }
5313     } else {
5314       if (AOP_TYPE(right) == AOP_CRY){
5315         // c = bit & bit;
5316         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5317         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5318       } else {
5319         // c = bit & val;
5320         MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5321         // c = lsb
5322         pic16_emitcode("rrc","a");
5323         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5324       }
5325     }
5326     // bit = c
5327     // val = c
5328     if(size)
5329       pic16_outBitC(result);
5330     // if(bit & ...)
5331     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5332       genIfxJump(ifx, "c");           
5333     goto release ;
5334   }
5335
5336   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5337   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5338   if((AOP_TYPE(right) == AOP_LIT) &&
5339      (AOP_TYPE(result) == AOP_CRY) &&
5340      (AOP_TYPE(left) != AOP_CRY)){
5341     int posbit = isLiteralBit(lit);
5342     /* left &  2^n */
5343     if(posbit){
5344       posbit--;
5345       //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5346       // bit = left & 2^n
5347       if(size)
5348         pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5349       // if(left &  2^n)
5350       else{
5351         if(ifx){
5352 /*
5353           if(IC_TRUE(ifx)) {
5354             pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5355             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5356           } else {
5357             pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5358             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5359           }
5360 */
5361           pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5362                     pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5363           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5364           
5365           ifx->generated = 1;
5366         }
5367         goto release;
5368       }
5369     } else {
5370       symbol *tlbl = newiTempLabel(NULL);
5371       int sizel = AOP_SIZE(left);
5372       if(size)
5373         pic16_emitcode("setb","c");
5374       while(sizel--){
5375         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5376           MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5377           // byte ==  2^n ?
5378           if((posbit = isLiteralBit(bytelit)) != 0)
5379             pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5380           else{
5381             if(bytelit != 0x0FFL)
5382               pic16_emitcode("anl","a,%s",
5383                              pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5384             pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5385           }
5386         }
5387         offset++;
5388       }
5389       // bit = left & literal
5390       if(size){
5391         pic16_emitcode("clr","c");
5392         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5393       }
5394       // if(left & literal)
5395       else{
5396         if(ifx)
5397           jmpTrueOrFalse(ifx, tlbl);
5398         goto release ;
5399       }
5400     }
5401     pic16_outBitC(result);
5402     goto release ;
5403   }
5404
5405   /* if left is same as result */
5406   if(pic16_sameRegs(AOP(result),AOP(left))){
5407     int know_W = -1;
5408     for(;size--; offset++,lit>>=8) {
5409       if(AOP_TYPE(right) == AOP_LIT){
5410         switch(lit & 0xff) {
5411         case 0x00:
5412           /*  and'ing with 0 has clears the result */
5413           pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5414           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5415           break;
5416         case 0xff:
5417           /* and'ing with 0xff is a nop when the result and left are the same */
5418           break;
5419
5420         default:
5421           {
5422             int p = my_powof2( (~lit) & 0xff );
5423             if(p>=0) {
5424               /* only one bit is set in the literal, so use a bcf instruction */
5425               pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5426               pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5427
5428             } else {
5429               pic16_emitcode("movlw","0x%x", (lit & 0xff));
5430               pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5431               if(know_W != (lit&0xff))
5432                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5433               know_W = lit &0xff;
5434               pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5435             }
5436           }    
5437         }
5438       } else {
5439         if (AOP_TYPE(left) == AOP_ACC) {
5440           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5441         } else {                    
5442           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5443           pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5444
5445         }
5446       }
5447     }
5448
5449   } else {
5450     // left & result in different registers
5451     if(AOP_TYPE(result) == AOP_CRY){
5452       // result = bit
5453       // if(size), result in bit
5454       // if(!size && ifx), conditional oper: if(left & right)
5455       symbol *tlbl = newiTempLabel(NULL);
5456       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5457       if(size)
5458         pic16_emitcode("setb","c");
5459       while(sizer--){
5460         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5461         pic16_emitcode("anl","a,%s",
5462                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5463         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5464         offset++;
5465       }
5466       if(size){
5467         CLRC;
5468         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5469         pic16_outBitC(result);
5470       } else if(ifx)
5471         jmpTrueOrFalse(ifx, tlbl);
5472     } else {
5473       for(;(size--);offset++) {
5474         // normal case
5475         // result = left & right
5476         if(AOP_TYPE(right) == AOP_LIT){
5477           int t = (lit >> (offset*8)) & 0x0FFL;
5478           switch(t) { 
5479           case 0x00:
5480             pic16_emitcode("clrf","%s",
5481                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5482             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5483             break;
5484           case 0xff:
5485             pic16_emitcode("movf","%s,w",
5486                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5487             pic16_emitcode("movwf","%s",
5488                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5489             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5490             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5491             break;
5492           default:
5493             pic16_emitcode("movlw","0x%x",t);
5494             pic16_emitcode("andwf","%s,w",
5495                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5496             pic16_emitcode("movwf","%s",
5497                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5498               
5499             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5500             pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5501             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5502           }
5503           continue;
5504         }
5505
5506         if (AOP_TYPE(left) == AOP_ACC) {
5507           pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5508           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5509         } else {
5510           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5511           pic16_emitcode("andwf","%s,w",
5512                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5513           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5514           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5515         }
5516         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5517         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5518       }
5519     }
5520   }
5521
5522   release :
5523     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5524   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5525   pic16_freeAsmop(result,NULL,ic,TRUE);     
5526 }
5527
5528 /*-----------------------------------------------------------------*/
5529 /* genOr  - code for or                                            */
5530 /*-----------------------------------------------------------------*/
5531 static void genOr (iCode *ic, iCode *ifx)
5532 {
5533     operand *left, *right, *result;
5534     int size, offset=0;
5535     unsigned long lit = 0L;
5536
5537     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5538
5539     pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5540     pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5541     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5542
5543     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5544
5545     /* if left is a literal & right is not then exchange them */
5546     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5547         AOP_NEEDSACC(left)) {
5548         operand *tmp = right ;
5549         right = left;
5550         left = tmp;
5551     }
5552
5553     /* if result = right then exchange them */
5554     if(pic16_sameRegs(AOP(result),AOP(right))){
5555         operand *tmp = right ;
5556         right = left;
5557         left = tmp;
5558     }
5559
5560     /* if right is bit then exchange them */
5561     if (AOP_TYPE(right) == AOP_CRY &&
5562         AOP_TYPE(left) != AOP_CRY){
5563         operand *tmp = right ;
5564         right = left;
5565         left = tmp;
5566     }
5567
5568     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5569
5570     if(AOP_TYPE(right) == AOP_LIT)
5571         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5572
5573     size = AOP_SIZE(result);
5574
5575     // if(bit | yy)
5576     // xx = bit | yy;
5577     if (AOP_TYPE(left) == AOP_CRY){
5578         if(AOP_TYPE(right) == AOP_LIT){
5579             // c = bit & literal;
5580             if(lit){
5581                 // lit != 0 => result = 1
5582                 if(AOP_TYPE(result) == AOP_CRY){
5583                   if(size)
5584                     pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5585                   //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5586                   //     AOP(result)->aopu.aop_dir,
5587                   //     AOP(result)->aopu.aop_dir);
5588                     else if(ifx)
5589                         continueIfTrue(ifx);
5590                     goto release;
5591                 }
5592             } else {
5593                 // lit == 0 => result = left
5594                 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5595                     goto release;
5596                 pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5597             }
5598         } else {
5599             if (AOP_TYPE(right) == AOP_CRY){
5600               if(pic16_sameRegs(AOP(result),AOP(left))){
5601                 // c = bit | bit;
5602                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5603                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5604                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5605
5606                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5607                          AOP(result)->aopu.aop_dir,
5608                          AOP(result)->aopu.aop_dir);
5609                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5610                          AOP(right)->aopu.aop_dir,
5611                          AOP(right)->aopu.aop_dir);
5612                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5613                          AOP(result)->aopu.aop_dir,
5614                          AOP(result)->aopu.aop_dir);
5615               } else {
5616                 if( AOP_TYPE(result) == AOP_ACC) {
5617                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5618                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5619                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5620                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5621
5622                 } else {
5623
5624                   pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5625                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5626                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5627                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5628
5629                   pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5630                                  AOP(result)->aopu.aop_dir,
5631                                  AOP(result)->aopu.aop_dir);
5632                   pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5633                                  AOP(right)->aopu.aop_dir,
5634                                  AOP(right)->aopu.aop_dir);
5635                   pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5636                                  AOP(left)->aopu.aop_dir,
5637                                  AOP(left)->aopu.aop_dir);
5638                   pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5639                                  AOP(result)->aopu.aop_dir,
5640                                  AOP(result)->aopu.aop_dir);
5641                 }
5642               }
5643             } else {
5644                 // c = bit | val;
5645                 symbol *tlbl = newiTempLabel(NULL);
5646                 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5647
5648
5649                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5650                 if( AOP_TYPE(right) == AOP_ACC) {
5651                   pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5652                   emitSKPNZ;
5653                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5654                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5655                 }
5656
5657
5658
5659                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5660                     pic16_emitcode(";XXX setb","c");
5661                 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5662                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5663                 pic16_toBoolean(right);
5664                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5665                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5666                     jmpTrueOrFalse(ifx, tlbl);
5667                     goto release;
5668                 } else {
5669                     CLRC;
5670                     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5671                 }
5672             }
5673         }
5674         // bit = c
5675         // val = c
5676         if(size)
5677             pic16_outBitC(result);
5678         // if(bit | ...)
5679         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5680             genIfxJump(ifx, "c");           
5681         goto release ;
5682     }
5683
5684     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5685     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5686     if((AOP_TYPE(right) == AOP_LIT) &&
5687        (AOP_TYPE(result) == AOP_CRY) &&
5688        (AOP_TYPE(left) != AOP_CRY)){
5689         if(lit){
5690           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5691             // result = 1
5692             if(size)
5693                 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5694             else 
5695                 continueIfTrue(ifx);
5696             goto release;
5697         } else {
5698           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5699             // lit = 0, result = boolean(left)
5700             if(size)
5701                 pic16_emitcode(";XXX setb","c");
5702             pic16_toBoolean(right);
5703             if(size){
5704                 symbol *tlbl = newiTempLabel(NULL);
5705                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5706                 CLRC;
5707                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5708             } else {
5709                 genIfxJump (ifx,"a");
5710                 goto release;
5711             }
5712         }
5713         pic16_outBitC(result);
5714         goto release ;
5715     }
5716
5717     /* if left is same as result */
5718     if(pic16_sameRegs(AOP(result),AOP(left))){
5719       int know_W = -1;
5720       for(;size--; offset++,lit>>=8) {
5721         if(AOP_TYPE(right) == AOP_LIT){
5722           if((lit & 0xff) == 0)
5723             /*  or'ing with 0 has no effect */
5724             continue;
5725           else {
5726             int p = my_powof2(lit & 0xff);
5727             if(p>=0) {
5728               /* only one bit is set in the literal, so use a bsf instruction */
5729               pic16_emitpcode(POC_BSF,
5730                         pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5731             } else {
5732               if(know_W != (lit & 0xff))
5733                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5734               know_W = lit & 0xff;
5735               pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5736             }
5737                     
5738           }
5739         } else {
5740           if (AOP_TYPE(left) == AOP_ACC) {
5741             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
5742             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5743           } else {                  
5744             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5745             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
5746
5747             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5748             pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5749
5750           }
5751         }
5752       }
5753     } else {
5754         // left & result in different registers
5755         if(AOP_TYPE(result) == AOP_CRY){
5756             // result = bit
5757             // if(size), result in bit
5758             // if(!size && ifx), conditional oper: if(left | right)
5759             symbol *tlbl = newiTempLabel(NULL);
5760             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5761             pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5762
5763
5764             if(size)
5765                 pic16_emitcode(";XXX setb","c");
5766             while(sizer--){
5767                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5768                 pic16_emitcode(";XXX orl","a,%s",
5769                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5770                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5771                 offset++;
5772             }
5773             if(size){
5774                 CLRC;
5775                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5776                 pic16_outBitC(result);
5777             } else if(ifx)
5778                 jmpTrueOrFalse(ifx, tlbl);
5779         } else for(;(size--);offset++){
5780           // normal case
5781           // result = left & right
5782           if(AOP_TYPE(right) == AOP_LIT){
5783             int t = (lit >> (offset*8)) & 0x0FFL;
5784             switch(t) { 
5785             case 0x00:
5786               pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
5787               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5788
5789               pic16_emitcode("movf","%s,w",
5790                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5791               pic16_emitcode("movwf","%s",
5792                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5793               break;
5794             default:
5795               pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
5796               pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5797               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5798
5799               pic16_emitcode("movlw","0x%x",t);
5800               pic16_emitcode("iorwf","%s,w",
5801                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5802               pic16_emitcode("movwf","%s",
5803                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5804               
5805             }
5806             continue;
5807           }
5808
5809           // faster than result <- left, anl result,right
5810           // and better if result is SFR
5811           if (AOP_TYPE(left) == AOP_ACC) {
5812             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
5813             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5814           } else {
5815             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5816             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5817
5818             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5819             pic16_emitcode("iorwf","%s,w",
5820                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5821           }
5822           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5823           pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5824         }
5825     }
5826
5827 release :
5828     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5829     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5830     pic16_freeAsmop(result,NULL,ic,TRUE);     
5831 }
5832
5833 /*-----------------------------------------------------------------*/
5834 /* genXor - code for xclusive or                                   */
5835 /*-----------------------------------------------------------------*/
5836 static void genXor (iCode *ic, iCode *ifx)
5837 {
5838   operand *left, *right, *result;
5839   int size, offset=0;
5840   unsigned long lit = 0L;
5841
5842   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5843
5844   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5845   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5846   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5847
5848   /* if left is a literal & right is not ||
5849      if left needs acc & right does not */
5850   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5851       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5852     operand *tmp = right ;
5853     right = left;
5854     left = tmp;
5855   }
5856
5857   /* if result = right then exchange them */
5858   if(pic16_sameRegs(AOP(result),AOP(right))){
5859     operand *tmp = right ;
5860     right = left;
5861     left = tmp;
5862   }
5863
5864   /* if right is bit then exchange them */
5865   if (AOP_TYPE(right) == AOP_CRY &&
5866       AOP_TYPE(left) != AOP_CRY){
5867     operand *tmp = right ;
5868     right = left;
5869     left = tmp;
5870   }
5871   if(AOP_TYPE(right) == AOP_LIT)
5872     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5873
5874   size = AOP_SIZE(result);
5875
5876   // if(bit ^ yy)
5877   // xx = bit ^ yy;
5878   if (AOP_TYPE(left) == AOP_CRY){
5879     if(AOP_TYPE(right) == AOP_LIT){
5880       // c = bit & literal;
5881       if(lit>>1){
5882         // lit>>1  != 0 => result = 1
5883         if(AOP_TYPE(result) == AOP_CRY){
5884           if(size)
5885             {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
5886             pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5887           else if(ifx)
5888             continueIfTrue(ifx);
5889           goto release;
5890         }
5891         pic16_emitcode("setb","c");
5892       } else{
5893         // lit == (0 or 1)
5894         if(lit == 0){
5895           // lit == 0, result = left
5896           if(size && pic16_sameRegs(AOP(result),AOP(left)))
5897             goto release;
5898           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5899         } else{
5900           // lit == 1, result = not(left)
5901           if(size && pic16_sameRegs(AOP(result),AOP(left))){
5902             pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
5903             pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
5904             pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5905             goto release;
5906           } else {
5907             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5908             pic16_emitcode("cpl","c");
5909           }
5910         }
5911       }
5912
5913     } else {
5914       // right != literal
5915       symbol *tlbl = newiTempLabel(NULL);
5916       if (AOP_TYPE(right) == AOP_CRY){
5917         // c = bit ^ bit;
5918         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5919       }
5920       else{
5921         int sizer = AOP_SIZE(right);
5922         // c = bit ^ val
5923         // if val>>1 != 0, result = 1
5924         pic16_emitcode("setb","c");
5925         while(sizer){
5926           MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5927           if(sizer == 1)
5928             // test the msb of the lsb
5929             pic16_emitcode("anl","a,#0xfe");
5930           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5931           sizer--;
5932         }
5933         // val = (0,1)
5934         pic16_emitcode("rrc","a");
5935       }
5936       pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5937       pic16_emitcode("cpl","c");
5938       pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5939     }
5940     // bit = c
5941     // val = c
5942     if(size)
5943       pic16_outBitC(result);
5944     // if(bit | ...)
5945     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5946       genIfxJump(ifx, "c");           
5947     goto release ;
5948   }
5949
5950   if(pic16_sameRegs(AOP(result),AOP(left))){
5951     /* if left is same as result */
5952     for(;size--; offset++) {
5953       if(AOP_TYPE(right) == AOP_LIT){
5954         int t  = (lit >> (offset*8)) & 0x0FFL;
5955         if(t == 0x00L)
5956           continue;
5957         else
5958           if (IS_AOP_PREG(left)) {
5959             MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5960             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5961             pic16_aopPut(AOP(result),"a",offset);
5962           } else {
5963             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5964             pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5965             pic16_emitcode("xrl","%s,%s",
5966                            pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5967                            pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5968           }
5969       } else {
5970         if (AOP_TYPE(left) == AOP_ACC)
5971           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5972         else {
5973           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5974           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5975 /*
5976           if (IS_AOP_PREG(left)) {
5977             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5978             pic16_aopPut(AOP(result),"a",offset);
5979           } else
5980             pic16_emitcode("xrl","%s,a",
5981                            pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5982 */
5983         }
5984       }
5985     }
5986   } else {
5987     // left & result in different registers
5988     if(AOP_TYPE(result) == AOP_CRY){
5989       // result = bit
5990       // if(size), result in bit
5991       // if(!size && ifx), conditional oper: if(left ^ right)
5992       symbol *tlbl = newiTempLabel(NULL);
5993       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5994       if(size)
5995         pic16_emitcode("setb","c");
5996       while(sizer--){
5997         if((AOP_TYPE(right) == AOP_LIT) &&
5998            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5999           MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6000         } else {
6001           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6002           pic16_emitcode("xrl","a,%s",
6003                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6004         }
6005         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6006         offset++;
6007       }
6008       if(size){
6009         CLRC;
6010         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6011         pic16_outBitC(result);
6012       } else if(ifx)
6013         jmpTrueOrFalse(ifx, tlbl);
6014     } else for(;(size--);offset++){
6015       // normal case
6016       // result = left & right
6017       if(AOP_TYPE(right) == AOP_LIT){
6018         int t = (lit >> (offset*8)) & 0x0FFL;
6019         switch(t) { 
6020         case 0x00:
6021           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6022           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6023           pic16_emitcode("movf","%s,w",
6024                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6025           pic16_emitcode("movwf","%s",
6026                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6027           break;
6028         case 0xff:
6029           pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6030           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6031           pic16_emitcode("comf","%s,w",
6032                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6033           pic16_emitcode("movwf","%s",
6034                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6035           break;
6036         default:
6037           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6038           pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6039           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6040           pic16_emitcode("movlw","0x%x",t);
6041           pic16_emitcode("xorwf","%s,w",
6042                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6043           pic16_emitcode("movwf","%s",
6044                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6045
6046         }
6047         continue;
6048       }
6049
6050       // faster than result <- left, anl result,right
6051       // and better if result is SFR
6052       if (AOP_TYPE(left) == AOP_ACC) {
6053         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6054         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6055       } else {
6056         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6057         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6058         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6059         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6060       }
6061       if ( AOP_TYPE(result) != AOP_ACC){
6062         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6063         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6064       }
6065     }
6066   }
6067
6068   release :
6069     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6070   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6071   pic16_freeAsmop(result,NULL,ic,TRUE);     
6072 }
6073
6074 /*-----------------------------------------------------------------*/
6075 /* genInline - write the inline code out                           */
6076 /*-----------------------------------------------------------------*/
6077 static void genInline (iCode *ic)
6078 {
6079     char *buffer, *bp, *bp1;
6080     
6081     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6082
6083     _G.inLine += (!options.asmpeep);
6084
6085     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6086     strcpy(buffer,IC_INLINE(ic));
6087
6088     /* emit each line as a code */
6089     while (*bp) {
6090         if (*bp == '\n') {
6091             *bp++ = '\0';
6092
6093             if(*bp1)
6094               pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6095             bp1 = bp;
6096         } else {
6097             if (*bp == ':') {
6098                 bp++;
6099                 *bp = '\0';
6100                 bp++;
6101                 pic16_emitcode(bp1,"");
6102                 bp1 = bp;
6103             } else
6104                 bp++;
6105         }
6106     }
6107     if ((bp1 != bp) && *bp1)
6108       pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6109
6110     Safe_free(buffer);
6111
6112     _G.inLine -= (!options.asmpeep);
6113 }
6114
6115 /*-----------------------------------------------------------------*/
6116 /* genRRC - rotate right with carry                                */
6117 /*-----------------------------------------------------------------*/
6118 static void genRRC (iCode *ic)
6119 {
6120   operand *left , *result ;
6121   int size, offset = 0, same;
6122
6123   /* rotate right with carry */
6124   left = IC_LEFT(ic);
6125   result=IC_RESULT(ic);
6126   pic16_aopOp (left,ic,FALSE);
6127   pic16_aopOp (result,ic,FALSE);
6128
6129   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6130
6131   same = pic16_sameRegs(AOP(result),AOP(left));
6132
6133   size = AOP_SIZE(result);    
6134
6135   /* get the lsb and put it into the carry */
6136   pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6137
6138   offset = 0 ;
6139
6140   while(size--) {
6141
6142     if(same) {
6143       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6144     } else {
6145       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6146       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6147     }
6148
6149     offset++;
6150   }
6151
6152   pic16_freeAsmop(left,NULL,ic,TRUE);
6153   pic16_freeAsmop(result,NULL,ic,TRUE);
6154 }
6155
6156 /*-----------------------------------------------------------------*/
6157 /* genRLC - generate code for rotate left with carry               */
6158 /*-----------------------------------------------------------------*/
6159 static void genRLC (iCode *ic)
6160 {    
6161   operand *left , *result ;
6162   int size, offset = 0;
6163   int same;
6164
6165   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6166   /* rotate right with carry */
6167   left = IC_LEFT(ic);
6168   result=IC_RESULT(ic);
6169   pic16_aopOp (left,ic,FALSE);
6170   pic16_aopOp (result,ic,FALSE);
6171
6172   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6173
6174   same = pic16_sameRegs(AOP(result),AOP(left));
6175
6176   /* move it to the result */
6177   size = AOP_SIZE(result);    
6178
6179   /* get the msb and put it into the carry */
6180   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6181
6182   offset = 0 ;
6183
6184   while(size--) {
6185
6186     if(same) {
6187       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6188     } else {
6189       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6190       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6191     }
6192
6193     offset++;
6194   }
6195
6196
6197   pic16_freeAsmop(left,NULL,ic,TRUE);
6198   pic16_freeAsmop(result,NULL,ic,TRUE);
6199 }
6200
6201 /*-----------------------------------------------------------------*/
6202 /* genGetHbit - generates code get highest order bit               */
6203 /*-----------------------------------------------------------------*/
6204 static void genGetHbit (iCode *ic)
6205 {
6206     operand *left, *result;
6207     left = IC_LEFT(ic);
6208     result=IC_RESULT(ic);
6209     pic16_aopOp (left,ic,FALSE);
6210     pic16_aopOp (result,ic,FALSE);
6211
6212     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6213     /* get the highest order byte into a */
6214     MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6215     if(AOP_TYPE(result) == AOP_CRY){
6216         pic16_emitcode("rlc","a");
6217         pic16_outBitC(result);
6218     }
6219     else{
6220         pic16_emitcode("rl","a");
6221         pic16_emitcode("anl","a,#0x01");
6222         pic16_outAcc(result);
6223     }
6224
6225
6226     pic16_freeAsmop(left,NULL,ic,TRUE);
6227     pic16_freeAsmop(result,NULL,ic,TRUE);
6228 }
6229
6230 /*-----------------------------------------------------------------*/
6231 /* AccRol - rotate left accumulator by known count                 */
6232 /*-----------------------------------------------------------------*/
6233 static void AccRol (int shCount)
6234 {
6235     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6236     shCount &= 0x0007;              // shCount : 0..7
6237     switch(shCount){
6238         case 0 :
6239             break;
6240         case 1 :
6241             pic16_emitcode("rl","a");
6242             break;
6243         case 2 :
6244             pic16_emitcode("rl","a");
6245             pic16_emitcode("rl","a");
6246             break;
6247         case 3 :
6248             pic16_emitcode("swap","a");
6249             pic16_emitcode("rr","a");
6250             break;
6251         case 4 :
6252             pic16_emitcode("swap","a");
6253             break;
6254         case 5 :
6255             pic16_emitcode("swap","a");
6256             pic16_emitcode("rl","a");
6257             break;
6258         case 6 :
6259             pic16_emitcode("rr","a");
6260             pic16_emitcode("rr","a");
6261             break;
6262         case 7 :
6263             pic16_emitcode("rr","a");
6264             break;
6265     }
6266 }
6267
6268 /*-----------------------------------------------------------------*/
6269 /* AccLsh - left shift accumulator by known count                  */
6270 /*-----------------------------------------------------------------*/
6271 static void AccLsh (int shCount)
6272 {
6273     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6274     if(shCount != 0){
6275         if(shCount == 1)
6276             pic16_emitcode("add","a,acc");
6277         else 
6278             if(shCount == 2) {
6279             pic16_emitcode("add","a,acc");
6280             pic16_emitcode("add","a,acc");
6281         } else {
6282             /* rotate left accumulator */
6283             AccRol(shCount);
6284             /* and kill the lower order bits */
6285             pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6286         }
6287     }
6288 }
6289
6290 /*-----------------------------------------------------------------*/
6291 /* AccRsh - right shift accumulator by known count                 */
6292 /*-----------------------------------------------------------------*/
6293 static void AccRsh (int shCount)
6294 {
6295     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6296     if(shCount != 0){
6297         if(shCount == 1){
6298             CLRC;
6299             pic16_emitcode("rrc","a");
6300         } else {
6301             /* rotate right accumulator */
6302             AccRol(8 - shCount);
6303             /* and kill the higher order bits */
6304             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6305         }
6306     }
6307 }
6308
6309 #if 0
6310 /*-----------------------------------------------------------------*/
6311 /* AccSRsh - signed right shift accumulator by known count                 */
6312 /*-----------------------------------------------------------------*/
6313 static void AccSRsh (int shCount)
6314 {
6315     symbol *tlbl ;
6316     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6317     if(shCount != 0){
6318         if(shCount == 1){
6319             pic16_emitcode("mov","c,acc.7");
6320             pic16_emitcode("rrc","a");
6321         } else if(shCount == 2){
6322             pic16_emitcode("mov","c,acc.7");
6323             pic16_emitcode("rrc","a");
6324             pic16_emitcode("mov","c,acc.7");
6325             pic16_emitcode("rrc","a");
6326         } else {
6327             tlbl = newiTempLabel(NULL);
6328             /* rotate right accumulator */
6329             AccRol(8 - shCount);
6330             /* and kill the higher order bits */
6331             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6332             pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6333             pic16_emitcode("orl","a,#0x%02x",
6334                      (unsigned char)~SRMask[shCount]);
6335             pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6336         }
6337     }
6338 }
6339 #endif
6340 /*-----------------------------------------------------------------*/
6341 /* shiftR1Left2Result - shift right one byte from left to result   */
6342 /*-----------------------------------------------------------------*/
6343 static void shiftR1Left2ResultSigned (operand *left, int offl,
6344                                 operand *result, int offr,
6345                                 int shCount)
6346 {
6347   int same;
6348
6349   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6350
6351   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6352
6353   switch(shCount) {
6354   case 1:
6355     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6356     if(same) 
6357       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6358     else {
6359       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6360       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6361     }
6362
6363     break;
6364   case 2:
6365
6366     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6367     if(same) 
6368       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6369     else {
6370       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6371       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6372     }
6373     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6374     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6375
6376     break;
6377
6378   case 3:
6379     if(same)
6380       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6381     else {
6382       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6383       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6384     }
6385
6386     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6387     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6388     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6389
6390     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6391     pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6392
6393     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6394     break;
6395
6396   case 4:
6397     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6398     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
6399     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6400     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
6401     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6402     break;
6403   case 5:
6404     if(same) {
6405       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
6406     } else {
6407       pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
6408       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6409     }
6410     pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
6411     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
6412     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6413     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
6414     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6415     break;
6416
6417   case 6:
6418     if(same) {
6419       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6420       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6421       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6422       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6423       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6424       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6425     } else {
6426       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6427       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6428       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6429       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6430       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6431     }
6432     break;
6433
6434   case 7:
6435     if(same) {
6436       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6437       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6438       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6439       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6440     } else {
6441       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6442       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6443       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6444     }
6445
6446   default:
6447     break;
6448   }
6449 }
6450
6451 /*-----------------------------------------------------------------*/
6452 /* shiftR1Left2Result - shift right one byte from left to result   */
6453 /*-----------------------------------------------------------------*/
6454 static void shiftR1Left2Result (operand *left, int offl,
6455                                 operand *result, int offr,
6456                                 int shCount, int sign)
6457 {
6458   int same;
6459
6460   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6461
6462   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6463
6464   /* Copy the msb into the carry if signed. */
6465   if(sign) {
6466     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6467     return;
6468   }
6469
6470
6471
6472   switch(shCount) {
6473   case 1:
6474     emitCLRC;
6475     if(same) 
6476       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6477     else {
6478       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6479       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6480     }
6481     break;
6482   case 2:
6483     emitCLRC;
6484     if(same) {
6485       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6486     } else {
6487       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6488       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6489     }
6490     emitCLRC;
6491     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6492
6493     break;
6494   case 3:
6495     if(same)
6496       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6497     else {
6498       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6499       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6500     }
6501
6502     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6503     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6504     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6505     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6506     break;
6507       
6508   case 4:
6509     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6510     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6511     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6512     break;
6513
6514   case 5:
6515     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6516     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6517     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6518     emitCLRC;
6519     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6520
6521     break;
6522   case 6:
6523
6524     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl));
6525     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6526     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6527     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6528     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6529     break;
6530
6531   case 7:
6532
6533     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6534     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6535     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6536
6537     break;
6538
6539   default:
6540     break;
6541   }
6542 }
6543
6544 /*-----------------------------------------------------------------*/
6545 /* shiftL1Left2Result - shift left one byte from left to result    */
6546 /*-----------------------------------------------------------------*/
6547 static void shiftL1Left2Result (operand *left, int offl,
6548                                 operand *result, int offr, int shCount)
6549 {
6550   int same;
6551
6552   //    char *l;
6553   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6554
6555   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6556   DEBUGpic16_emitcode ("; ***","same =  %d",same);
6557     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6558     //    MOVA(l);
6559     /* shift left accumulator */
6560     //AccLsh(shCount); // don't comment out just yet...
6561   //    pic16_aopPut(AOP(result),"a",offr);
6562
6563   switch(shCount) {
6564   case 1:
6565     /* Shift left 1 bit position */
6566     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6567     if(same) {
6568       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6569     } else {
6570       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6571       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6572     }
6573     break;
6574   case 2:
6575     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6576     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6577     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6578     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6579     break;
6580   case 3:
6581     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6582     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6583     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6584     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6585     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6586     break;
6587   case 4:
6588     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6589     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6590     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6591     break;
6592   case 5:
6593     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6594     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6595     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6596     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6597     break;
6598   case 6:
6599     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6600     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6601     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6602     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6603     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6604     break;
6605   case 7:
6606     pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6607     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6608     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6609     break;
6610
6611   default:
6612     DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6613   }
6614
6615 }
6616
6617 /*-----------------------------------------------------------------*/
6618 /* movLeft2Result - move byte from left to result                  */
6619 /*-----------------------------------------------------------------*/
6620 static void movLeft2Result (operand *left, int offl,
6621                             operand *result, int offr)
6622 {
6623   char *l;
6624   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6625   if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6626     l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6627
6628     if (*l == '@' && (IS_AOP_PREG(result))) {
6629       pic16_emitcode("mov","a,%s",l);
6630       pic16_aopPut(AOP(result),"a",offr);
6631     } else {
6632       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6633       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6634     }
6635   }
6636 }
6637
6638 /*-----------------------------------------------------------------*/
6639 /* shiftL2Left2Result - shift left two bytes from left to result   */
6640 /*-----------------------------------------------------------------*/
6641 static void shiftL2Left2Result (operand *left, int offl,
6642                                 operand *result, int offr, int shCount)
6643 {
6644
6645
6646   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6647
6648   if(pic16_sameRegs(AOP(result), AOP(left))) {
6649     switch(shCount) {
6650     case 0:
6651       break;
6652     case 1:
6653     case 2:
6654     case 3:
6655
6656       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6657       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6658       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6659
6660       while(--shCount) {
6661         emitCLRC;
6662         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6663         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6664       }
6665
6666       break;
6667     case 4:
6668     case 5:
6669       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6670       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6671       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6672       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6673       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6674       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6675       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6676       if(shCount >=5) {
6677         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6678         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6679       }
6680       break;
6681     case 6:
6682       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6683       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6684       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6685       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6686       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6687       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6688       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6689       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6690       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6691       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6692       break;
6693     case 7:
6694       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6695       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6696       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6697       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6698       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6699     }
6700
6701   } else {
6702     switch(shCount) {
6703     case 0:
6704       break;
6705     case 1:
6706     case 2:
6707     case 3:
6708       /* note, use a mov/add for the shift since the mov has a
6709          chance of getting optimized out */
6710       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6711       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6712       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6713       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl+MSB16));
6714       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6715
6716       while(--shCount) {
6717         emitCLRC;
6718         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6719         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6720       }
6721       break;
6722
6723     case 4:
6724     case 5:
6725       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6726       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6727       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6728       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6729       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6730       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6731       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6732       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6733
6734
6735       if(shCount == 5) {
6736         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6737         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6738       }
6739       break;
6740     case 6:
6741       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6742       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6743       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6744       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6745
6746       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6747       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6748       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6749       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6750       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6751       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6752       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6753       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6754       break;
6755     case 7:
6756       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6757       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6758       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6759       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6760       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6761     }
6762   }
6763
6764 }
6765 /*-----------------------------------------------------------------*/
6766 /* shiftR2Left2Result - shift right two bytes from left to result  */
6767 /*-----------------------------------------------------------------*/
6768 static void shiftR2Left2Result (operand *left, int offl,
6769                                 operand *result, int offr,
6770                                 int shCount, int sign)
6771 {
6772   int same=0;
6773
6774   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6775   same = pic16_sameRegs(AOP(result), AOP(left));
6776
6777   if(same && ((offl + MSB16) == offr)){
6778     same=1;
6779     /* don't crash result[offr] */
6780     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6781     pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6782   }
6783 /* else {
6784     movLeft2Result(left,offl, result, offr);
6785     MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6786   }
6787 */
6788   /* a:x >> shCount (x = lsb(result))*/
6789 /*
6790   if(sign)
6791     AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6792   else {
6793     AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6794 */
6795   switch(shCount) {
6796   case 0:
6797     break;
6798   case 1:
6799   case 2:
6800   case 3:
6801     if(sign)
6802       pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6803     else
6804       emitCLRC;
6805
6806     if(same) {
6807       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6808       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6809     } else {
6810       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6811       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6812       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6813       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6814     }
6815
6816     while(--shCount) {
6817       if(sign)
6818         pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6819       else
6820         emitCLRC;
6821       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6822       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6823     }
6824     break;
6825   case 4:
6826   case 5:
6827     if(same) {
6828
6829       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6830       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6831       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6832
6833       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6834       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6835       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6836       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6837     } else {
6838       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6839       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6840       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6841
6842       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6843       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6844       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6845       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6846       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6847     }
6848
6849     if(shCount >=5) {
6850       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6851       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6852     }
6853
6854     if(sign) {
6855       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6856       pic16_emitpcode(POC_BTFSC, 
6857                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6858       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6859     }
6860
6861     break;
6862
6863   case 6:
6864     if(same) {
6865
6866       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6867       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6868
6869       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6870       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6871       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6872       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6873       if(sign) {
6874         pic16_emitpcode(POC_BTFSC, 
6875                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6876         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6877       }
6878       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6879       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6880       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6881       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6882     } else {
6883       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6884       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6885       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6886       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6887       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6888       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6889       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6890       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6891       if(sign) {
6892         pic16_emitpcode(POC_BTFSC, 
6893                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6894         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6895       }
6896       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6897       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6898
6899         
6900     }
6901
6902     break;
6903   case 7:
6904     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6905     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6906     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6907     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6908     if(sign) {
6909       emitSKPNC;
6910       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6911     } else 
6912       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6913   }
6914 }
6915
6916
6917 /*-----------------------------------------------------------------*/
6918 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6919 /*-----------------------------------------------------------------*/
6920 static void shiftLLeftOrResult (operand *left, int offl,
6921                                 operand *result, int offr, int shCount)
6922 {
6923     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6924     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6925     /* shift left accumulator */
6926     AccLsh(shCount);
6927     /* or with result */
6928     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6929     /* back to result */
6930     pic16_aopPut(AOP(result),"a",offr);
6931 }
6932
6933 /*-----------------------------------------------------------------*/
6934 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6935 /*-----------------------------------------------------------------*/
6936 static void shiftRLeftOrResult (operand *left, int offl,
6937                                 operand *result, int offr, int shCount)
6938 {
6939     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6940     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6941     /* shift right accumulator */
6942     AccRsh(shCount);
6943     /* or with result */
6944     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6945     /* back to result */
6946     pic16_aopPut(AOP(result),"a",offr);
6947 }
6948
6949 /*-----------------------------------------------------------------*/
6950 /* genlshOne - left shift a one byte quantity by known count       */
6951 /*-----------------------------------------------------------------*/
6952 static void genlshOne (operand *result, operand *left, int shCount)
6953 {       
6954     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6955     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6956 }
6957
6958 /*-----------------------------------------------------------------*/
6959 /* genlshTwo - left shift two bytes by known amount != 0           */
6960 /*-----------------------------------------------------------------*/
6961 static void genlshTwo (operand *result,operand *left, int shCount)
6962 {
6963     int size;
6964     
6965     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6966     size = pic16_getDataSize(result);
6967
6968     /* if shCount >= 8 */
6969     if (shCount >= 8) {
6970         shCount -= 8 ;
6971
6972         if (size > 1){
6973             if (shCount)
6974                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6975             else 
6976                 movLeft2Result(left, LSB, result, MSB16);
6977         }
6978         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6979     }
6980
6981     /*  1 <= shCount <= 7 */
6982     else {  
6983         if(size == 1)
6984             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6985         else 
6986             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6987     }
6988 }
6989
6990 /*-----------------------------------------------------------------*/
6991 /* shiftLLong - shift left one long from left to result            */
6992 /* offl = LSB or MSB16                                             */
6993 /*-----------------------------------------------------------------*/
6994 static void shiftLLong (operand *left, operand *result, int offr )
6995 {
6996     char *l;
6997     int size = AOP_SIZE(result);
6998
6999     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7000     if(size >= LSB+offr){
7001         l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7002         MOVA(l);
7003         pic16_emitcode("add","a,acc");
7004         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7005             size >= MSB16+offr && offr != LSB )
7006             pic16_emitcode("xch","a,%s",
7007                      pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7008         else        
7009             pic16_aopPut(AOP(result),"a",LSB+offr);
7010     }
7011
7012     if(size >= MSB16+offr){
7013         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7014             l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7015             MOVA(l);
7016         }
7017         pic16_emitcode("rlc","a");
7018         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7019             size >= MSB24+offr && offr != LSB)
7020             pic16_emitcode("xch","a,%s",
7021                      pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7022         else        
7023             pic16_aopPut(AOP(result),"a",MSB16+offr);
7024     }
7025
7026     if(size >= MSB24+offr){
7027         if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7028             l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7029             MOVA(l);
7030         }
7031         pic16_emitcode("rlc","a");
7032         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7033             size >= MSB32+offr && offr != LSB )
7034             pic16_emitcode("xch","a,%s",
7035                      pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7036         else        
7037             pic16_aopPut(AOP(result),"a",MSB24+offr);
7038     }
7039
7040     if(size > MSB32+offr){
7041         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7042             l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7043             MOVA(l);    
7044         }
7045         pic16_emitcode("rlc","a");
7046         pic16_aopPut(AOP(result),"a",MSB32+offr);
7047     }
7048     if(offr != LSB)
7049         pic16_aopPut(AOP(result),zero,LSB);       
7050 }
7051
7052 /*-----------------------------------------------------------------*/
7053 /* genlshFour - shift four byte by a known amount != 0             */
7054 /*-----------------------------------------------------------------*/
7055 static void genlshFour (operand *result, operand *left, int shCount)
7056 {
7057     int size;
7058
7059     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7060     size = AOP_SIZE(result);
7061
7062     /* if shifting more that 3 bytes */
7063     if (shCount >= 24 ) {
7064         shCount -= 24;
7065         if (shCount)
7066             /* lowest order of left goes to the highest
7067             order of the destination */
7068             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7069         else
7070             movLeft2Result(left, LSB, result, MSB32);
7071         pic16_aopPut(AOP(result),zero,LSB);
7072         pic16_aopPut(AOP(result),zero,MSB16);
7073         pic16_aopPut(AOP(result),zero,MSB32);
7074         return;
7075     }
7076
7077     /* more than two bytes */
7078     else if ( shCount >= 16 ) {
7079         /* lower order two bytes goes to higher order two bytes */
7080         shCount -= 16;
7081         /* if some more remaining */
7082         if (shCount)
7083             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7084         else {
7085             movLeft2Result(left, MSB16, result, MSB32);
7086             movLeft2Result(left, LSB, result, MSB24);
7087         }
7088         pic16_aopPut(AOP(result),zero,MSB16);
7089         pic16_aopPut(AOP(result),zero,LSB);
7090         return;
7091     }    
7092
7093     /* if more than 1 byte */
7094     else if ( shCount >= 8 ) {
7095         /* lower order three bytes goes to higher order  three bytes */
7096         shCount -= 8;
7097         if(size == 2){
7098             if(shCount)
7099                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7100             else
7101                 movLeft2Result(left, LSB, result, MSB16);
7102         }
7103         else{   /* size = 4 */
7104             if(shCount == 0){
7105                 movLeft2Result(left, MSB24, result, MSB32);
7106                 movLeft2Result(left, MSB16, result, MSB24);
7107                 movLeft2Result(left, LSB, result, MSB16);
7108                 pic16_aopPut(AOP(result),zero,LSB);
7109             }
7110             else if(shCount == 1)
7111                 shiftLLong(left, result, MSB16);
7112             else{
7113                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7114                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7115                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7116                 pic16_aopPut(AOP(result),zero,LSB);
7117             }
7118         }
7119     }
7120
7121     /* 1 <= shCount <= 7 */
7122     else if(shCount <= 2){
7123         shiftLLong(left, result, LSB);
7124         if(shCount == 2)
7125             shiftLLong(result, result, LSB);
7126     }
7127     /* 3 <= shCount <= 7, optimize */
7128     else{
7129         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7130         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7131         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7132     }
7133 }
7134
7135 /*-----------------------------------------------------------------*/
7136 /* genLeftShiftLiteral - left shifting by known count              */
7137 /*-----------------------------------------------------------------*/
7138 static void genLeftShiftLiteral (operand *left,
7139                                  operand *right,
7140                                  operand *result,
7141                                  iCode *ic)
7142 {    
7143     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7144     int size;
7145
7146     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7147     pic16_freeAsmop(right,NULL,ic,TRUE);
7148
7149     pic16_aopOp(left,ic,FALSE);
7150     pic16_aopOp(result,ic,FALSE);
7151
7152     size = getSize(operandType(result));
7153
7154 #if VIEW_SIZE
7155     pic16_emitcode("; shift left ","result %d, left %d",size,
7156              AOP_SIZE(left));
7157 #endif
7158
7159     /* I suppose that the left size >= result size */
7160     if(shCount == 0){
7161         while(size--){
7162             movLeft2Result(left, size, result, size);
7163         }
7164     }
7165
7166     else if(shCount >= (size * 8))
7167         while(size--)
7168             pic16_aopPut(AOP(result),zero,size);
7169     else{
7170         switch (size) {
7171             case 1:
7172                 genlshOne (result,left,shCount);
7173                 break;
7174
7175             case 2:
7176             case 3:
7177                 genlshTwo (result,left,shCount);
7178                 break;
7179
7180             case 4:
7181                 genlshFour (result,left,shCount);
7182                 break;
7183         }
7184     }
7185     pic16_freeAsmop(left,NULL,ic,TRUE);
7186     pic16_freeAsmop(result,NULL,ic,TRUE);
7187 }
7188
7189 /*-----------------------------------------------------------------*
7190  * genMultiAsm - repeat assembly instruction for size of register.
7191  * if endian == 1, then the high byte (i.e base address + size of 
7192  * register) is used first else the low byte is used first;
7193  *-----------------------------------------------------------------*/
7194 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7195 {
7196
7197   int offset = 0;
7198
7199   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7200
7201   if(!reg)
7202     return;
7203
7204   if(!endian) {
7205     endian = 1;
7206   } else {
7207     endian = -1;
7208     offset = size-1;
7209   }
7210
7211   while(size--) {
7212     pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
7213     offset += endian;
7214   }
7215
7216 }
7217 /*-----------------------------------------------------------------*/
7218 /* genLeftShift - generates code for left shifting                 */
7219 /*-----------------------------------------------------------------*/
7220 static void genLeftShift (iCode *ic)
7221 {
7222   operand *left,*right, *result;
7223   int size, offset;
7224   char *l;
7225   symbol *tlbl , *tlbl1;
7226   pCodeOp *pctemp;
7227
7228   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7229
7230   right = IC_RIGHT(ic);
7231   left  = IC_LEFT(ic);
7232   result = IC_RESULT(ic);
7233
7234   pic16_aopOp(right,ic,FALSE);
7235
7236   /* if the shift count is known then do it 
7237      as efficiently as possible */
7238   if (AOP_TYPE(right) == AOP_LIT) {
7239     genLeftShiftLiteral (left,right,result,ic);
7240     return ;
7241   }
7242
7243   /* shift count is unknown then we have to form 
7244      a loop get the loop count in B : Note: we take
7245      only the lower order byte since shifting
7246      more that 32 bits make no sense anyway, ( the
7247      largest size of an object can be only 32 bits ) */  
7248
7249     
7250   pic16_aopOp(left,ic,FALSE);
7251   pic16_aopOp(result,ic,FALSE);
7252
7253   /* now move the left to the result if they are not the
7254      same */
7255   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7256       AOP_SIZE(result) > 1) {
7257
7258     size = AOP_SIZE(result);
7259     offset=0;
7260     while (size--) {
7261       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7262       if (*l == '@' && (IS_AOP_PREG(result))) {
7263
7264         pic16_emitcode("mov","a,%s",l);
7265         pic16_aopPut(AOP(result),"a",offset);
7266       } else {
7267         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7268         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7269         //pic16_aopPut(AOP(result),l,offset);
7270       }
7271       offset++;
7272     }
7273   }
7274
7275   size = AOP_SIZE(result);
7276
7277   /* if it is only one byte then */
7278   if (size == 1) {
7279     if(optimized_for_speed) {
7280       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7281       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
7282       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7283       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7284       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7285       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7286       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7287       pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
7288       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
7289       pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
7290       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7291       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7292     } else {
7293
7294       tlbl = newiTempLabel(NULL);
7295       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7296         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7297         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7298       }
7299
7300       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7301       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7302       pic16_emitpLabel(tlbl->key);
7303       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7304       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7305       emitSKPC;
7306       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7307     }
7308     goto release ;
7309   }
7310     
7311   if (pic16_sameRegs(AOP(left),AOP(result))) {
7312
7313     tlbl = newiTempLabel(NULL);
7314     pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7315     genMultiAsm(POC_RRCF, result, size,1);
7316     pic16_emitpLabel(tlbl->key);
7317     genMultiAsm(POC_RLCF, result, size,0);
7318     pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7319     emitSKPC;
7320     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7321     goto release;
7322   }
7323
7324   //tlbl = newiTempLabel(NULL);
7325   //offset = 0 ;   
7326   //tlbl1 = newiTempLabel(NULL);
7327
7328   //reAdjustPreg(AOP(result));    
7329     
7330   //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7331   //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7332   //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7333   //MOVA(l);
7334   //pic16_emitcode("add","a,acc");         
7335   //pic16_aopPut(AOP(result),"a",offset++);
7336   //while (--size) {
7337   //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7338   //  MOVA(l);
7339   //  pic16_emitcode("rlc","a");         
7340   //  pic16_aopPut(AOP(result),"a",offset++);
7341   //}
7342   //reAdjustPreg(AOP(result));
7343
7344   //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7345   //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7346
7347
7348   tlbl = newiTempLabel(NULL);
7349   tlbl1= newiTempLabel(NULL);
7350
7351   size = AOP_SIZE(result);
7352   offset = 1;
7353
7354   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7355
7356   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7357
7358   /* offset should be 0, 1 or 3 */
7359   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7360   emitSKPNZ;
7361   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7362
7363   pic16_emitpcode(POC_MOVWF, pctemp);
7364
7365
7366   pic16_emitpLabel(tlbl->key);
7367
7368   emitCLRC;
7369   pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
7370   while(--size)
7371     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
7372
7373   pic16_emitpcode(POC_DECFSZ,  pctemp);
7374   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7375   pic16_emitpLabel(tlbl1->key);
7376
7377   pic16_popReleaseTempReg(pctemp);
7378
7379
7380  release:
7381   pic16_freeAsmop (right,NULL,ic,TRUE);
7382   pic16_freeAsmop(left,NULL,ic,TRUE);
7383   pic16_freeAsmop(result,NULL,ic,TRUE);
7384 }
7385
7386 /*-----------------------------------------------------------------*/
7387 /* genrshOne - right shift a one byte quantity by known count      */
7388 /*-----------------------------------------------------------------*/
7389 static void genrshOne (operand *result, operand *left,
7390                        int shCount, int sign)
7391 {
7392     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7393     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7394 }
7395
7396 /*-----------------------------------------------------------------*/
7397 /* genrshTwo - right shift two bytes by known amount != 0          */
7398 /*-----------------------------------------------------------------*/
7399 static void genrshTwo (operand *result,operand *left,
7400                        int shCount, int sign)
7401 {
7402   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7403   /* if shCount >= 8 */
7404   if (shCount >= 8) {
7405     shCount -= 8 ;
7406     if (shCount)
7407       shiftR1Left2Result(left, MSB16, result, LSB,
7408                          shCount, sign);
7409     else
7410       movLeft2Result(left, MSB16, result, LSB);
7411
7412     pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7413
7414     if(sign) {
7415       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7416       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7417     }
7418   }
7419
7420   /*  1 <= shCount <= 7 */
7421   else
7422     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7423 }
7424
7425 /*-----------------------------------------------------------------*/
7426 /* shiftRLong - shift right one long from left to result           */
7427 /* offl = LSB or MSB16                                             */
7428 /*-----------------------------------------------------------------*/
7429 static void shiftRLong (operand *left, int offl,
7430                         operand *result, int sign)
7431 {
7432     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7433     if(!sign)
7434         pic16_emitcode("clr","c");
7435     MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7436     if(sign)
7437         pic16_emitcode("mov","c,acc.7");
7438     pic16_emitcode("rrc","a");
7439     pic16_aopPut(AOP(result),"a",MSB32-offl);
7440     if(offl == MSB16)
7441         /* add sign of "a" */
7442         pic16_addSign(result, MSB32, sign);
7443
7444     MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7445     pic16_emitcode("rrc","a");
7446     pic16_aopPut(AOP(result),"a",MSB24-offl);
7447
7448     MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7449     pic16_emitcode("rrc","a");
7450     pic16_aopPut(AOP(result),"a",MSB16-offl);
7451
7452     if(offl == LSB){
7453         MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7454         pic16_emitcode("rrc","a");
7455         pic16_aopPut(AOP(result),"a",LSB);
7456     }
7457 }
7458
7459 /*-----------------------------------------------------------------*/
7460 /* genrshFour - shift four byte by a known amount != 0             */
7461 /*-----------------------------------------------------------------*/
7462 static void genrshFour (operand *result, operand *left,
7463                         int shCount, int sign)
7464 {
7465   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7466   /* if shifting more that 3 bytes */
7467   if(shCount >= 24 ) {
7468     shCount -= 24;
7469     if(shCount)
7470       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7471     else
7472       movLeft2Result(left, MSB32, result, LSB);
7473
7474     pic16_addSign(result, MSB16, sign);
7475   }
7476   else if(shCount >= 16){
7477     shCount -= 16;
7478     if(shCount)
7479       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7480     else{
7481       movLeft2Result(left, MSB24, result, LSB);
7482       movLeft2Result(left, MSB32, result, MSB16);
7483     }
7484     pic16_addSign(result, MSB24, sign);
7485   }
7486   else if(shCount >= 8){
7487     shCount -= 8;
7488     if(shCount == 1)
7489       shiftRLong(left, MSB16, result, sign);
7490     else if(shCount == 0){
7491       movLeft2Result(left, MSB16, result, LSB);
7492       movLeft2Result(left, MSB24, result, MSB16);
7493       movLeft2Result(left, MSB32, result, MSB24);
7494       pic16_addSign(result, MSB32, sign);
7495     }
7496     else{
7497       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7498       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7499       /* the last shift is signed */
7500       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7501       pic16_addSign(result, MSB32, sign);
7502     }
7503   }
7504   else{   /* 1 <= shCount <= 7 */
7505     if(shCount <= 2){
7506       shiftRLong(left, LSB, result, sign);
7507       if(shCount == 2)
7508         shiftRLong(result, LSB, result, sign);
7509     }
7510     else{
7511       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7512       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7513       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7514     }
7515   }
7516 }
7517
7518 /*-----------------------------------------------------------------*/
7519 /* genRightShiftLiteral - right shifting by known count            */
7520 /*-----------------------------------------------------------------*/
7521 static void genRightShiftLiteral (operand *left,
7522                                   operand *right,
7523                                   operand *result,
7524                                   iCode *ic,
7525                                   int sign)
7526 {    
7527   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7528   int lsize,res_size;
7529
7530   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7531   pic16_freeAsmop(right,NULL,ic,TRUE);
7532
7533   pic16_aopOp(left,ic,FALSE);
7534   pic16_aopOp(result,ic,FALSE);
7535
7536 #if VIEW_SIZE
7537   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7538                  AOP_SIZE(left));
7539 #endif
7540
7541   lsize = pic16_getDataSize(left);
7542   res_size = pic16_getDataSize(result);
7543   /* test the LEFT size !!! */
7544
7545   /* I suppose that the left size >= result size */
7546   if(shCount == 0){
7547     while(res_size--)
7548       movLeft2Result(left, lsize, result, res_size);
7549   }
7550
7551   else if(shCount >= (lsize * 8)){
7552
7553     if(res_size == 1) {
7554       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7555       if(sign) {
7556         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7557         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7558       }
7559     } else {
7560
7561       if(sign) {
7562         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7563         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7564         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7565         while(res_size--)
7566           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7567
7568       } else {
7569
7570         while(res_size--)
7571           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7572       }
7573     }
7574   } else {
7575
7576     switch (res_size) {
7577     case 1:
7578       genrshOne (result,left,shCount,sign);
7579       break;
7580
7581     case 2:
7582       genrshTwo (result,left,shCount,sign);
7583       break;
7584
7585     case 4:
7586       genrshFour (result,left,shCount,sign);
7587       break;
7588     default :
7589       break;
7590     }
7591
7592   }
7593
7594   pic16_freeAsmop(left,NULL,ic,TRUE);
7595   pic16_freeAsmop(result,NULL,ic,TRUE);
7596 }
7597
7598 /*-----------------------------------------------------------------*/
7599 /* genSignedRightShift - right shift of signed number              */
7600 /*-----------------------------------------------------------------*/
7601 static void genSignedRightShift (iCode *ic)
7602 {
7603   operand *right, *left, *result;
7604   int size, offset;
7605   //  char *l;
7606   symbol *tlbl, *tlbl1 ;
7607   pCodeOp *pctemp;
7608
7609   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7610
7611   /* we do it the hard way put the shift count in b
7612      and loop thru preserving the sign */
7613   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7614
7615   right = IC_RIGHT(ic);
7616   left  = IC_LEFT(ic);
7617   result = IC_RESULT(ic);
7618
7619   pic16_aopOp(right,ic,FALSE);  
7620   pic16_aopOp(left,ic,FALSE);
7621   pic16_aopOp(result,ic,FALSE);
7622
7623
7624   if ( AOP_TYPE(right) == AOP_LIT) {
7625     genRightShiftLiteral (left,right,result,ic,1);
7626     return ;
7627   }
7628   /* shift count is unknown then we have to form 
7629      a loop get the loop count in B : Note: we take
7630      only the lower order byte since shifting
7631      more that 32 bits make no sense anyway, ( the
7632      largest size of an object can be only 32 bits ) */  
7633
7634   //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7635   //pic16_emitcode("inc","b");
7636   //pic16_freeAsmop (right,NULL,ic,TRUE);
7637   //pic16_aopOp(left,ic,FALSE);
7638   //pic16_aopOp(result,ic,FALSE);
7639
7640   /* now move the left to the result if they are not the
7641      same */
7642   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7643       AOP_SIZE(result) > 1) {
7644
7645     size = AOP_SIZE(result);
7646     offset=0;
7647     while (size--) { 
7648       /*
7649         l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7650         if (*l == '@' && IS_AOP_PREG(result)) {
7651
7652         pic16_emitcode("mov","a,%s",l);
7653         pic16_aopPut(AOP(result),"a",offset);
7654         } else
7655         pic16_aopPut(AOP(result),l,offset);
7656       */
7657       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7658       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7659
7660       offset++;
7661     }
7662   }
7663
7664   /* mov the highest order bit to OVR */    
7665   tlbl = newiTempLabel(NULL);
7666   tlbl1= newiTempLabel(NULL);
7667
7668   size = AOP_SIZE(result);
7669   offset = size - 1;
7670
7671   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7672
7673   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7674
7675   /* offset should be 0, 1 or 3 */
7676   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7677   emitSKPNZ;
7678   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7679
7680   pic16_emitpcode(POC_MOVWF, pctemp);
7681
7682
7683   pic16_emitpLabel(tlbl->key);
7684
7685   pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
7686   pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
7687
7688   while(--size) {
7689     pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
7690   }
7691
7692   pic16_emitpcode(POC_DECFSZ,  pctemp);
7693   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7694   pic16_emitpLabel(tlbl1->key);
7695
7696   pic16_popReleaseTempReg(pctemp);
7697 #if 0
7698   size = AOP_SIZE(result);
7699   offset = size - 1;
7700   pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7701   pic16_emitcode("rlc","a");
7702   pic16_emitcode("mov","ov,c");
7703   /* if it is only one byte then */
7704   if (size == 1) {
7705     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7706     MOVA(l);
7707     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7708     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7709     pic16_emitcode("mov","c,ov");
7710     pic16_emitcode("rrc","a");
7711     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7712     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7713     pic16_aopPut(AOP(result),"a",0);
7714     goto release ;
7715   }
7716
7717   reAdjustPreg(AOP(result));
7718   pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7719   pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7720   pic16_emitcode("mov","c,ov");
7721   while (size--) {
7722     l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7723     MOVA(l);
7724     pic16_emitcode("rrc","a");         
7725     pic16_aopPut(AOP(result),"a",offset--);
7726   }
7727   reAdjustPreg(AOP(result));
7728   pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7729   pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7730
7731  release:
7732 #endif
7733
7734   pic16_freeAsmop(left,NULL,ic,TRUE);
7735   pic16_freeAsmop(result,NULL,ic,TRUE);
7736   pic16_freeAsmop(right,NULL,ic,TRUE);
7737 }
7738
7739 /*-----------------------------------------------------------------*/
7740 /* genRightShift - generate code for right shifting                */
7741 /*-----------------------------------------------------------------*/
7742 static void genRightShift (iCode *ic)
7743 {
7744     operand *right, *left, *result;
7745     sym_link *retype ;
7746     int size, offset;
7747     char *l;
7748     symbol *tlbl, *tlbl1 ;
7749
7750     /* if signed then we do it the hard way preserve the
7751     sign bit moving it inwards */
7752     retype = getSpec(operandType(IC_RESULT(ic)));
7753     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7754
7755     if (!SPEC_USIGN(retype)) {
7756         genSignedRightShift (ic);
7757         return ;
7758     }
7759
7760     /* signed & unsigned types are treated the same : i.e. the
7761     signed is NOT propagated inwards : quoting from the
7762     ANSI - standard : "for E1 >> E2, is equivalent to division
7763     by 2**E2 if unsigned or if it has a non-negative value,
7764     otherwise the result is implementation defined ", MY definition
7765     is that the sign does not get propagated */
7766
7767     right = IC_RIGHT(ic);
7768     left  = IC_LEFT(ic);
7769     result = IC_RESULT(ic);
7770
7771     pic16_aopOp(right,ic,FALSE);
7772
7773     /* if the shift count is known then do it 
7774     as efficiently as possible */
7775     if (AOP_TYPE(right) == AOP_LIT) {
7776         genRightShiftLiteral (left,right,result,ic, 0);
7777         return ;
7778     }
7779
7780     /* shift count is unknown then we have to form 
7781     a loop get the loop count in B : Note: we take
7782     only the lower order byte since shifting
7783     more that 32 bits make no sense anyway, ( the
7784     largest size of an object can be only 32 bits ) */  
7785
7786     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7787     pic16_emitcode("inc","b");
7788     pic16_aopOp(left,ic,FALSE);
7789     pic16_aopOp(result,ic,FALSE);
7790
7791     /* now move the left to the result if they are not the
7792     same */
7793     if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7794         AOP_SIZE(result) > 1) {
7795
7796         size = AOP_SIZE(result);
7797         offset=0;
7798         while (size--) {
7799             l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7800             if (*l == '@' && IS_AOP_PREG(result)) {
7801
7802                 pic16_emitcode("mov","a,%s",l);
7803                 pic16_aopPut(AOP(result),"a",offset);
7804             } else
7805                 pic16_aopPut(AOP(result),l,offset);
7806             offset++;
7807         }
7808     }
7809
7810     tlbl = newiTempLabel(NULL);
7811     tlbl1= newiTempLabel(NULL);
7812     size = AOP_SIZE(result);
7813     offset = size - 1;
7814
7815     /* if it is only one byte then */
7816     if (size == 1) {
7817
7818       tlbl = newiTempLabel(NULL);
7819       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7820         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7821         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7822       }
7823
7824       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7825       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7826       pic16_emitpLabel(tlbl->key);
7827       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7828       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7829       emitSKPC;
7830       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7831
7832       goto release ;
7833     }
7834
7835     reAdjustPreg(AOP(result));
7836     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7837     pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7838     CLRC;
7839     while (size--) {
7840         l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7841         MOVA(l);
7842         pic16_emitcode("rrc","a");         
7843         pic16_aopPut(AOP(result),"a",offset--);
7844     }
7845     reAdjustPreg(AOP(result));
7846
7847     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7848     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7849
7850 release:
7851     pic16_freeAsmop(left,NULL,ic,TRUE);
7852     pic16_freeAsmop (right,NULL,ic,TRUE);
7853     pic16_freeAsmop(result,NULL,ic,TRUE);
7854 }
7855
7856 /*-----------------------------------------------------------------*/
7857 /* genUnpackBits - generates code for unpacking bits               */
7858 /*-----------------------------------------------------------------*/
7859 static void genUnpackBits (operand *result, char *rname, int ptype)
7860 {    
7861     int shCnt ;
7862     int rlen = 0 ;
7863     sym_link *etype;
7864     int offset = 0 ;
7865
7866     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7867     etype = getSpec(operandType(result));
7868
7869     /* read the first byte  */
7870     switch (ptype) {
7871
7872     case POINTER:
7873     case IPOINTER:
7874         pic16_emitcode("mov","a,@%s",rname);
7875         break;
7876         
7877     case PPOINTER:
7878         pic16_emitcode("movx","a,@%s",rname);
7879         break;
7880         
7881     case FPOINTER:
7882         pic16_emitcode("movx","a,@dptr");
7883         break;
7884
7885     case CPOINTER:
7886         pic16_emitcode("clr","a");
7887         pic16_emitcode("movc","a","@a+dptr");
7888         break;
7889
7890     case GPOINTER:
7891         pic16_emitcode("lcall","__gptrget");
7892         break;
7893     }
7894
7895     /* if we have bitdisplacement then it fits   */
7896     /* into this byte completely or if length is */
7897     /* less than a byte                          */
7898     if ((shCnt = SPEC_BSTR(etype)) || 
7899         (SPEC_BLEN(etype) <= 8))  {
7900
7901         /* shift right acc */
7902         AccRsh(shCnt);
7903
7904         pic16_emitcode("anl","a,#0x%02x",
7905                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7906         pic16_aopPut(AOP(result),"a",offset);
7907         return ;
7908     }
7909
7910     /* bit field did not fit in a byte  */
7911     rlen = SPEC_BLEN(etype) - 8;
7912     pic16_aopPut(AOP(result),"a",offset++);
7913
7914     while (1)  {
7915
7916         switch (ptype) {
7917         case POINTER:
7918         case IPOINTER:
7919             pic16_emitcode("inc","%s",rname);
7920             pic16_emitcode("mov","a,@%s",rname);
7921             break;
7922             
7923         case PPOINTER:
7924             pic16_emitcode("inc","%s",rname);
7925             pic16_emitcode("movx","a,@%s",rname);
7926             break;
7927
7928         case FPOINTER:
7929             pic16_emitcode("inc","dptr");
7930             pic16_emitcode("movx","a,@dptr");
7931             break;
7932             
7933         case CPOINTER:
7934             pic16_emitcode("clr","a");
7935             pic16_emitcode("inc","dptr");
7936             pic16_emitcode("movc","a","@a+dptr");
7937             break;
7938             
7939         case GPOINTER:
7940             pic16_emitcode("inc","dptr");
7941             pic16_emitcode("lcall","__gptrget");
7942             break;
7943         }
7944
7945         rlen -= 8;            
7946         /* if we are done */
7947         if ( rlen <= 0 )
7948             break ;
7949         
7950         pic16_aopPut(AOP(result),"a",offset++);
7951                               
7952     }
7953     
7954     if (rlen) {
7955         pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7956         pic16_aopPut(AOP(result),"a",offset);          
7957     }
7958     
7959     return ;
7960 }
7961
7962 #if 0
7963 /*-----------------------------------------------------------------*/
7964 /* genDataPointerGet - generates code when ptr offset is known     */
7965 /*-----------------------------------------------------------------*/
7966 static void genDataPointerGet (operand *left, 
7967                                operand *result, 
7968                                iCode *ic)
7969 {
7970   int size , offset = 0;
7971
7972
7973   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7974
7975
7976   /* optimization - most of the time, left and result are the same
7977    * address, but different types. for the pic code, we could omit
7978    * the following
7979    */
7980
7981   pic16_aopOp(result,ic,TRUE);
7982
7983   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7984
7985   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7986
7987   size = AOP_SIZE(result);
7988
7989   while (size--) {
7990     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7991     offset++;
7992   }
7993
7994   pic16_freeAsmop(left,NULL,ic,TRUE);
7995   pic16_freeAsmop(result,NULL,ic,TRUE);
7996 }
7997 #endif
7998 /*-----------------------------------------------------------------*/
7999 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
8000 /*-----------------------------------------------------------------*/
8001 static void genNearPointerGet (operand *left, 
8002                                operand *result, 
8003                                iCode *ic)
8004 {
8005     asmop *aop = NULL;
8006     //regs *preg = NULL ;
8007     char *rname ;
8008     sym_link *rtype, *retype;
8009     sym_link *ltype = operandType(left);    
8010     //char buffer[80];
8011
8012     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8013
8014     rtype = operandType(result);
8015     retype= getSpec(rtype);
8016     
8017     pic16_aopOp(left,ic,FALSE);
8018     
8019     /* if left is rematerialisable and
8020        result is not bit variable type and
8021        the left is pointer to data space i.e
8022        lower 128 bytes of space */
8023     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8024         !IS_BITVAR(retype)         &&
8025         DCL_TYPE(ltype) == POINTER) {
8026       //genDataPointerGet (left,result,ic);
8027         return ;
8028     }
8029     
8030     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8031
8032         /* if the value is already in a pointer register
8033        then don't need anything more */
8034     if (!AOP_INPREG(AOP(left))) {
8035         /* otherwise get a free pointer register */
8036     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8037 /*
8038         aop = newAsmop(0);
8039         preg = getFreePtr(ic,&aop,FALSE);
8040         pic16_emitcode("mov","%s,%s",
8041                 preg->name,
8042                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8043         rname = preg->name ;
8044 */
8045     rname ="BAD";
8046     } else
8047         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8048     
8049     pic16_aopOp (result,ic,FALSE);
8050     
8051       /* if bitfield then unpack the bits */
8052     if (IS_BITVAR(retype)) 
8053         genUnpackBits (result,rname,POINTER);
8054     else {
8055         /* we have can just get the values */
8056       int size = AOP_SIZE(result);
8057       int offset = 0 ;  
8058         
8059       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8060
8061       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8062       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8063       while(size--) {
8064         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8065         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8066         if(size)
8067           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8068       }
8069 /*
8070         while (size--) {
8071             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8072
8073                 pic16_emitcode("mov","a,@%s",rname);
8074                 pic16_aopPut(AOP(result),"a",offset);
8075             } else {
8076                 sprintf(buffer,"@%s",rname);
8077                 pic16_aopPut(AOP(result),buffer,offset);
8078             }
8079             offset++ ;
8080             if (size)
8081                 pic16_emitcode("inc","%s",rname);
8082         }
8083 */
8084     }
8085
8086     /* now some housekeeping stuff */
8087     if (aop) {
8088         /* we had to allocate for this iCode */
8089     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8090         pic16_freeAsmop(NULL,aop,ic,TRUE);
8091     } else { 
8092         /* we did not allocate which means left
8093            already in a pointer register, then
8094            if size > 0 && this could be used again
8095            we have to point it back to where it 
8096            belongs */
8097     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8098         if (AOP_SIZE(result) > 1 &&
8099             !OP_SYMBOL(left)->remat &&
8100             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8101               ic->depth )) {
8102             int size = AOP_SIZE(result) - 1;
8103             while (size--)
8104                 pic16_emitcode("dec","%s",rname);
8105         }
8106     }
8107
8108     /* done */
8109     pic16_freeAsmop(left,NULL,ic,TRUE);
8110     pic16_freeAsmop(result,NULL,ic,TRUE);
8111      
8112 }
8113
8114 /*-----------------------------------------------------------------*/
8115 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
8116 /*-----------------------------------------------------------------*/
8117 static void genPagedPointerGet (operand *left, 
8118                                operand *result, 
8119                                iCode *ic)
8120 {
8121     asmop *aop = NULL;
8122     regs *preg = NULL ;
8123     char *rname ;
8124     sym_link *rtype, *retype;    
8125
8126     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8127
8128     rtype = operandType(result);
8129     retype= getSpec(rtype);
8130     
8131     pic16_aopOp(left,ic,FALSE);
8132
8133   /* if the value is already in a pointer register
8134        then don't need anything more */
8135     if (!AOP_INPREG(AOP(left))) {
8136         /* otherwise get a free pointer register */
8137         aop = newAsmop(0);
8138         preg = getFreePtr(ic,&aop,FALSE);
8139         pic16_emitcode("mov","%s,%s",
8140                 preg->name,
8141                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8142         rname = preg->name ;
8143     } else
8144         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8145     
8146     pic16_freeAsmop(left,NULL,ic,TRUE);
8147     pic16_aopOp (result,ic,FALSE);
8148
8149     /* if bitfield then unpack the bits */
8150     if (IS_BITVAR(retype)) 
8151         genUnpackBits (result,rname,PPOINTER);
8152     else {
8153         /* we have can just get the values */
8154         int size = AOP_SIZE(result);
8155         int offset = 0 ;        
8156         
8157         while (size--) {
8158             
8159             pic16_emitcode("movx","a,@%s",rname);
8160             pic16_aopPut(AOP(result),"a",offset);
8161             
8162             offset++ ;
8163             
8164             if (size)
8165                 pic16_emitcode("inc","%s",rname);
8166         }
8167     }
8168
8169     /* now some housekeeping stuff */
8170     if (aop) {
8171         /* we had to allocate for this iCode */
8172         pic16_freeAsmop(NULL,aop,ic,TRUE);
8173     } else { 
8174         /* we did not allocate which means left
8175            already in a pointer register, then
8176            if size > 0 && this could be used again
8177            we have to point it back to where it 
8178            belongs */
8179         if (AOP_SIZE(result) > 1 &&
8180             !OP_SYMBOL(left)->remat &&
8181             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8182               ic->depth )) {
8183             int size = AOP_SIZE(result) - 1;
8184             while (size--)
8185                 pic16_emitcode("dec","%s",rname);
8186         }
8187     }
8188
8189     /* done */
8190     pic16_freeAsmop(result,NULL,ic,TRUE);
8191     
8192         
8193 }
8194
8195 /*-----------------------------------------------------------------*/
8196 /* genFarPointerGet - gget value from far space                    */
8197 /*-----------------------------------------------------------------*/
8198 static void genFarPointerGet (operand *left,
8199                               operand *result, iCode *ic)
8200 {
8201     int size, offset ;
8202     sym_link *retype = getSpec(operandType(result));
8203
8204     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8205
8206     pic16_aopOp(left,ic,FALSE);
8207
8208     /* if the operand is already in dptr 
8209     then we do nothing else we move the value to dptr */
8210     if (AOP_TYPE(left) != AOP_STR) {
8211         /* if this is remateriazable */
8212         if (AOP_TYPE(left) == AOP_IMMD)
8213             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8214         else { /* we need to get it byte by byte */
8215             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8216             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8217             if (options.model == MODEL_FLAT24)
8218             {
8219                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8220             }
8221         }
8222     }
8223     /* so dptr know contains the address */
8224     pic16_freeAsmop(left,NULL,ic,TRUE);
8225     pic16_aopOp(result,ic,FALSE);
8226
8227     /* if bit then unpack */
8228     if (IS_BITVAR(retype)) 
8229         genUnpackBits(result,"dptr",FPOINTER);
8230     else {
8231         size = AOP_SIZE(result);
8232         offset = 0 ;
8233
8234         while (size--) {
8235             pic16_emitcode("movx","a,@dptr");
8236             pic16_aopPut(AOP(result),"a",offset++);
8237             if (size)
8238                 pic16_emitcode("inc","dptr");
8239         }
8240     }
8241
8242     pic16_freeAsmop(result,NULL,ic,TRUE);
8243 }
8244 #if 0
8245 /*-----------------------------------------------------------------*/
8246 /* genCodePointerGet - get value from code space                  */
8247 /*-----------------------------------------------------------------*/
8248 static void genCodePointerGet (operand *left,
8249                                 operand *result, iCode *ic)
8250 {
8251     int size, offset ;
8252     sym_link *retype = getSpec(operandType(result));
8253
8254     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8255
8256     pic16_aopOp(left,ic,FALSE);
8257
8258     /* if the operand is already in dptr 
8259     then we do nothing else we move the value to dptr */
8260     if (AOP_TYPE(left) != AOP_STR) {
8261         /* if this is remateriazable */
8262         if (AOP_TYPE(left) == AOP_IMMD)
8263             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8264         else { /* we need to get it byte by byte */
8265             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8266             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8267             if (options.model == MODEL_FLAT24)
8268             {
8269                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8270             }
8271         }
8272     }
8273     /* so dptr know contains the address */
8274     pic16_freeAsmop(left,NULL,ic,TRUE);
8275     pic16_aopOp(result,ic,FALSE);
8276
8277     /* if bit then unpack */
8278     if (IS_BITVAR(retype)) 
8279         genUnpackBits(result,"dptr",CPOINTER);
8280     else {
8281         size = AOP_SIZE(result);
8282         offset = 0 ;
8283
8284         while (size--) {
8285             pic16_emitcode("clr","a");
8286             pic16_emitcode("movc","a,@a+dptr");
8287             pic16_aopPut(AOP(result),"a",offset++);
8288             if (size)
8289                 pic16_emitcode("inc","dptr");
8290         }
8291     }
8292
8293     pic16_freeAsmop(result,NULL,ic,TRUE);
8294 }
8295 #endif
8296 /*-----------------------------------------------------------------*/
8297 /* genGenPointerGet - gget value from generic pointer space        */
8298 /*-----------------------------------------------------------------*/
8299 static void genGenPointerGet (operand *left,
8300                               operand *result, iCode *ic)
8301 {
8302   int size, offset ;
8303   sym_link *retype = getSpec(operandType(result));
8304
8305   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8306   pic16_aopOp(left,ic,FALSE);
8307   pic16_aopOp(result,ic,FALSE);
8308
8309
8310   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8311
8312   /* if the operand is already in dptr 
8313      then we do nothing else we move the value to dptr */
8314   //  if (AOP_TYPE(left) != AOP_STR) {
8315     /* if this is remateriazable */
8316     if (AOP_TYPE(left) == AOP_IMMD) {
8317       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8318       pic16_emitcode("mov","b,#%d",pointerCode(retype));
8319     }
8320     else { /* we need to get it byte by byte */
8321
8322       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8323       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8324
8325       size = AOP_SIZE(result);
8326       offset = 0 ;
8327
8328       while(size--) {
8329         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8330         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8331         if(size)
8332           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8333       }
8334       goto release;
8335     }
8336     //}
8337   /* so dptr know contains the address */
8338
8339   /* if bit then unpack */
8340   //if (IS_BITVAR(retype)) 
8341   //  genUnpackBits(result,"dptr",GPOINTER);
8342
8343  release:
8344   pic16_freeAsmop(left,NULL,ic,TRUE);
8345   pic16_freeAsmop(result,NULL,ic,TRUE);
8346
8347 }
8348
8349 /*-----------------------------------------------------------------*/
8350 /* genConstPointerGet - get value from const generic pointer space */
8351 /*-----------------------------------------------------------------*/
8352 static void genConstPointerGet (operand *left,
8353                                 operand *result, iCode *ic)
8354 {
8355   //sym_link *retype = getSpec(operandType(result));
8356   symbol *albl = newiTempLabel(NULL);
8357   symbol *blbl = newiTempLabel(NULL);
8358   PIC_OPCODE poc;
8359
8360   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8361   pic16_aopOp(left,ic,FALSE);
8362   pic16_aopOp(result,ic,FALSE);
8363
8364
8365   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8366
8367   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8368
8369   pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8370   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8371   pic16_emitpLabel(albl->key);
8372
8373   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8374     
8375   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8376   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8377   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8378   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8379
8380   pic16_emitpLabel(blbl->key);
8381
8382   pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8383
8384
8385   pic16_freeAsmop(left,NULL,ic,TRUE);
8386   pic16_freeAsmop(result,NULL,ic,TRUE);
8387
8388 }
8389 /*-----------------------------------------------------------------*/
8390 /* genPointerGet - generate code for pointer get                   */
8391 /*-----------------------------------------------------------------*/
8392 static void genPointerGet (iCode *ic)
8393 {
8394     operand *left, *result ;
8395     sym_link *type, *etype;
8396     int p_type;
8397
8398     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8399
8400     left = IC_LEFT(ic);
8401     result = IC_RESULT(ic) ;
8402
8403     /* depending on the type of pointer we need to
8404     move it to the correct pointer register */
8405     type = operandType(left);
8406     etype = getSpec(type);
8407
8408     if (IS_PTR_CONST(type))
8409       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8410
8411     /* if left is of type of pointer then it is simple */
8412     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8413         p_type = DCL_TYPE(type);
8414     else {
8415         /* we have to go by the storage class */
8416         p_type = PTR_TYPE(SPEC_OCLS(etype));
8417
8418         DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8419
8420         if (SPEC_OCLS(etype)->codesp ) {
8421           DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8422           //p_type = CPOINTER ; 
8423         }
8424         else
8425             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8426               DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8427                /*p_type = FPOINTER ;*/ 
8428             else
8429                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8430                   DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8431 /*                  p_type = PPOINTER; */
8432                 else
8433                     if (SPEC_OCLS(etype) == idata )
8434                       DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8435 /*                      p_type = IPOINTER; */
8436                     else
8437                       DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8438 /*                      p_type = POINTER ; */
8439     }
8440
8441     /* now that we have the pointer type we assign
8442     the pointer values */
8443     switch (p_type) {
8444
8445     case POINTER:       
8446     case IPOINTER:
8447         genNearPointerGet (left,result,ic);
8448         break;
8449
8450     case PPOINTER:
8451         genPagedPointerGet(left,result,ic);
8452         break;
8453
8454     case FPOINTER:
8455         genFarPointerGet (left,result,ic);
8456         break;
8457
8458     case CPOINTER:
8459         genConstPointerGet (left,result,ic);
8460         //pic16_emitcodePointerGet (left,result,ic);
8461         break;
8462
8463     case GPOINTER:
8464       if (IS_PTR_CONST(type))
8465         genConstPointerGet (left,result,ic);
8466       else
8467         genGenPointerGet (left,result,ic);
8468       break;
8469     }
8470
8471 }
8472
8473 /*-----------------------------------------------------------------*/
8474 /* genPackBits - generates code for packed bit storage             */
8475 /*-----------------------------------------------------------------*/
8476 static void genPackBits (sym_link    *etype ,
8477                          operand *right ,
8478                          char *rname, int p_type)
8479 {
8480     int shCount = 0 ;
8481     int offset = 0  ;
8482     int rLen = 0 ;
8483     int blen, bstr ;   
8484     char *l ;
8485
8486     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8487     blen = SPEC_BLEN(etype);
8488     bstr = SPEC_BSTR(etype);
8489
8490     l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8491     MOVA(l);   
8492
8493     /* if the bit lenth is less than or    */
8494     /* it exactly fits a byte then         */
8495     if (SPEC_BLEN(etype) <= 8 )  {
8496         shCount = SPEC_BSTR(etype) ;
8497
8498         /* shift left acc */
8499         AccLsh(shCount);
8500
8501         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8502
8503
8504             switch (p_type) {
8505                 case POINTER:
8506                     pic16_emitcode ("mov","b,a");
8507                     pic16_emitcode("mov","a,@%s",rname);
8508                     break;
8509
8510                 case FPOINTER:
8511                     pic16_emitcode ("mov","b,a");
8512                     pic16_emitcode("movx","a,@dptr");
8513                     break;
8514
8515                 case GPOINTER:
8516                     pic16_emitcode ("push","b");
8517                     pic16_emitcode ("push","acc");
8518                     pic16_emitcode ("lcall","__gptrget");
8519                     pic16_emitcode ("pop","b");
8520                     break;
8521             }
8522
8523             pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8524                       ((unsigned char)(0xFF << (blen+bstr)) | 
8525                        (unsigned char)(0xFF >> (8-bstr)) ) );
8526             pic16_emitcode ("orl","a,b");
8527             if (p_type == GPOINTER)
8528                 pic16_emitcode("pop","b");
8529         }
8530     }
8531
8532     switch (p_type) {
8533         case POINTER:
8534             pic16_emitcode("mov","@%s,a",rname);
8535             break;
8536
8537         case FPOINTER:
8538             pic16_emitcode("movx","@dptr,a");
8539             break;
8540
8541         case GPOINTER:
8542             DEBUGpic16_emitcode(";lcall","__gptrput");
8543             break;
8544     }
8545
8546     /* if we r done */
8547     if ( SPEC_BLEN(etype) <= 8 )
8548         return ;
8549
8550     pic16_emitcode("inc","%s",rname);
8551     rLen = SPEC_BLEN(etype) ;     
8552
8553     /* now generate for lengths greater than one byte */
8554     while (1) {
8555
8556         l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8557
8558         rLen -= 8 ;
8559         if (rLen <= 0 )
8560             break ;
8561
8562         switch (p_type) {
8563             case POINTER:
8564                 if (*l == '@') {
8565                     MOVA(l);
8566                     pic16_emitcode("mov","@%s,a",rname);
8567                 } else
8568                     pic16_emitcode("mov","@%s,%s",rname,l);
8569                 break;
8570
8571             case FPOINTER:
8572                 MOVA(l);
8573                 pic16_emitcode("movx","@dptr,a");
8574                 break;
8575
8576             case GPOINTER:
8577                 MOVA(l);
8578                 DEBUGpic16_emitcode(";lcall","__gptrput");
8579                 break;  
8580         }   
8581         pic16_emitcode ("inc","%s",rname);
8582     }
8583
8584     MOVA(l);
8585
8586     /* last last was not complete */
8587     if (rLen)   {
8588         /* save the byte & read byte */
8589         switch (p_type) {
8590             case POINTER:
8591                 pic16_emitcode ("mov","b,a");
8592                 pic16_emitcode("mov","a,@%s",rname);
8593                 break;
8594
8595             case FPOINTER:
8596                 pic16_emitcode ("mov","b,a");
8597                 pic16_emitcode("movx","a,@dptr");
8598                 break;
8599
8600             case GPOINTER:
8601                 pic16_emitcode ("push","b");
8602                 pic16_emitcode ("push","acc");
8603                 pic16_emitcode ("lcall","__gptrget");
8604                 pic16_emitcode ("pop","b");
8605                 break;
8606         }
8607
8608         pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8609         pic16_emitcode ("orl","a,b");
8610     }
8611
8612     if (p_type == GPOINTER)
8613         pic16_emitcode("pop","b");
8614
8615     switch (p_type) {
8616
8617     case POINTER:
8618         pic16_emitcode("mov","@%s,a",rname);
8619         break;
8620         
8621     case FPOINTER:
8622         pic16_emitcode("movx","@dptr,a");
8623         break;
8624         
8625     case GPOINTER:
8626         DEBUGpic16_emitcode(";lcall","__gptrput");
8627         break;                  
8628     }
8629 }
8630 /*-----------------------------------------------------------------*/
8631 /* genDataPointerSet - remat pointer to data space                 */
8632 /*-----------------------------------------------------------------*/
8633 static void genDataPointerSet(operand *right,
8634                               operand *result,
8635                               iCode *ic)
8636 {
8637     int size, offset = 0 ;
8638     char *l, buffer[256];
8639
8640     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8641     pic16_aopOp(right,ic,FALSE);
8642     
8643     l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8644     size = AOP_SIZE(right);
8645 /*
8646     if ( AOP_TYPE(result) == AOP_PCODE) {
8647       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8648               AOP(result)->aopu.pcop->name,
8649               PCOI(AOP(result)->aopu.pcop)->offset);
8650     }
8651 */
8652
8653     // tsd, was l+1 - the underline `_' prefix was being stripped
8654     while (size--) {
8655       if (offset) {
8656         sprintf(buffer,"(%s + %d)",l,offset);
8657         fprintf(stderr,"oops  %s\n",buffer);
8658       } else
8659         sprintf(buffer,"%s",l);
8660
8661         if (AOP_TYPE(right) == AOP_LIT) {
8662           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8663           lit = lit >> (8*offset);
8664           if(lit&0xff) {
8665             pic16_emitcode("movlw","%d",lit);
8666             pic16_emitcode("movwf","%s",buffer);
8667
8668             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8669             //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8670             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8671
8672           } else {
8673             pic16_emitcode("clrf","%s",buffer);
8674             //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8675             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8676           }
8677         }else {
8678           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8679           pic16_emitcode("movwf","%s",buffer);
8680
8681           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8682           //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8683           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8684
8685         }
8686
8687         offset++;
8688     }
8689
8690     pic16_freeAsmop(right,NULL,ic,TRUE);
8691     pic16_freeAsmop(result,NULL,ic,TRUE);
8692 }
8693
8694 /*-----------------------------------------------------------------*/
8695 /* genNearPointerSet - pic16_emitcode for near pointer put                */
8696 /*-----------------------------------------------------------------*/
8697 static void genNearPointerSet (operand *right,
8698                                operand *result, 
8699                                iCode *ic)
8700 {
8701   asmop *aop = NULL;
8702   char *l;
8703   sym_link *retype;
8704   sym_link *ptype = operandType(result);
8705
8706     
8707   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8708   retype= getSpec(operandType(right));
8709
8710   pic16_aopOp(result,ic,FALSE);
8711
8712     
8713   /* if the result is rematerializable &
8714      in data space & not a bit variable */
8715   //if (AOP_TYPE(result) == AOP_IMMD &&
8716   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8717       DCL_TYPE(ptype) == POINTER   &&
8718       !IS_BITVAR(retype)) {
8719     genDataPointerSet (right,result,ic);
8720     pic16_freeAsmop(result,NULL,ic,TRUE);
8721     return;
8722   }
8723
8724   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8725   pic16_aopOp(right,ic,FALSE);
8726   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8727
8728   /* if the value is already in a pointer register
8729      then don't need anything more */
8730   if (!AOP_INPREG(AOP(result))) {
8731     /* otherwise get a free pointer register */
8732     //aop = newAsmop(0);
8733     //preg = getFreePtr(ic,&aop,FALSE);
8734     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8735     //pic16_emitcode("mov","%s,%s",
8736     //         preg->name,
8737     //         pic16_aopGet(AOP(result),0,FALSE,TRUE));
8738     //rname = preg->name ;
8739     //pic16_emitcode("movwf","fsr0");
8740     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8741     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8742     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8743     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8744     goto release;
8745
8746   }// else
8747   //   rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8748
8749
8750   /* if bitfield then unpack the bits */
8751   if (IS_BITVAR(retype)) {
8752     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8753            "The programmer is obviously confused");
8754     //genPackBits (retype,right,rname,POINTER);
8755     exit(1);
8756   }
8757   else {
8758     /* we have can just get the values */
8759     int size = AOP_SIZE(right);
8760     int offset = 0 ;    
8761
8762     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8763     while (size--) {
8764       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8765       if (*l == '@' ) {
8766         //MOVA(l);
8767         //pic16_emitcode("mov","@%s,a",rname);
8768         pic16_emitcode("movf","indf0,w ;1");
8769       } else {
8770
8771         if (AOP_TYPE(right) == AOP_LIT) {
8772           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8773           if(lit) {
8774             pic16_emitcode("movlw","%s",l);
8775             pic16_emitcode("movwf","indf0 ;2");
8776           } else 
8777             pic16_emitcode("clrf","indf0");
8778         }else {
8779           pic16_emitcode("movf","%s,w",l);
8780           pic16_emitcode("movwf","indf0 ;2");
8781         }
8782         //pic16_emitcode("mov","@%s,%s",rname,l);
8783       }
8784       if (size)
8785         pic16_emitcode("incf","fsr0,f ;3");
8786       //pic16_emitcode("inc","%s",rname);
8787       offset++;
8788     }
8789   }
8790
8791   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8792   /* now some housekeeping stuff */
8793   if (aop) {
8794     /* we had to allocate for this iCode */
8795     pic16_freeAsmop(NULL,aop,ic,TRUE);
8796   } else { 
8797     /* we did not allocate which means left
8798        already in a pointer register, then
8799        if size > 0 && this could be used again
8800        we have to point it back to where it 
8801        belongs */
8802     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8803     if (AOP_SIZE(right) > 1 &&
8804         !OP_SYMBOL(result)->remat &&
8805         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8806           ic->depth )) {
8807       int size = AOP_SIZE(right) - 1;
8808       while (size--)
8809         pic16_emitcode("decf","fsr0,f");
8810       //pic16_emitcode("dec","%s",rname);
8811     }
8812   }
8813
8814   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8815   /* done */
8816  release:
8817   pic16_freeAsmop(right,NULL,ic,TRUE);
8818   pic16_freeAsmop(result,NULL,ic,TRUE);
8819 }
8820
8821 /*-----------------------------------------------------------------*/
8822 /* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
8823 /*-----------------------------------------------------------------*/
8824 static void genPagedPointerSet (operand *right,
8825                                operand *result, 
8826                                iCode *ic)
8827 {
8828     asmop *aop = NULL;
8829     regs *preg = NULL ;
8830     char *rname , *l;
8831     sym_link *retype;
8832        
8833     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8834
8835     retype= getSpec(operandType(right));
8836     
8837     pic16_aopOp(result,ic,FALSE);
8838     
8839     /* if the value is already in a pointer register
8840        then don't need anything more */
8841     if (!AOP_INPREG(AOP(result))) {
8842         /* otherwise get a free pointer register */
8843         aop = newAsmop(0);
8844         preg = getFreePtr(ic,&aop,FALSE);
8845         pic16_emitcode("mov","%s,%s",
8846                 preg->name,
8847                 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8848         rname = preg->name ;
8849     } else
8850         rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8851     
8852     pic16_freeAsmop(result,NULL,ic,TRUE);
8853     pic16_aopOp (right,ic,FALSE);
8854
8855     /* if bitfield then unpack the bits */
8856     if (IS_BITVAR(retype)) 
8857         genPackBits (retype,right,rname,PPOINTER);
8858     else {
8859         /* we have can just get the values */
8860         int size = AOP_SIZE(right);
8861         int offset = 0 ;        
8862         
8863         while (size--) {
8864             l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8865             
8866             MOVA(l);
8867             pic16_emitcode("movx","@%s,a",rname);
8868
8869             if (size)
8870                 pic16_emitcode("inc","%s",rname);
8871
8872             offset++;
8873         }
8874     }
8875     
8876     /* now some housekeeping stuff */
8877     if (aop) {
8878         /* we had to allocate for this iCode */
8879         pic16_freeAsmop(NULL,aop,ic,TRUE);
8880     } else { 
8881         /* we did not allocate which means left
8882            already in a pointer register, then
8883            if size > 0 && this could be used again
8884            we have to point it back to where it 
8885            belongs */
8886         if (AOP_SIZE(right) > 1 &&
8887             !OP_SYMBOL(result)->remat &&
8888             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8889               ic->depth )) {
8890             int size = AOP_SIZE(right) - 1;
8891             while (size--)
8892                 pic16_emitcode("dec","%s",rname);
8893         }
8894     }
8895
8896     /* done */
8897     pic16_freeAsmop(right,NULL,ic,TRUE);
8898     
8899         
8900 }
8901
8902 /*-----------------------------------------------------------------*/
8903 /* genFarPointerSet - set value from far space                     */
8904 /*-----------------------------------------------------------------*/
8905 static void genFarPointerSet (operand *right,
8906                               operand *result, iCode *ic)
8907 {
8908     int size, offset ;
8909     sym_link *retype = getSpec(operandType(right));
8910
8911     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8912     pic16_aopOp(result,ic,FALSE);
8913
8914     /* if the operand is already in dptr 
8915     then we do nothing else we move the value to dptr */
8916     if (AOP_TYPE(result) != AOP_STR) {
8917         /* if this is remateriazable */
8918         if (AOP_TYPE(result) == AOP_IMMD)
8919             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8920         else { /* we need to get it byte by byte */
8921             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8922             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8923             if (options.model == MODEL_FLAT24)
8924             {
8925                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8926             }
8927         }
8928     }
8929     /* so dptr know contains the address */
8930     pic16_freeAsmop(result,NULL,ic,TRUE);
8931     pic16_aopOp(right,ic,FALSE);
8932
8933     /* if bit then unpack */
8934     if (IS_BITVAR(retype)) 
8935         genPackBits(retype,right,"dptr",FPOINTER);
8936     else {
8937         size = AOP_SIZE(right);
8938         offset = 0 ;
8939
8940         while (size--) {
8941             char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8942             MOVA(l);
8943             pic16_emitcode("movx","@dptr,a");
8944             if (size)
8945                 pic16_emitcode("inc","dptr");
8946         }
8947     }
8948
8949     pic16_freeAsmop(right,NULL,ic,TRUE);
8950 }
8951
8952 /*-----------------------------------------------------------------*/
8953 /* genGenPointerSet - set value from generic pointer space         */
8954 /*-----------------------------------------------------------------*/
8955 static void genGenPointerSet (operand *right,
8956                               operand *result, iCode *ic)
8957 {
8958   int size, offset ;
8959   sym_link *retype = getSpec(operandType(right));
8960
8961   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8962
8963   pic16_aopOp(result,ic,FALSE);
8964   pic16_aopOp(right,ic,FALSE);
8965   size = AOP_SIZE(right);
8966
8967   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8968
8969   /* if the operand is already in dptr 
8970      then we do nothing else we move the value to dptr */
8971   if (AOP_TYPE(result) != AOP_STR) {
8972     /* if this is remateriazable */
8973     if (AOP_TYPE(result) == AOP_IMMD) {
8974       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8975       pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8976     }
8977     else { /* we need to get it byte by byte */
8978       //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8979       size = AOP_SIZE(right);
8980       offset = 0 ;
8981
8982       /* hack hack! see if this the FSR. If so don't load W */
8983       if(AOP_TYPE(right) != AOP_ACC) {
8984
8985
8986         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8987         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8988
8989         if(AOP_SIZE(result) > 1) {
8990           pic16_emitpcode(POC_BCF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8991           pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8992           pic16_emitpcode(POC_BSF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8993
8994         }
8995
8996         //if(size==2)
8997         //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8998         //if(size==4) {
8999         //  pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9000         //  pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9001         //}
9002
9003         while(size--) {
9004           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9005           pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9006           
9007           if(size)
9008             pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9009         }
9010
9011
9012         goto release;
9013       } 
9014
9015       if(aopIdx(AOP(result),0) != 4) {
9016
9017         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9018         goto release;
9019       }
9020
9021       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9022       goto release;
9023
9024     }
9025   }
9026   /* so dptr know contains the address */
9027
9028
9029   /* if bit then unpack */
9030   if (IS_BITVAR(retype)) 
9031     genPackBits(retype,right,"dptr",GPOINTER);
9032   else {
9033     size = AOP_SIZE(right);
9034     offset = 0 ;
9035
9036   DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9037
9038     while (size--) {
9039
9040       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9041       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9042
9043       if (AOP_TYPE(right) == AOP_LIT) 
9044         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9045       else
9046         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9047
9048       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9049
9050       offset++;
9051     }
9052   }
9053
9054  release:
9055   pic16_freeAsmop(right,NULL,ic,TRUE);
9056   pic16_freeAsmop(result,NULL,ic,TRUE);
9057 }
9058
9059 /*-----------------------------------------------------------------*/
9060 /* genPointerSet - stores the value into a pointer location        */
9061 /*-----------------------------------------------------------------*/
9062 static void genPointerSet (iCode *ic)
9063 {    
9064     operand *right, *result ;
9065     sym_link *type, *etype;
9066     int p_type;
9067
9068     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9069
9070     right = IC_RIGHT(ic);
9071     result = IC_RESULT(ic) ;
9072
9073     /* depending on the type of pointer we need to
9074     move it to the correct pointer register */
9075     type = operandType(result);
9076     etype = getSpec(type);
9077     /* if left is of type of pointer then it is simple */
9078     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9079         p_type = DCL_TYPE(type);
9080     }
9081     else {
9082         /* we have to go by the storage class */
9083         p_type = PTR_TYPE(SPEC_OCLS(etype));
9084
9085 /*      if (SPEC_OCLS(etype)->codesp ) { */
9086 /*          p_type = CPOINTER ;  */
9087 /*      } */
9088 /*      else */
9089 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9090 /*              p_type = FPOINTER ; */
9091 /*          else */
9092 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9093 /*                  p_type = PPOINTER ; */
9094 /*              else */
9095 /*                  if (SPEC_OCLS(etype) == idata ) */
9096 /*                      p_type = IPOINTER ; */
9097 /*                  else */
9098 /*                      p_type = POINTER ; */
9099     }
9100
9101     /* now that we have the pointer type we assign
9102     the pointer values */
9103     switch (p_type) {
9104
9105     case POINTER:
9106     case IPOINTER:
9107         genNearPointerSet (right,result,ic);
9108         break;
9109
9110     case PPOINTER:
9111         genPagedPointerSet (right,result,ic);
9112         break;
9113
9114     case FPOINTER:
9115         genFarPointerSet (right,result,ic);
9116         break;
9117
9118     case GPOINTER:
9119         genGenPointerSet (right,result,ic);
9120         break;
9121
9122     default:
9123       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9124               "genPointerSet: illegal pointer type");
9125     }
9126 }
9127
9128 /*-----------------------------------------------------------------*/
9129 /* genIfx - generate code for Ifx statement                        */
9130 /*-----------------------------------------------------------------*/
9131 static void genIfx (iCode *ic, iCode *popIc)
9132 {
9133   operand *cond = IC_COND(ic);
9134   int isbit =0;
9135
9136   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9137
9138   pic16_aopOp(cond,ic,FALSE);
9139
9140   /* get the value into acc */
9141   if (AOP_TYPE(cond) != AOP_CRY)
9142     pic16_toBoolean(cond);
9143   else
9144     isbit = 1;
9145   /* the result is now in the accumulator */
9146   pic16_freeAsmop(cond,NULL,ic,TRUE);
9147
9148   /* if there was something to be popped then do it */
9149   if (popIc)
9150     genIpop(popIc);
9151
9152   /* if the condition is  a bit variable */
9153   if (isbit && IS_ITEMP(cond) && 
9154       SPIL_LOC(cond)) {
9155     genIfxJump(ic,SPIL_LOC(cond)->rname);
9156     DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9157   }
9158   else {
9159     if (isbit && !IS_ITEMP(cond))
9160       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9161     else
9162       genIfxJump(ic,"a");
9163   }
9164   ic->generated = 1;
9165
9166 }
9167
9168 /*-----------------------------------------------------------------*/
9169 /* genAddrOf - generates code for address of                       */
9170 /*-----------------------------------------------------------------*/
9171 static void genAddrOf (iCode *ic)
9172 {
9173   operand *right, *result, *left;
9174   int size, offset ;
9175
9176   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9177
9178
9179   //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9180
9181   pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9182   pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9183   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9184
9185   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9186
9187   size = AOP_SIZE(IC_RESULT(ic));
9188   offset = 0;
9189
9190   while (size--) {
9191     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9192     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9193     offset++;
9194   }
9195
9196   pic16_freeAsmop(left,NULL,ic,FALSE);
9197   pic16_freeAsmop(result,NULL,ic,TRUE);
9198
9199 }
9200
9201 #if 0
9202 /*-----------------------------------------------------------------*/
9203 /* genFarFarAssign - assignment when both are in far space         */
9204 /*-----------------------------------------------------------------*/
9205 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9206 {
9207     int size = AOP_SIZE(right);
9208     int offset = 0;
9209     char *l ;
9210     /* first push the right side on to the stack */
9211     while (size--) {
9212         l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9213         MOVA(l);
9214         pic16_emitcode ("push","acc");
9215     }
9216     
9217     pic16_freeAsmop(right,NULL,ic,FALSE);
9218     /* now assign DPTR to result */
9219     pic16_aopOp(result,ic,FALSE);
9220     size = AOP_SIZE(result);
9221     while (size--) {
9222         pic16_emitcode ("pop","acc");
9223         pic16_aopPut(AOP(result),"a",--offset);
9224     }
9225     pic16_freeAsmop(result,NULL,ic,FALSE);
9226         
9227 }
9228 #endif
9229
9230 /*-----------------------------------------------------------------*/
9231 /* genAssign - generate code for assignment                        */
9232 /*-----------------------------------------------------------------*/
9233 static void genAssign (iCode *ic)
9234 {
9235   operand *result, *right;
9236   int size, offset,know_W;
9237   unsigned long lit = 0L;
9238
9239   result = IC_RESULT(ic);
9240   right  = IC_RIGHT(ic) ;
9241
9242   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9243
9244   /* if they are the same */
9245   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9246     return ;
9247
9248   pic16_aopOp(right,ic,FALSE);
9249   pic16_aopOp(result,ic,TRUE);
9250
9251   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9252
9253   /* if they are the same registers */
9254   if (pic16_sameRegs(AOP(right),AOP(result)))
9255     goto release;
9256
9257   /* if the result is a bit */
9258   if (AOP_TYPE(result) == AOP_CRY) {
9259
9260     /* if the right size is a literal then
9261        we know what the value is */
9262     if (AOP_TYPE(right) == AOP_LIT) {
9263           
9264       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9265                   pic16_popGet(AOP(result),0));
9266
9267       if (((int) operandLitValue(right))) 
9268         pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9269                        AOP(result)->aopu.aop_dir,
9270                        AOP(result)->aopu.aop_dir);
9271       else
9272         pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9273                        AOP(result)->aopu.aop_dir,
9274                        AOP(result)->aopu.aop_dir);
9275       goto release;
9276     }
9277
9278     /* the right is also a bit variable */
9279     if (AOP_TYPE(right) == AOP_CRY) {
9280       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9281       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9282       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9283
9284       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9285                      AOP(result)->aopu.aop_dir,
9286                      AOP(result)->aopu.aop_dir);
9287       pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9288                      AOP(right)->aopu.aop_dir,
9289                      AOP(right)->aopu.aop_dir);
9290       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9291                      AOP(result)->aopu.aop_dir,
9292                      AOP(result)->aopu.aop_dir);
9293       goto release ;
9294     }
9295
9296     /* we need to or */
9297     pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9298     pic16_toBoolean(right);
9299     emitSKPZ;
9300     pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9301     //pic16_aopPut(AOP(result),"a",0);
9302     goto release ;
9303   }
9304
9305   /* bit variables done */
9306   /* general case */
9307   size = AOP_SIZE(result);
9308   offset = 0 ;
9309   if(AOP_TYPE(right) == AOP_LIT)
9310     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9311
9312   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9313   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9314     if(aopIdx(AOP(result),0) == 4) {
9315   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9316       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9317       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9318       goto release;
9319     } else
9320       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9321   }
9322
9323   know_W=-1;
9324   while (size--) {
9325   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9326     if(AOP_TYPE(right) == AOP_LIT) {
9327       if(lit&0xff) {
9328         if(know_W != (lit&0xff))
9329           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9330         know_W = lit&0xff;
9331         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9332       } else
9333         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9334
9335       lit >>= 8;
9336
9337     } else if (AOP_TYPE(right) == AOP_CRY) {
9338       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9339       if(offset == 0) {
9340         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9341         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9342       }
9343     } else {
9344   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9345       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9346       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9347     }
9348             
9349     offset++;
9350   }
9351
9352     
9353  release:
9354   pic16_freeAsmop (right,NULL,ic,FALSE);
9355   pic16_freeAsmop (result,NULL,ic,TRUE);
9356 }   
9357
9358 /*-----------------------------------------------------------------*/
9359 /* genJumpTab - genrates code for jump table                       */
9360 /*-----------------------------------------------------------------*/
9361 static void genJumpTab (iCode *ic)
9362 {
9363     symbol *jtab;
9364     char *l;
9365
9366     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9367
9368     pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9369     /* get the condition into accumulator */
9370     l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9371     MOVA(l);
9372     /* multiply by three */
9373     pic16_emitcode("add","a,acc");
9374     pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9375
9376     jtab = newiTempLabel(NULL);
9377     pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9378     pic16_emitcode("jmp","@a+dptr");
9379     pic16_emitcode("","%05d_DS_:",jtab->key+100);
9380
9381     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9382     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9383     emitSKPNC;
9384     pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9385     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9386     pic16_emitpLabel(jtab->key);
9387
9388     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9389
9390     /* now generate the jump labels */
9391     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9392          jtab = setNextItem(IC_JTLABELS(ic))) {
9393         pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9394         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9395         
9396     }
9397
9398 }
9399
9400 /*-----------------------------------------------------------------*/
9401 /* genMixedOperation - gen code for operators between mixed types  */
9402 /*-----------------------------------------------------------------*/
9403 /*
9404   TSD - Written for the PIC port - but this unfortunately is buggy.
9405   This routine is good in that it is able to efficiently promote 
9406   types to different (larger) sizes. Unfortunately, the temporary
9407   variables that are optimized out by this routine are sometimes
9408   used in other places. So until I know how to really parse the 
9409   iCode tree, I'm going to not be using this routine :(.
9410 */
9411 static int genMixedOperation (iCode *ic)
9412 {
9413 #if 0
9414   operand *result = IC_RESULT(ic);
9415   sym_link *ctype = operandType(IC_LEFT(ic));
9416   operand *right = IC_RIGHT(ic);
9417   int ret = 0;
9418   int big,small;
9419   int offset;
9420
9421   iCode *nextic;
9422   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9423
9424   pic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9425
9426   nextic = ic->next;
9427   if(!nextic)
9428     return 0;
9429
9430   nextright = IC_RIGHT(nextic);
9431   nextleft  = IC_LEFT(nextic);
9432   nextresult = IC_RESULT(nextic);
9433
9434   pic16_aopOp(right,ic,FALSE);
9435   pic16_aopOp(result,ic,FALSE);
9436   pic16_aopOp(nextright,  nextic, FALSE);
9437   pic16_aopOp(nextleft,   nextic, FALSE);
9438   pic16_aopOp(nextresult, nextic, FALSE);
9439
9440   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9441
9442     operand *t = right;
9443     right = nextright;
9444     nextright = t; 
9445
9446     pic16_emitcode(";remove right +","");
9447
9448   } else   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9449 /*
9450     operand *t = right;
9451     right = nextleft;
9452     nextleft = t; 
9453 */
9454     pic16_emitcode(";remove left +","");
9455   } else
9456     return 0;
9457
9458   big = AOP_SIZE(nextleft);
9459   small = AOP_SIZE(nextright);
9460
9461   switch(nextic->op) {
9462
9463   case '+':
9464     pic16_emitcode(";optimize a +","");
9465     /* if unsigned or not an integral type */
9466     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9467       pic16_emitcode(";add a bit to something","");
9468     } else {
9469
9470       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9471
9472       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9473         pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9474         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9475       } else
9476         pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9477
9478       offset = 0;
9479       while(--big) {
9480
9481         offset++;
9482
9483         if(--small) {
9484           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9485             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9486             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9487           }
9488
9489           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9490           emitSKPNC;
9491           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9492                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9493                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9494           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9495           pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9496
9497         } else {
9498           pic16_emitcode("rlf","known_zero,w");
9499
9500           /*
9501             if right is signed
9502               btfsc  right,7
9503                addlw ff
9504           */
9505           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9506             pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9507             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9508           } else {
9509             pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9510           }
9511         }
9512       }
9513       ret = 1;
9514     }
9515   }
9516   ret = 1;
9517
9518 release:
9519   pic16_freeAsmop(right,NULL,ic,TRUE);
9520   pic16_freeAsmop(result,NULL,ic,TRUE);
9521   pic16_freeAsmop(nextright,NULL,ic,TRUE);
9522   pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9523   if(ret)
9524     nextic->generated = 1;
9525
9526   return ret;
9527 #else
9528   return 0;
9529 #endif
9530 }
9531 /*-----------------------------------------------------------------*/
9532 /* genCast - gen code for casting                                  */
9533 /*-----------------------------------------------------------------*/
9534 static void genCast (iCode *ic)
9535 {
9536     operand *result = IC_RESULT(ic);
9537     sym_link *ctype = operandType(IC_LEFT(ic));
9538     sym_link *rtype = operandType(IC_RIGHT(ic));
9539     operand *right = IC_RIGHT(ic);
9540     int size, offset ;
9541
9542     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9543     /* if they are equivalent then do nothing */
9544     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9545         return ;
9546
9547     pic16_aopOp(right,ic,FALSE) ;
9548     pic16_aopOp(result,ic,FALSE);
9549
9550     DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9551
9552     /* if the result is a bit */
9553     if (AOP_TYPE(result) == AOP_CRY) {
9554         /* if the right size is a literal then
9555         we know what the value is */
9556       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9557         if (AOP_TYPE(right) == AOP_LIT) {
9558
9559           pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9560                       pic16_popGet(AOP(result),0));
9561
9562             if (((int) operandLitValue(right))) 
9563               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9564                        AOP(result)->aopu.aop_dir,
9565                        AOP(result)->aopu.aop_dir);
9566             else
9567               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9568                        AOP(result)->aopu.aop_dir,
9569                        AOP(result)->aopu.aop_dir);
9570
9571             goto release;
9572         }
9573
9574         /* the right is also a bit variable */
9575         if (AOP_TYPE(right) == AOP_CRY) {
9576
9577           emitCLRC;
9578           pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9579
9580           pic16_emitcode("clrc","");
9581           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9582                    AOP(right)->aopu.aop_dir,
9583                    AOP(right)->aopu.aop_dir);
9584             pic16_aopPut(AOP(result),"c",0);
9585             goto release ;
9586         }
9587
9588         /* we need to or */
9589         if (AOP_TYPE(right) == AOP_REG) {
9590           pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9591           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9592           pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9593         }
9594         pic16_toBoolean(right);
9595         pic16_aopPut(AOP(result),"a",0);
9596         goto release ;
9597     }
9598
9599     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9600       int offset = 1;
9601       size = AOP_SIZE(result);
9602
9603       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9604
9605       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
9606       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9607       pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
9608
9609       while (size--)
9610         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9611
9612       goto release;
9613     }
9614
9615     /* if they are the same size : or less */
9616     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9617
9618         /* if they are in the same place */
9619       if (pic16_sameRegs(AOP(right),AOP(result)))
9620         goto release;
9621
9622       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9623       if (IS_PTR_CONST(rtype))
9624         DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9625       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9626         DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9627
9628       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9630         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9631         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9632         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9633         if(AOP_SIZE(result) <2)
9634           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9635
9636       } else {
9637
9638         /* if they in different places then copy */
9639         size = AOP_SIZE(result);
9640         offset = 0 ;
9641         while (size--) {
9642           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9643           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9644
9645           //pic16_aopPut(AOP(result),
9646           // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9647           // offset);
9648
9649           offset++;
9650         }
9651       }
9652       goto release;
9653     }
9654
9655
9656     /* if the result is of type pointer */
9657     if (IS_PTR(ctype)) {
9658
9659         int p_type;
9660         sym_link *type = operandType(right);
9661         sym_link *etype = getSpec(type);
9662       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9663
9664         /* pointer to generic pointer */
9665         if (IS_GENPTR(ctype)) {
9666             char *l = zero;
9667             
9668             if (IS_PTR(type)) 
9669                 p_type = DCL_TYPE(type);
9670             else {
9671                 /* we have to go by the storage class */
9672                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9673
9674 /*              if (SPEC_OCLS(etype)->codesp )  */
9675 /*                  p_type = CPOINTER ;  */
9676 /*              else */
9677 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9678 /*                      p_type = FPOINTER ; */
9679 /*                  else */
9680 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9681 /*                          p_type = PPOINTER; */
9682 /*                      else */
9683 /*                          if (SPEC_OCLS(etype) == idata ) */
9684 /*                              p_type = IPOINTER ; */
9685 /*                          else */
9686 /*                              p_type = POINTER ; */
9687             }
9688                 
9689             /* the first two bytes are known */
9690       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9691             size = GPTRSIZE - 1; 
9692             offset = 0 ;
9693             while (size--) {
9694               if(offset < AOP_SIZE(right)) {
9695       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9696                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9697                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9698                   pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9699                   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9700                 } else { 
9701                   pic16_aopPut(AOP(result),
9702                          pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9703                          offset);
9704                 }
9705               } else 
9706                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9707               offset++;
9708             }
9709             /* the last byte depending on type */
9710             switch (p_type) {
9711             case IPOINTER:
9712             case POINTER:
9713                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9714                 break;
9715             case FPOINTER:
9716               pic16_emitcode(";BUG!? ","%d",__LINE__);
9717                 l = one;
9718                 break;
9719             case CPOINTER:
9720               pic16_emitcode(";BUG!? ","%d",__LINE__);
9721                 l = "#0x02";
9722                 break;                          
9723             case PPOINTER:
9724               pic16_emitcode(";BUG!? ","%d",__LINE__);
9725                 l = "#0x03";
9726                 break;
9727                 
9728             default:
9729                 /* this should never happen */
9730                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9731                        "got unknown pointer type");
9732                 exit(1);
9733             }
9734             //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
9735             goto release ;
9736         }
9737         
9738         /* just copy the pointers */
9739         size = AOP_SIZE(result);
9740         offset = 0 ;
9741         while (size--) {
9742             pic16_aopPut(AOP(result),
9743                    pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9744                    offset);
9745             offset++;
9746         }
9747         goto release ;
9748     }
9749     
9750
9751
9752     /* so we now know that the size of destination is greater
9753     than the size of the source.
9754     Now, if the next iCode is an operator then we might be
9755     able to optimize the operation without performing a cast.
9756     */
9757     if(genMixedOperation(ic))
9758       goto release;
9759
9760     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9761     
9762     /* we move to result for the size of source */
9763     size = AOP_SIZE(right);
9764     offset = 0 ;
9765     while (size--) {
9766       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(right),offset));
9767       pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset));
9768       offset++;
9769     }
9770
9771     /* now depending on the sign of the destination */
9772     size = AOP_SIZE(result) - AOP_SIZE(right);
9773     /* if unsigned or not an integral type */
9774     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9775       while (size--)
9776         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9777     } else {
9778       /* we need to extend the sign :{ */
9779
9780       if(size == 1) {
9781         /* Save one instruction of casting char to int */
9782         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
9783         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9784         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
9785       } else {
9786         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9787
9788         if(offset)
9789           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9790         else
9791           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9792         
9793         pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
9794
9795         while (size--)
9796           pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
9797       }
9798     }
9799
9800 release:
9801     pic16_freeAsmop(right,NULL,ic,TRUE);
9802     pic16_freeAsmop(result,NULL,ic,TRUE);
9803
9804 }
9805
9806 /*-----------------------------------------------------------------*/
9807 /* genDjnz - generate decrement & jump if not zero instrucion      */
9808 /*-----------------------------------------------------------------*/
9809 static int genDjnz (iCode *ic, iCode *ifx)
9810 {
9811     symbol *lbl, *lbl1;
9812     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9813
9814     if (!ifx)
9815         return 0;
9816     
9817     /* if the if condition has a false label
9818        then we cannot save */
9819     if (IC_FALSE(ifx))
9820         return 0;
9821
9822     /* if the minus is not of the form 
9823        a = a - 1 */
9824     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9825         !IS_OP_LITERAL(IC_RIGHT(ic)))
9826         return 0;
9827
9828     if (operandLitValue(IC_RIGHT(ic)) != 1)
9829         return 0;
9830
9831     /* if the size of this greater than one then no
9832        saving */
9833     if (getSize(operandType(IC_RESULT(ic))) > 1)
9834         return 0;
9835
9836     /* otherwise we can save BIG */
9837     lbl = newiTempLabel(NULL);
9838     lbl1= newiTempLabel(NULL);
9839
9840     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9841     
9842     if (IS_AOP_PREG(IC_RESULT(ic))) {
9843         pic16_emitcode("dec","%s",
9844                  pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9845         pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9846         pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9847     } else {    
9848
9849
9850       pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9851       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9852
9853       pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9854       pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9855
9856     }
9857 /*     pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9858 /*     pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9859 /*     pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9860 /*     pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9861
9862     
9863     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9864     ifx->generated = 1;
9865     return 1;
9866 }
9867
9868 /*-----------------------------------------------------------------*/
9869 /* genReceive - generate code for a receive iCode                  */
9870 /*-----------------------------------------------------------------*/
9871 static void genReceive (iCode *ic)
9872 {    
9873   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9874
9875   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9876       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9877         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9878
9879     int size = getSize(operandType(IC_RESULT(ic)));
9880     int offset =  pic16_fReturnSizePic - size;
9881     while (size--) {
9882       pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9883                                     fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9884       offset++;
9885     }
9886     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9887     size = AOP_SIZE(IC_RESULT(ic));
9888     offset = 0;
9889     while (size--) {
9890       pic16_emitcode ("pop","acc");
9891       pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9892     }
9893         
9894   } else {
9895     _G.accInUse++;
9896     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9897     _G.accInUse--;
9898     assignResultValue(IC_RESULT(ic));   
9899   }
9900
9901   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9902 }
9903
9904 /*-----------------------------------------------------------------*/
9905 /* genpic16Code - generate code for pic16 based controllers        */
9906 /*-----------------------------------------------------------------*/
9907 /*
9908  * At this point, ralloc.c has gone through the iCode and attempted
9909  * to optimize in a way suitable for a PIC. Now we've got to generate
9910  * PIC instructions that correspond to the iCode.
9911  *
9912  * Once the instructions are generated, we'll pass through both the
9913  * peep hole optimizer and the pCode optimizer.
9914  *-----------------------------------------------------------------*/
9915
9916 void genpic16Code (iCode *lic)
9917 {
9918     iCode *ic;
9919     int cln = 0;
9920
9921     lineHead = lineCurr = NULL;
9922
9923     pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9924     pic16_addpBlock(pb);
9925
9926 #if 0
9927     /* if debug information required */
9928     if (options.debug && currFunc) { 
9929       if (currFunc) {
9930         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9931         _G.debugLine = 1;
9932         if (IS_STATIC(currFunc->etype)) {
9933           pic16_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9934           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9935         } else {
9936           pic16_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9937           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9938         }
9939         _G.debugLine = 0;
9940       }
9941     }
9942 #endif
9943
9944     for (ic = lic ; ic ; ic = ic->next ) {
9945
9946 //      fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
9947 //      DEBUGpic16_emitcode("; VR", "");
9948       DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
9949         if ( cln != ic->lineno ) {
9950             if ( options.debug ) {
9951                 _G.debugLine = 1;
9952                 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9953                          FileBaseName(ic->filename),ic->lineno,
9954                          ic->level,ic->block);
9955                 _G.debugLine = 0;
9956             }
9957             /*
9958               pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9959               pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9960               printCLine(ic->filename, ic->lineno));
9961             */
9962             pic16_addpCode2pBlock(pb,
9963                             pic16_newpCodeCSource(ic->lineno, 
9964                                             ic->filename, 
9965                                             printCLine(ic->filename, ic->lineno)));
9966
9967             cln = ic->lineno ;
9968         }
9969         /* if the result is marked as
9970            spilt and rematerializable or code for
9971            this has already been generated then
9972            do nothing */
9973         if (resultRemat(ic) || ic->generated ) 
9974             continue ;
9975         
9976         /* depending on the operation */
9977         switch (ic->op) {
9978         case '!' :
9979             genNot(ic);
9980             break;
9981             
9982         case '~' :
9983             genCpl(ic);
9984             break;
9985             
9986         case UNARYMINUS:
9987             genUminus (ic);
9988             break;
9989             
9990         case IPUSH:
9991             genIpush (ic);
9992             break;
9993             
9994         case IPOP:
9995             /* IPOP happens only when trying to restore a 
9996                spilt live range, if there is an ifx statement
9997                following this pop then the if statement might
9998                be using some of the registers being popped which
9999                would destroy the contents of the register so
10000                we need to check for this condition and handle it */
10001             if (ic->next            && 
10002                 ic->next->op == IFX &&
10003                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10004                 genIfx (ic->next,ic);
10005             else
10006                 genIpop (ic);
10007             break; 
10008             
10009         case CALL:
10010             genCall (ic);
10011             break;
10012             
10013         case PCALL:
10014             genPcall (ic);
10015             break;
10016             
10017         case FUNCTION:
10018             genFunction (ic);
10019             break;
10020             
10021         case ENDFUNCTION:
10022             genEndFunction (ic);
10023             break;
10024             
10025         case RETURN:
10026             genRet (ic);
10027             break;
10028             
10029         case LABEL:
10030             genLabel (ic);
10031             break;
10032             
10033         case GOTO:
10034             genGoto (ic);
10035             break;
10036             
10037         case '+' :
10038             pic16_genPlus (ic) ;
10039             break;
10040             
10041         case '-' :
10042             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10043                 pic16_genMinus (ic);
10044             break;
10045             
10046         case '*' :
10047             genMult (ic);
10048             break;
10049             
10050         case '/' :
10051             genDiv (ic) ;
10052             break;
10053             
10054         case '%' :
10055             genMod (ic);
10056             break;
10057             
10058         case '>' :
10059             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10060             break;
10061             
10062         case '<' :
10063             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10064             break;
10065             
10066         case LE_OP:
10067         case GE_OP:
10068         case NE_OP:
10069             
10070             /* note these two are xlated by algebraic equivalence
10071                during parsing SDCC.y */
10072             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10073                    "got '>=' or '<=' shouldn't have come here");
10074             break;      
10075             
10076         case EQ_OP:
10077             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10078             break;          
10079             
10080         case AND_OP:
10081             genAndOp (ic);
10082             break;
10083             
10084         case OR_OP:
10085             genOrOp (ic);
10086             break;
10087             
10088         case '^' :
10089             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10090             break;
10091             
10092         case '|' :
10093                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10094             break;
10095             
10096         case BITWISEAND:
10097             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10098             break;
10099             
10100         case INLINEASM:
10101             genInline (ic);
10102             break;
10103             
10104         case RRC:
10105             genRRC (ic);
10106             break;
10107             
10108         case RLC:
10109             genRLC (ic);
10110             break;
10111             
10112         case GETHBIT:
10113             genGetHbit (ic);
10114             break;
10115             
10116         case LEFT_OP:
10117             genLeftShift (ic);
10118             break;
10119             
10120         case RIGHT_OP:
10121             genRightShift (ic);
10122             break;
10123             
10124         case GET_VALUE_AT_ADDRESS:
10125             genPointerGet(ic);
10126             break;
10127             
10128         case '=' :
10129             if (POINTER_SET(ic))
10130                 genPointerSet(ic);
10131             else
10132                 genAssign(ic);
10133             break;
10134             
10135         case IFX:
10136             genIfx (ic,NULL);
10137             break;
10138             
10139         case ADDRESS_OF:
10140             genAddrOf (ic);
10141             break;
10142             
10143         case JUMPTABLE:
10144             genJumpTab (ic);
10145             break;
10146             
10147         case CAST:
10148             genCast (ic);
10149             break;
10150             
10151         case RECEIVE:
10152             genReceive(ic);
10153             break;
10154             
10155         case SEND:
10156             addSet(&_G.sendSet,ic);
10157             break;
10158
10159         default :
10160             ic = ic;
10161         }
10162     }
10163     
10164
10165     /* now we are ready to call the 
10166        peep hole optimizer */
10167     if (!options.nopeep) {
10168       peepHole (&lineHead);
10169     }
10170     /* now do the actual printing */
10171     printLine (lineHead,codeOutFile);
10172
10173 #ifdef PCODE_DEBUG
10174     DFPRINTF((stderr,"printing pBlock\n\n"));
10175     pic16_printpBlock(stdout,pb);
10176 #endif
10177
10178     return;
10179 }
10180