* src/configure.in: check for endianess (even while cross-compiling)
[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     if(pic16_debug_verbose)
268       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
269
270     va_end(ap);
271 }
272
273
274 /*-----------------------------------------------------------------*/
275 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
276 /*-----------------------------------------------------------------*/
277 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
278 {
279     bool r0iu = FALSE , r1iu = FALSE;
280     bool r0ou = FALSE , r1ou = FALSE;
281
282     /* the logic: if r0 & r1 used in the instruction
283     then we are in trouble otherwise */
284
285     /* first check if r0 & r1 are used by this
286     instruction, in which case we are in trouble */
287     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
288         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
289     {
290         goto endOfWorld;      
291     }
292
293     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
294     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
295
296     /* if no usage of r0 then return it */
297     if (!r0iu && !r0ou) {
298         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
299         (*aopp)->type = AOP_R0;
300         
301         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
302     }
303
304     /* if no usage of r1 then return it */
305     if (!r1iu && !r1ou) {
306         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
307         (*aopp)->type = AOP_R1;
308
309         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
310     }    
311
312     /* now we know they both have usage */
313     /* if r0 not used in this instruction */
314     if (!r0iu) {
315         /* push it if not already pushed */
316         if (!_G.r0Pushed) {
317           //pic16_emitcode ("push","%s",
318           //          pic16_regWithIdx(R0_IDX)->dname);
319             _G.r0Pushed++ ;
320         }
321         
322         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
323         (*aopp)->type = AOP_R0;
324
325         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
326     }
327
328     /* if r1 not used then */
329
330     if (!r1iu) {
331         /* push it if not already pushed */
332         if (!_G.r1Pushed) {
333           //pic16_emitcode ("push","%s",
334           //          pic16_regWithIdx(R1_IDX)->dname);
335             _G.r1Pushed++ ;
336         }
337         
338         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
339         (*aopp)->type = AOP_R1;
340         return pic16_regWithIdx(R1_IDX);
341     }
342
343 endOfWorld :
344     /* I said end of world but not quite end of world yet */
345     /* if this is a result then we can push it on the stack*/
346     if (result) {
347         (*aopp)->type = AOP_STK;    
348         return NULL;
349     }
350
351     /* other wise this is true end of the world */
352     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
353            "getFreePtr should never reach here");
354     exit(0);
355 }
356
357 /*-----------------------------------------------------------------*/
358 /* newAsmop - creates a new asmOp                                  */
359 /*-----------------------------------------------------------------*/
360 static asmop *newAsmop (short type)
361 {
362     asmop *aop;
363
364     aop = Safe_calloc(1,sizeof(asmop));
365     aop->type = type;
366     return aop;
367 }
368
369 static void genSetDPTR(int n)
370 {
371     if (!n)
372     {
373         pic16_emitcode(";", "Select standard DPTR");
374         pic16_emitcode("mov", "dps, #0x00");
375     }
376     else
377     {
378         pic16_emitcode(";", "Select alternate DPTR");
379         pic16_emitcode("mov", "dps, #0x01");
380     }
381 }
382
383 /*-----------------------------------------------------------------*/
384 /* resolveIfx - converts an iCode ifx into a form more useful for  */
385 /*              generating code                                    */
386 /*-----------------------------------------------------------------*/
387 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
388 {
389   if(!resIfx) 
390     return;
391
392   //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
393
394   resIfx->condition = 1;    /* assume that the ifx is true */
395   resIfx->generated = 0;    /* indicate that the ifx has not been used */
396
397   if(!ifx) {
398     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
399 /*
400     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
401                         __FUNCTION__,__LINE__,resIfx->lbl->key);
402 */
403   } else {
404     if(IC_TRUE(ifx)) {
405       resIfx->lbl = IC_TRUE(ifx);
406     } else {
407       resIfx->lbl = IC_FALSE(ifx);
408       resIfx->condition = 0;
409     }
410 /*
411     if(IC_TRUE(ifx)) 
412       DEBUGpic16_emitcode("; ***","ifx true is non-null");
413     if(IC_FALSE(ifx)) 
414       DEBUGpic16_emitcode("; ***","ifx false is non-null");
415 */
416   }
417
418   //  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
419
420 }
421 /*-----------------------------------------------------------------*/
422 /* pointerCode - returns the code for a pointer type               */
423 /*-----------------------------------------------------------------*/
424 static int pointerCode (sym_link *etype)
425 {
426
427     return PTR_TYPE(SPEC_OCLS(etype));
428
429 }
430
431 /*-----------------------------------------------------------------*/
432 /* aopForSym - for a true symbol                                   */
433 /*-----------------------------------------------------------------*/
434 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
435 {
436     asmop *aop;
437     memmap *space= SPEC_OCLS(sym->etype);
438
439     DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
440     /* if already has one */
441     if (sym->aop)
442         return sym->aop;
443
444     /* assign depending on the storage class */
445     /* if it is on the stack or indirectly addressable */
446     /* space we need to assign either r0 or r1 to it   */    
447     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
448         sym->aop = aop = newAsmop(0);
449         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
450         aop->size = getSize(sym->type);
451
452         /* now assign the address of the variable to 
453         the pointer register */
454         if (aop->type != AOP_STK) {
455
456             if (sym->onStack) {
457                     if ( _G.accInUse )
458                         pic16_emitcode("push","acc");
459
460                     pic16_emitcode("mov","a,_bp");
461                     pic16_emitcode("add","a,#0x%02x",
462                              ((sym->stack < 0) ?
463                               ((char)(sym->stack - _G.nRegsSaved )) :
464                               ((char)sym->stack)) & 0xff);
465                     pic16_emitcode("mov","%s,a",
466                              aop->aopu.aop_ptr->name);
467
468                     if ( _G.accInUse )
469                         pic16_emitcode("pop","acc");
470             } else
471                 pic16_emitcode("mov","%s,#%s",
472                          aop->aopu.aop_ptr->name,
473                          sym->rname);
474             aop->paged = space->paged;
475         } else
476             aop->aopu.aop_stk = sym->stack;
477         return aop;
478     }
479     
480     if (sym->onStack && options.stack10bit)
481     {
482         /* It's on the 10 bit stack, which is located in
483          * far data space.
484          */
485          
486       //DEBUGpic16_emitcode(";","%d",__LINE__);
487
488         if ( _G.accInUse )
489                 pic16_emitcode("push","acc");
490
491         pic16_emitcode("mov","a,_bp");
492         pic16_emitcode("add","a,#0x%02x",
493                  ((sym->stack < 0) ?
494                    ((char)(sym->stack - _G.nRegsSaved )) :
495                    ((char)sym->stack)) & 0xff);
496         
497         genSetDPTR(1);
498         pic16_emitcode ("mov","dpx1,#0x40");
499         pic16_emitcode ("mov","dph1,#0x00");
500         pic16_emitcode ("mov","dpl1, a");
501         genSetDPTR(0);
502         
503         if ( _G.accInUse )
504             pic16_emitcode("pop","acc");
505             
506         sym->aop = aop = newAsmop(AOP_DPTR2);
507         aop->size = getSize(sym->type); 
508         return aop;
509     }
510
511     //DEBUGpic16_emitcode(";","%d",__LINE__);
512     /* if in bit space */
513     if (IN_BITSPACE(space)) {
514         sym->aop = aop = newAsmop (AOP_CRY);
515         aop->aopu.aop_dir = sym->rname ;
516         aop->size = getSize(sym->type);
517         //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
518         return aop;
519     }
520     /* if it is in direct space */
521     if (IN_DIRSPACE(space)) {
522         sym->aop = aop = newAsmop (AOP_DIR);
523         aop->aopu.aop_dir = sym->rname ;
524         aop->size = getSize(sym->type);
525         DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526         return aop;
527     }
528
529     /* special case for a function */
530     if (IS_FUNC(sym->type)) {   
531         sym->aop = aop = newAsmop(AOP_IMMD);    
532         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
533         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
534         strcpy(aop->aopu.aop_immd,sym->rname);
535         aop->size = FPTRSIZE; 
536         DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
537         return aop;
538     }
539
540
541     /* only remaining is far space */
542     /* in which case DPTR gets the address */
543     sym->aop = aop = newAsmop(AOP_PCODE);
544
545     aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
546     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
547     PCOI(aop->aopu.pcop)->index = 0;
548
549     DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
550                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
551
552     pic16_allocDirReg (IC_LEFT(ic));
553
554     aop->size = FPTRSIZE; 
555 /*
556     DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
557     sym->aop = aop = newAsmop(AOP_DPTR);
558     pic16_emitcode ("mov","dptr,#%s", sym->rname);
559     aop->size = getSize(sym->type);
560
561     DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
562 */
563
564     /* if it is in code space */
565     if (IN_CODESPACE(space))
566         aop->code = 1;
567
568     return aop;     
569 }
570
571 /*-----------------------------------------------------------------*/
572 /* aopForRemat - rematerialzes an object                           */
573 /*-----------------------------------------------------------------*/
574 static asmop *aopForRemat (operand *op) // x symbol *sym)
575 {
576   symbol *sym = OP_SYMBOL(op);
577   iCode *ic = NULL;
578   asmop *aop = newAsmop(AOP_PCODE);
579   int val = 0;
580   int offset = 0;
581
582   ic = sym->rematiCode;
583
584   DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
585   if(IS_OP_POINTER(op)) {
586     DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
587   }
588   for (;;) {
589     if (ic->op == '+') {
590       val += (int) operandLitValue(IC_RIGHT(ic));
591     } else if (ic->op == '-') {
592       val -= (int) operandLitValue(IC_RIGHT(ic));
593     } else
594       break;
595         
596     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
597   }
598
599   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
600   aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
601   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
602   PCOI(aop->aopu.pcop)->index = val;
603
604   DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
605                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
606                       val, IS_PTR_CONST(operandType(op)));
607
608   //    DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
609
610   pic16_allocDirReg (IC_LEFT(ic));
611
612   return aop;        
613 }
614
615 static int aopIdx (asmop *aop, int offset)
616 {
617   if(!aop)
618     return -1;
619
620   if(aop->type !=  AOP_REG)
621     return -2;
622         
623   return aop->aopu.aop_reg[offset]->rIdx;
624
625 }
626 /*-----------------------------------------------------------------*/
627 /* regsInCommon - two operands have some registers in common       */
628 /*-----------------------------------------------------------------*/
629 static bool regsInCommon (operand *op1, operand *op2)
630 {
631     symbol *sym1, *sym2;
632     int i;
633
634     /* if they have registers in common */
635     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
636         return FALSE ;
637
638     sym1 = OP_SYMBOL(op1);
639     sym2 = OP_SYMBOL(op2);
640
641     if (sym1->nRegs == 0 || sym2->nRegs == 0)
642         return FALSE ;
643
644     for (i = 0 ; i < sym1->nRegs ; i++) {
645         int j;
646         if (!sym1->regs[i])
647             continue ;
648
649         for (j = 0 ; j < sym2->nRegs ;j++ ) {
650             if (!sym2->regs[j])
651                 continue ;
652
653             if (sym2->regs[j] == sym1->regs[i])
654                 return TRUE ;
655         }
656     }
657
658     return FALSE ;
659 }
660
661 /*-----------------------------------------------------------------*/
662 /* operandsEqu - equivalent                                        */
663 /*-----------------------------------------------------------------*/
664 static bool operandsEqu ( operand *op1, operand *op2)
665 {
666     symbol *sym1, *sym2;
667
668     /* if they not symbols */
669     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
670         return FALSE;
671
672     sym1 = OP_SYMBOL(op1);
673     sym2 = OP_SYMBOL(op2);
674
675     /* if both are itemps & one is spilt
676        and the other is not then false */
677     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
678         sym1->isspilt != sym2->isspilt )
679         return FALSE ;
680
681     /* if they are the same */
682     if (sym1 == sym2)
683         return TRUE ;
684
685     if (strcmp(sym1->rname,sym2->rname) == 0)
686         return TRUE;
687
688
689     /* if left is a tmp & right is not */
690     if (IS_ITEMP(op1)  && 
691         !IS_ITEMP(op2) &&
692         sym1->isspilt  &&
693         (sym1->usl.spillLoc == sym2))
694         return TRUE;
695
696     if (IS_ITEMP(op2)  && 
697         !IS_ITEMP(op1) &&
698         sym2->isspilt  &&
699         sym1->level > 0 &&
700         (sym2->usl.spillLoc == sym1))
701         return TRUE ;
702
703     return FALSE ;
704 }
705
706 /*-----------------------------------------------------------------*/
707 /* pic16_sameRegs - two asmops have the same registers                   */
708 /*-----------------------------------------------------------------*/
709 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
710 {
711     int i;
712
713     if (aop1 == aop2)
714         return TRUE ;
715
716     if (aop1->type != AOP_REG ||
717         aop2->type != AOP_REG )
718         return FALSE ;
719
720     if (aop1->size != aop2->size )
721         return FALSE ;
722
723     for (i = 0 ; i < aop1->size ; i++ )
724         if (aop1->aopu.aop_reg[i] !=
725             aop2->aopu.aop_reg[i] )
726             return FALSE ;
727
728     return TRUE ;
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* pic16_aopOp - allocates an asmop for an operand  :                    */
733 /*-----------------------------------------------------------------*/
734 void pic16_aopOp (operand *op, iCode *ic, bool result)
735 {
736     asmop *aop;
737     symbol *sym;
738     int i;
739
740     if (!op)
741         return ;
742
743     //    DEBUGpic16_emitcode(";","%d",__LINE__);
744     /* if this a literal */
745     if (IS_OP_LITERAL(op)) {
746         op->aop = aop = newAsmop(AOP_LIT);
747         aop->aopu.aop_lit = op->operand.valOperand;
748         aop->size = getSize(operandType(op));
749         return;
750     }
751
752     {
753       sym_link *type = operandType(op);
754       if(IS_PTR_CONST(type))
755         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
756     }
757
758     /* if already has a asmop then continue */
759     if (op->aop)
760         return ;
761
762     /* if the underlying symbol has a aop */
763     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
764       DEBUGpic16_emitcode(";","%d",__LINE__);
765         op->aop = OP_SYMBOL(op)->aop;
766         return;
767     }
768
769     /* if this is a true symbol */
770     if (IS_TRUE_SYMOP(op)) {    
771       //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
772       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
773       return ;
774     }
775
776     /* this is a temporary : this has
777     only four choices :
778     a) register
779     b) spillocation
780     c) rematerialize 
781     d) conditional   
782     e) can be a return use only */
783
784     sym = OP_SYMBOL(op);
785
786
787     /* if the type is a conditional */
788     if (sym->regType == REG_CND) {
789         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
790         aop->size = 0;
791         return;
792     }
793
794     /* if it is spilt then two situations
795     a) is rematerialize 
796     b) has a spill location */
797     if (sym->isspilt || sym->nRegs == 0) {
798
799       DEBUGpic16_emitcode(";","%d",__LINE__);
800         /* rematerialize it NOW */
801         if (sym->remat) {
802
803             sym->aop = op->aop = aop =
804                                       aopForRemat (op);
805             aop->size = getSize(sym->type);
806             //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
807             return;
808         }
809
810         if (sym->accuse) {
811             int i;
812             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
813             aop->size = getSize(sym->type);
814             for ( i = 0 ; i < 2 ; i++ )
815                 aop->aopu.aop_str[i] = accUse[i];
816             DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
817             return;  
818         }
819
820         if (sym->ruonly ) {
821           /*
822           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
823           aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
824           //pic16_allocDirReg (IC_LEFT(ic));
825           aop->size = getSize(sym->type);
826           */
827
828           unsigned i;
829
830           aop = op->aop = sym->aop = newAsmop(AOP_STR);
831           aop->size = getSize(sym->type);
832           for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
833             aop->aopu.aop_str[i] = fReturn[i];
834
835           DEBUGpic16_emitcode(";","%d",__LINE__);
836           return;
837         }
838
839         /* else spill location  */
840         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
841             /* force a new aop if sizes differ */
842             sym->usl.spillLoc->aop = NULL;
843         }
844         DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
845                             __FUNCTION__,__LINE__,
846                             sym->usl.spillLoc->rname,
847                             sym->rname, sym->usl.spillLoc->offset);
848
849         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
850         //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
851         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
852                                           getSize(sym->type), 
853                                           sym->usl.spillLoc->offset);
854         aop->size = getSize(sym->type);
855
856         return;
857     }
858
859     {
860       sym_link *type = operandType(op);
861       if(IS_PTR_CONST(type)) 
862         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
863     }
864
865     /* must be in a register */
866     DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
867     sym->aop = op->aop = aop = newAsmop(AOP_REG);
868     aop->size = sym->nRegs;
869     for ( i = 0 ; i < sym->nRegs ;i++)
870         aop->aopu.aop_reg[i] = sym->regs[i];
871 }
872
873 /*-----------------------------------------------------------------*/
874 /* pic16_freeAsmop - free up the asmop given to an operand               */
875 /*----------------------------------------------------------------*/
876 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
877 {   
878     asmop *aop ;
879
880     if (!op)
881         aop = aaop;
882     else 
883         aop = op->aop;
884
885     if (!aop)
886         return ;
887
888     if (aop->freed)
889         goto dealloc; 
890
891     aop->freed = 1;
892
893     /* depending on the asmop type only three cases need work AOP_RO
894        , AOP_R1 && AOP_STK */
895 #if 0
896     switch (aop->type) {
897         case AOP_R0 :
898             if (_G.r0Pushed ) {
899                 if (pop) {
900                     pic16_emitcode ("pop","ar0");     
901                     _G.r0Pushed--;
902                 }
903             }
904             bitVectUnSetBit(ic->rUsed,R0_IDX);
905             break;
906
907         case AOP_R1 :
908             if (_G.r1Pushed ) {
909                 if (pop) {
910                     pic16_emitcode ("pop","ar1");
911                     _G.r1Pushed--;
912                 }
913             }
914             bitVectUnSetBit(ic->rUsed,R1_IDX);          
915             break;
916
917         case AOP_STK :
918         {
919             int sz = aop->size;    
920             int stk = aop->aopu.aop_stk + aop->size;
921             bitVectUnSetBit(ic->rUsed,R0_IDX);
922             bitVectUnSetBit(ic->rUsed,R1_IDX);          
923
924             getFreePtr(ic,&aop,FALSE);
925             
926             if (options.stack10bit)
927             {
928                 /* I'm not sure what to do here yet... */
929                 /* #STUB */
930                 fprintf(stderr, 
931                         "*** Warning: probably generating bad code for "
932                         "10 bit stack mode.\n");
933             }
934             
935             if (stk) {
936                 pic16_emitcode ("mov","a,_bp");
937                 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
938                 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
939             } else {
940                 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
941             }
942
943             while (sz--) {
944                 pic16_emitcode("pop","acc");
945                 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
946                 if (!sz) break;
947                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
948             }
949             op->aop = aop;
950             pic16_freeAsmop(op,NULL,ic,TRUE);
951             if (_G.r0Pushed) {
952                 pic16_emitcode("pop","ar0");
953                 _G.r0Pushed--;
954             }
955
956             if (_G.r1Pushed) {
957                 pic16_emitcode("pop","ar1");
958                 _G.r1Pushed--;
959             }       
960         }
961     }
962 #endif
963
964 dealloc:
965     /* all other cases just dealloc */
966     if (op ) {
967         op->aop = NULL;
968         if (IS_SYMOP(op)) {
969             OP_SYMBOL(op)->aop = NULL;    
970             /* if the symbol has a spill */
971             if (SPIL_LOC(op))
972                 SPIL_LOC(op)->aop = NULL;
973         }
974     }
975 }
976
977 /*-----------------------------------------------------------------*/
978 /* pic16_aopGet - for fetching value of the aop                          */
979 /*-----------------------------------------------------------------*/
980 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
981 {
982     char *s = buffer ;
983     char *rs;
984
985     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
986     /* offset is greater than
987     size then zero */
988     if (offset > (aop->size - 1) &&
989         aop->type != AOP_LIT)
990         return zero;
991
992     /* depending on type */
993     switch (aop->type) {
994         
995     case AOP_R0:
996     case AOP_R1:
997         DEBUGpic16_emitcode(";","%d",__LINE__);
998         /* if we need to increment it */       
999         while (offset > aop->coff) {        
1000             pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1001             aop->coff++;
1002         }
1003         
1004         while (offset < aop->coff) {
1005             pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1006             aop->coff--;
1007         }
1008         
1009         aop->coff = offset ;
1010         if (aop->paged) {
1011             pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1012             return (dname ? "acc" : "a");
1013         }       
1014         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1015         rs = Safe_calloc(1,strlen(s)+1);
1016         strcpy(rs,s);   
1017         return rs;
1018         
1019     case AOP_DPTR:
1020     case AOP_DPTR2:
1021         DEBUGpic16_emitcode(";","%d",__LINE__);
1022     if (aop->type == AOP_DPTR2)
1023     {
1024         genSetDPTR(1);
1025     }
1026     
1027         while (offset > aop->coff) {
1028             pic16_emitcode ("inc","dptr");
1029             aop->coff++;
1030         }
1031         
1032         while (offset < aop->coff) {        
1033             pic16_emitcode("lcall","__decdptr");
1034             aop->coff--;
1035         }
1036         
1037         aop->coff = offset;
1038         if (aop->code) {
1039             pic16_emitcode("clr","a");
1040             pic16_emitcode("movc","a,@a+dptr");
1041         }
1042     else {
1043             pic16_emitcode("movx","a,@dptr");
1044     }
1045             
1046     if (aop->type == AOP_DPTR2)
1047     {
1048         genSetDPTR(0);
1049     }
1050             
1051     return (dname ? "acc" : "a");
1052         
1053         
1054     case AOP_IMMD:
1055         if (bit16) 
1056             sprintf (s,"%s",aop->aopu.aop_immd);
1057         else
1058             if (offset) 
1059                 sprintf(s,"(%s >> %d)",
1060                         aop->aopu.aop_immd,
1061                         offset*8);
1062             else
1063                 sprintf(s,"%s",
1064                         aop->aopu.aop_immd);
1065         DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1066         rs = Safe_calloc(1,strlen(s)+1);
1067         strcpy(rs,s);   
1068         return rs;
1069         
1070     case AOP_DIR:
1071       if (offset) {
1072         sprintf(s,"(%s + %d)",
1073                 aop->aopu.aop_dir,
1074                 offset);
1075         DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1076       } else
1077             sprintf(s,"%s",aop->aopu.aop_dir);
1078         rs = Safe_calloc(1,strlen(s)+1);
1079         strcpy(rs,s);   
1080         return rs;
1081         
1082     case AOP_REG:
1083       //if (dname) 
1084       //    return aop->aopu.aop_reg[offset]->dname;
1085       //else
1086             return aop->aopu.aop_reg[offset]->name;
1087         
1088     case AOP_CRY:
1089       //pic16_emitcode(";","%d",__LINE__);
1090       return aop->aopu.aop_dir;
1091         
1092     case AOP_ACC:
1093         DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1094         return "AOP_accumulator_bug";
1095
1096     case AOP_LIT:
1097         sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1098         rs = Safe_calloc(1,strlen(s)+1);
1099         strcpy(rs,s);   
1100         return rs;
1101         
1102     case AOP_STR:
1103         aop->coff = offset ;
1104         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1105             dname)
1106             return "acc";
1107         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1108         
1109         return aop->aopu.aop_str[offset];
1110         
1111     case AOP_PCODE:
1112       {
1113         pCodeOp *pcop = aop->aopu.pcop;
1114         DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1115         if(pcop->name) {
1116           DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1117           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1118           sprintf(s,"%s", pcop->name);
1119         } else
1120           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1121
1122       }
1123       rs = Safe_calloc(1,strlen(s)+1);
1124       strcpy(rs,s);   
1125       return rs;
1126
1127     }
1128
1129     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1130            "aopget got unsupported aop->type");
1131     exit(0);
1132 }
1133
1134
1135 /*-----------------------------------------------------------------*/
1136 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1137 /*-----------------------------------------------------------------*/
1138 pCodeOp *pic16_popGetTempReg(void)
1139 {
1140
1141   pCodeOp *pcop;
1142
1143   pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1144   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1145     PCOR(pcop)->r->wasUsed=1;
1146     PCOR(pcop)->r->isFree=0;
1147   }
1148
1149   return pcop;
1150 }
1151
1152 /*-----------------------------------------------------------------*/
1153 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1154 /*-----------------------------------------------------------------*/
1155 void pic16_popReleaseTempReg(pCodeOp *pcop)
1156 {
1157
1158   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1159     PCOR(pcop)->r->isFree = 1;
1160
1161 }
1162 /*-----------------------------------------------------------------*/
1163 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL             */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *pic16_popGetLabel(unsigned int key)
1166 {
1167
1168   DEBUGpic16_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1169
1170   if(key>max_key)
1171     max_key = key;
1172
1173   return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1174 }
1175
1176 /*-----------------------------------------------------------------*/
1177 /* pic16_popCopyReg - copy a pcode operator                              */
1178 /*-----------------------------------------------------------------*/
1179 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1180 {
1181   pCodeOpReg *pcor;
1182
1183   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1184   pcor->pcop.type = pc->pcop.type;
1185   if(pc->pcop.name) {
1186     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1187       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1188   } else
1189     pcor->pcop.name = NULL;
1190
1191   pcor->r = pc->r;
1192   pcor->rIdx = pc->rIdx;
1193   pcor->r->wasUsed=1;
1194
1195   //DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1196
1197   return PCOP(pcor);
1198 }
1199 /*-----------------------------------------------------------------*/
1200 /* pic16_popGet - asm operator to pcode operator conversion              */
1201 /*-----------------------------------------------------------------*/
1202 pCodeOp *pic16_popGetLit(unsigned int lit)
1203 {
1204
1205   return pic16_newpCodeOpLit(lit);
1206 }
1207
1208
1209 /*-----------------------------------------------------------------*/
1210 /* pic16_popGetImmd - asm operator to pcode immediate conversion         */
1211 /*-----------------------------------------------------------------*/
1212 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1213 {
1214
1215   return pic16_newpCodeOpImmd(name, offset,index, 0);
1216 }
1217
1218
1219 /*-----------------------------------------------------------------*/
1220 /* pic16_popGet - asm operator to pcode operator conversion              */
1221 /*-----------------------------------------------------------------*/
1222 pCodeOp *pic16_popGetWithString(char *str)
1223 {
1224   pCodeOp *pcop;
1225
1226
1227   if(!str) {
1228     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1229     exit (1);
1230   }
1231
1232   pcop = pic16_newpCodeOp(str,PO_STR);
1233
1234   return pcop;
1235 }
1236
1237 /*-----------------------------------------------------------------*/
1238 /* popRegFromString -                                              */
1239 /*-----------------------------------------------------------------*/
1240 static pCodeOp *popRegFromString(char *str, int size, int offset)
1241 {
1242
1243   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1244   pcop->type = PO_DIR;
1245
1246   DEBUGpic16_emitcode(";","%d",__LINE__);
1247
1248   if(!str)
1249     str = "BAD_STRING";
1250
1251   pcop->name = Safe_calloc(1,strlen(str)+1);
1252   strcpy(pcop->name,str);
1253
1254   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1255
1256   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1257   if(PCOR(pcop)->r == NULL) {
1258     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1259     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1260     DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1261   } else {
1262     DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1263   }
1264   PCOR(pcop)->instance = offset;
1265
1266   return pcop;
1267 }
1268
1269 static pCodeOp *popRegFromIdx(int rIdx)
1270 {
1271   pCodeOp *pcop;
1272
1273   DEBUGpic16_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1274                        __FUNCTION__,__LINE__,rIdx);
1275
1276   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1277
1278   PCOR(pcop)->rIdx = rIdx;
1279   PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1280   PCOR(pcop)->r->isFree = 0;
1281   PCOR(pcop)->r->wasUsed = 1;
1282
1283   pcop->type = PCOR(pcop)->r->pc_type;
1284
1285
1286   return pcop;
1287 }
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGet - asm operator to pcode operator conversion              */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1292 {
1293   //char *s = buffer ;
1294     //char *rs;
1295
1296     pCodeOp *pcop;
1297
1298     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1299     /* offset is greater than
1300     size then zero */
1301
1302     if (offset > (aop->size - 1) &&
1303         aop->type != AOP_LIT)
1304       return NULL;  //zero;
1305
1306     /* depending on type */
1307     switch (aop->type) {
1308         
1309     case AOP_R0:
1310     case AOP_R1:
1311     case AOP_DPTR:
1312     case AOP_DPTR2:
1313     case AOP_ACC:
1314         DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1315         return NULL;
1316         
1317     case AOP_IMMD:
1318       DEBUGpic16_emitcode(";","%d",__LINE__);
1319       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1320
1321     case AOP_DIR:
1322       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1323 #if 0
1324         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1325         pcop->type = PO_DIR;
1326
1327         /*
1328         if (offset)
1329             sprintf(s,"(%s + %d)",
1330                     aop->aopu.aop_dir,
1331                     offset);
1332         else
1333             sprintf(s,"%s",aop->aopu.aop_dir);
1334         pcop->name = Safe_calloc(1,strlen(s)+1);
1335         strcpy(pcop->name,s);   
1336         */
1337         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1338         strcpy(pcop->name,aop->aopu.aop_dir);   
1339         PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1340         if(PCOR(pcop)->r == NULL) {
1341           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1342           PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1343           DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1344         } else {
1345           DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1346         }
1347         PCOR(pcop)->instance = offset;
1348
1349         return pcop;
1350 #endif
1351         
1352     case AOP_REG:
1353       {
1354         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1355
1356         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1357         PCOR(pcop)->rIdx = rIdx;
1358         PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1359         PCOR(pcop)->r->wasUsed=1;
1360         PCOR(pcop)->r->isFree=0;
1361
1362         PCOR(pcop)->instance = offset;
1363         pcop->type = PCOR(pcop)->r->pc_type;
1364         //rs = aop->aopu.aop_reg[offset]->name;
1365         //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1366         return pcop;
1367       }
1368
1369     case AOP_CRY:
1370       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1371       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1372       //if(PCOR(pcop)->r == NULL)
1373       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1374       return pcop;
1375         
1376     case AOP_LIT:
1377       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1378
1379     case AOP_STR:
1380       DEBUGpic16_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1381       return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1382       /*
1383       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1384       PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1385       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1386       pcop->type = PCOR(pcop)->r->pc_type;
1387       pcop->name = PCOR(pcop)->r->name;
1388
1389       return pcop;
1390       */
1391
1392     case AOP_PCODE:
1393       DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1394                           __LINE__, 
1395                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1396       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1397       PCOI(pcop)->offset = offset;
1398       return pcop;
1399     }
1400
1401     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1402            "pic16_popGet got unsupported aop->type");
1403     exit(0);
1404 }
1405 /*-----------------------------------------------------------------*/
1406 /* pic16_aopPut - puts a string for a aop                                */
1407 /*-----------------------------------------------------------------*/
1408 void pic16_aopPut (asmop *aop, char *s, int offset)
1409 {
1410     char *d = buffer ;
1411     symbol *lbl ;
1412
1413     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1414
1415     if (aop->size && offset > ( aop->size - 1)) {
1416         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1417                "pic16_aopPut got offset > aop->size");
1418         exit(0);
1419     }
1420
1421     /* will assign value to value */
1422     /* depending on where it is ofcourse */
1423     switch (aop->type) {
1424     case AOP_DIR:
1425       if (offset) {
1426         sprintf(d,"(%s + %d)",
1427                 aop->aopu.aop_dir,offset);
1428         fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1429
1430       } else
1431             sprintf(d,"%s",aop->aopu.aop_dir);
1432         
1433         if (strcmp(d,s)) {
1434           DEBUGpic16_emitcode(";","%d",__LINE__);
1435           if(strcmp(s,"W"))
1436             pic16_emitcode("movf","%s,w",s);
1437           pic16_emitcode("movwf","%s",d);
1438
1439           if(strcmp(s,"W")) {
1440             pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1441             if(offset >= aop->size) {
1442               pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1443               break;
1444             } else
1445               pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1446           }
1447
1448           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1449
1450
1451         }
1452         break;
1453         
1454     case AOP_REG:
1455       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1456         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1457           /*
1458             if (*s == '@'           ||
1459                 strcmp(s,"r0") == 0 ||
1460                 strcmp(s,"r1") == 0 ||
1461                 strcmp(s,"r2") == 0 ||
1462                 strcmp(s,"r3") == 0 ||
1463                 strcmp(s,"r4") == 0 ||
1464                 strcmp(s,"r5") == 0 ||
1465                 strcmp(s,"r6") == 0 || 
1466                 strcmp(s,"r7") == 0 )
1467                 pic16_emitcode("mov","%s,%s  ; %d",
1468                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1469             else
1470           */
1471
1472           if(strcmp(s,"W")==0 )
1473             pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
1474
1475           pic16_emitcode("movwf","%s",
1476                    aop->aopu.aop_reg[offset]->name);
1477
1478           if(strcmp(s,zero)==0) {
1479             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1480
1481           } else if(strcmp(s,"W")==0) {
1482             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1483             pcop->type = PO_GPR_REGISTER;
1484
1485             PCOR(pcop)->rIdx = -1;
1486             PCOR(pcop)->r = NULL;
1487
1488             DEBUGpic16_emitcode(";","%d",__LINE__);
1489             pcop->name = Safe_strdup(s);
1490             pic16_emitpcode(POC_MOVFW,pcop);
1491             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1492           } else if(strcmp(s,one)==0) {
1493             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1494             pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1495           } else {
1496             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1497           }
1498         }
1499         break;
1500         
1501     case AOP_DPTR:
1502     case AOP_DPTR2:
1503     
1504     if (aop->type == AOP_DPTR2)
1505     {
1506         genSetDPTR(1);
1507     }
1508     
1509         if (aop->code) {
1510             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1511                    "pic16_aopPut writting to code space");
1512             exit(0);
1513         }
1514         
1515         while (offset > aop->coff) {
1516             aop->coff++;
1517             pic16_emitcode ("inc","dptr");
1518         }
1519         
1520         while (offset < aop->coff) {
1521             aop->coff-- ;
1522             pic16_emitcode("lcall","__decdptr");
1523         }
1524         
1525         aop->coff = offset;
1526         
1527         /* if not in accumulater */
1528         MOVA(s);        
1529         
1530         pic16_emitcode ("movx","@dptr,a");
1531         
1532     if (aop->type == AOP_DPTR2)
1533     {
1534         genSetDPTR(0);
1535     }
1536         break;
1537         
1538     case AOP_R0:
1539     case AOP_R1:
1540         while (offset > aop->coff) {
1541             aop->coff++;
1542             pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1543         }
1544         while (offset < aop->coff) {
1545             aop->coff-- ;
1546             pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1547         }
1548         aop->coff = offset;
1549         
1550         if (aop->paged) {
1551             MOVA(s);           
1552             pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1553             
1554         } else
1555             if (*s == '@') {
1556                 MOVA(s);
1557                 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1558             } else
1559                 if (strcmp(s,"r0") == 0 ||
1560                     strcmp(s,"r1") == 0 ||
1561                     strcmp(s,"r2") == 0 ||
1562                     strcmp(s,"r3") == 0 ||
1563                     strcmp(s,"r4") == 0 ||
1564                     strcmp(s,"r5") == 0 ||
1565                     strcmp(s,"r6") == 0 || 
1566                     strcmp(s,"r7") == 0 ) {
1567                     char buffer[10];
1568                     sprintf(buffer,"a%s",s);
1569                     pic16_emitcode("mov","@%s,%s",
1570                              aop->aopu.aop_ptr->name,buffer);
1571                 } else
1572                     pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1573         
1574         break;
1575         
1576     case AOP_STK:
1577         if (strcmp(s,"a") == 0)
1578             pic16_emitcode("push","acc");
1579         else
1580             pic16_emitcode("push","%s",s);
1581         
1582         break;
1583         
1584     case AOP_CRY:
1585         /* if bit variable */
1586         if (!aop->aopu.aop_dir) {
1587             pic16_emitcode("clr","a");
1588             pic16_emitcode("rlc","a");
1589         } else {
1590             if (s == zero) 
1591                 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1592             else
1593                 if (s == one)
1594                     pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1595                 else
1596                     if (!strcmp(s,"c"))
1597                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1598                     else {
1599                         lbl = newiTempLabel(NULL);
1600                         
1601                         if (strcmp(s,"a")) {
1602                             MOVA(s);
1603                         }
1604                         pic16_emitcode("clr","c");
1605                         pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1606                         pic16_emitcode("cpl","c");
1607                         pic16_emitcode("","%05d_DS_:",lbl->key+100);
1608                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1609                     }
1610         }
1611         break;
1612         
1613     case AOP_STR:
1614         aop->coff = offset;
1615         if (strcmp(aop->aopu.aop_str[offset],s))
1616             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1617         break;
1618         
1619     case AOP_ACC:
1620         aop->coff = offset;
1621         if (!offset && (strcmp(s,"acc") == 0))
1622             break;
1623         
1624         if (strcmp(aop->aopu.aop_str[offset],s))
1625             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1626         break;
1627
1628     default :
1629         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1630                "pic16_aopPut got unsupported aop->type");
1631         exit(0);    
1632     }    
1633
1634 }
1635
1636 /*-----------------------------------------------------------------*/
1637 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1638 /*-----------------------------------------------------------------*/
1639 static void mov2w (asmop *aop, int offset)
1640 {
1641
1642   if(!aop)
1643     return;
1644
1645   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1646
1647   if ( aop->type == AOP_PCODE ||
1648        aop->type == AOP_LIT )
1649     pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1650   else
1651     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1652
1653 }
1654
1655 /*-----------------------------------------------------------------*/
1656 /* reAdjustPreg - points a register back to where it should        */
1657 /*-----------------------------------------------------------------*/
1658 static void reAdjustPreg (asmop *aop)
1659 {
1660     int size ;
1661
1662     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1663     aop->coff = 0;
1664     if ((size = aop->size) <= 1)
1665         return ;
1666     size-- ;
1667     switch (aop->type) {
1668         case AOP_R0 :
1669         case AOP_R1 :
1670             while (size--)
1671                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1672             break;          
1673         case AOP_DPTR :
1674         case AOP_DPTR2:
1675             if (aop->type == AOP_DPTR2)
1676             {
1677                 genSetDPTR(1);
1678             } 
1679             while (size--)
1680             {
1681                 pic16_emitcode("lcall","__decdptr");
1682             }
1683                 
1684             if (aop->type == AOP_DPTR2)
1685             {
1686                 genSetDPTR(0);
1687             }                
1688             break;  
1689
1690     }   
1691
1692 }
1693
1694 /*-----------------------------------------------------------------*/
1695 /* genNotFloat - generates not for float operations              */
1696 /*-----------------------------------------------------------------*/
1697 static void genNotFloat (operand *op, operand *res)
1698 {
1699     int size, offset;
1700     char *l;
1701     symbol *tlbl ;
1702
1703     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1704     /* we will put 127 in the first byte of 
1705     the result */
1706     pic16_aopPut(AOP(res),"#127",0);
1707     size = AOP_SIZE(op) - 1;
1708     offset = 1;
1709
1710     l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1711     MOVA(l);    
1712
1713     while(size--) {
1714         pic16_emitcode("orl","a,%s",
1715                  pic16_aopGet(op->aop,
1716                         offset++,FALSE,FALSE));
1717     }
1718     tlbl = newiTempLabel(NULL);
1719
1720     tlbl = newiTempLabel(NULL);
1721     pic16_aopPut(res->aop,one,1);
1722     pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1723     pic16_aopPut(res->aop,zero,1);
1724     pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1725
1726     size = res->aop->size - 2;
1727     offset = 2;    
1728     /* put zeros in the rest */
1729     while (size--) 
1730         pic16_aopPut(res->aop,zero,offset++);
1731 }
1732
1733 #if 0
1734 /*-----------------------------------------------------------------*/
1735 /* opIsGptr: returns non-zero if the passed operand is             */   
1736 /* a generic pointer type.                                         */
1737 /*-----------------------------------------------------------------*/ 
1738 static int opIsGptr(operand *op)
1739 {
1740     sym_link *type = operandType(op);
1741     
1742     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1743     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1744     {
1745         return 1;
1746     }
1747     return 0;        
1748 }
1749 #endif
1750
1751 /*-----------------------------------------------------------------*/
1752 /* pic16_getDataSize - get the operand data size                         */
1753 /*-----------------------------------------------------------------*/
1754 int pic16_getDataSize(operand *op)
1755 {
1756     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1757
1758
1759     return AOP_SIZE(op);
1760
1761     // tsd- in the pic port, the genptr size is 1, so this code here
1762     // fails. ( in the 8051 port, the size was 4).
1763 #if 0
1764     int size;
1765     size = AOP_SIZE(op);
1766     if (size == GPTRSIZE)
1767     {
1768         sym_link *type = operandType(op);
1769         if (IS_GENPTR(type))
1770         {
1771             /* generic pointer; arithmetic operations
1772              * should ignore the high byte (pointer type).
1773              */
1774             size--;
1775     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1776         }
1777     }
1778     return size;
1779 #endif
1780 }
1781
1782 /*-----------------------------------------------------------------*/
1783 /* pic16_outAcc - output Acc                                             */
1784 /*-----------------------------------------------------------------*/
1785 void pic16_outAcc(operand *result)
1786 {
1787   int size,offset;
1788   DEBUGpic16_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1789   DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1790
1791
1792   size = pic16_getDataSize(result);
1793   if(size){
1794     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1795     size--;
1796     offset = 1;
1797     /* unsigned or positive */
1798     while(size--)
1799       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1800   }
1801
1802 }
1803
1804 /*-----------------------------------------------------------------*/
1805 /* pic16_outBitC - output a bit C                                        */
1806 /*-----------------------------------------------------------------*/
1807 void pic16_outBitC(operand *result)
1808 {
1809
1810     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1811     /* if the result is bit */
1812     if (AOP_TYPE(result) == AOP_CRY) 
1813         pic16_aopPut(AOP(result),"c",0);
1814     else {
1815         pic16_emitcode("clr","a  ; %d", __LINE__);
1816         pic16_emitcode("rlc","a");
1817         pic16_outAcc(result);
1818     }
1819 }
1820
1821 /*-----------------------------------------------------------------*/
1822 /* pic16_toBoolean - emit code for orl a,operator(sizeop)                */
1823 /*-----------------------------------------------------------------*/
1824 void pic16_toBoolean(operand *oper)
1825 {
1826     int size = AOP_SIZE(oper) - 1;
1827     int offset = 1;
1828
1829     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1830
1831     if ( AOP_TYPE(oper) != AOP_ACC) {
1832       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1833     }
1834     while (size--) {
1835       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1836     }
1837 }
1838
1839
1840 /*-----------------------------------------------------------------*/
1841 /* genNot - generate code for ! operation                          */
1842 /*-----------------------------------------------------------------*/
1843 static void genNot (iCode *ic)
1844 {
1845   symbol *tlbl;
1846   sym_link *optype = operandType(IC_LEFT(ic));
1847   int size;
1848
1849   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1850   /* assign asmOps to operand & result */
1851   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1852   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1853
1854   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1855   /* if in bit space then a special case */
1856   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1857     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1858       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1859       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1860     } else {
1861       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1862       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1863       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1864     }
1865     goto release;
1866   }
1867
1868   /* if type float then do float */
1869   if (IS_FLOAT(optype)) {
1870     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1871     goto release;
1872   }
1873
1874   size = AOP_SIZE(IC_RESULT(ic));
1875   if(size == 1) {
1876     pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1877     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1878     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1879     goto release;
1880   }
1881   pic16_toBoolean(IC_LEFT(ic));
1882
1883   tlbl = newiTempLabel(NULL);
1884   pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1885   pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1886   pic16_outBitC(IC_RESULT(ic));
1887
1888  release:    
1889   /* release the aops */
1890   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1891   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1892 }
1893
1894
1895 /*-----------------------------------------------------------------*/
1896 /* genCpl - generate code for complement                           */
1897 /*-----------------------------------------------------------------*/
1898 static void genCpl (iCode *ic)
1899 {
1900     int offset = 0;
1901     int size ;
1902
1903
1904     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1905     /* assign asmOps to operand & result */
1906     pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1907     pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1908
1909     /* if both are in bit space then 
1910     a special case */
1911     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1912         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1913
1914         pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1915         pic16_emitcode("cpl","c"); 
1916         pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1917         goto release; 
1918     } 
1919
1920     size = AOP_SIZE(IC_RESULT(ic));
1921     while (size--) {
1922         char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1923         MOVA(l);       
1924         pic16_emitcode("cpl","a");
1925         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1926     }
1927
1928
1929 release:
1930     /* release the aops */
1931     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1932     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1933 }
1934
1935 /*-----------------------------------------------------------------*/
1936 /* genUminusFloat - unary minus for floating points                */
1937 /*-----------------------------------------------------------------*/
1938 static void genUminusFloat(operand *op,operand *result)
1939 {
1940     int size ,offset =0 ;
1941     char *l;
1942
1943     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1944     /* for this we just need to flip the 
1945     first it then copy the rest in place */
1946     size = AOP_SIZE(op) - 1;
1947     l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1948
1949     MOVA(l);    
1950
1951     pic16_emitcode("cpl","acc.7");
1952     pic16_aopPut(AOP(result),"a",3);    
1953
1954     while(size--) {
1955         pic16_aopPut(AOP(result),
1956                pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1957                offset);
1958         offset++;
1959     }          
1960 }
1961
1962 /*-----------------------------------------------------------------*/
1963 /* genUminus - unary minus code generation                         */
1964 /*-----------------------------------------------------------------*/
1965 static void genUminus (iCode *ic)
1966 {
1967   int size, i;
1968   sym_link *optype, *rtype;
1969
1970
1971   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1972   /* assign asmops */
1973   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1974   pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1975
1976   /* if both in bit space then special
1977      case */
1978   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1979       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1980
1981     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1982     pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1983     pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
1984
1985     goto release; 
1986   } 
1987
1988   optype = operandType(IC_LEFT(ic));
1989   rtype = operandType(IC_RESULT(ic));
1990
1991   /* if float then do float stuff */
1992   if (IS_FLOAT(optype)) {
1993     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1994     goto release;
1995   }
1996
1997   /* otherwise subtract from zero by taking the 2's complement */
1998   size = AOP_SIZE(IC_LEFT(ic));
1999
2000   for(i=0; i<size; i++) {
2001     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2002       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
2003     else {
2004       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2005       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2006     }
2007   }
2008
2009   pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
2010   for(i=1; i<size; i++) {
2011     emitSKPNZ;
2012     pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
2013   }
2014
2015  release:
2016   /* release the aops */
2017   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2018   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2019 }
2020
2021 /*-----------------------------------------------------------------*/
2022 /* saveRegisters - will look for a call and save the registers     */
2023 /*-----------------------------------------------------------------*/
2024 static void saveRegisters(iCode *lic) 
2025 {
2026     int i;
2027     iCode *ic;
2028     bitVect *rsave;
2029     sym_link *dtype;
2030
2031     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2032     /* look for call */
2033     for (ic = lic ; ic ; ic = ic->next) 
2034         if (ic->op == CALL || ic->op == PCALL)
2035             break;
2036
2037     if (!ic) {
2038         fprintf(stderr,"found parameter push with no function call\n");
2039         return ;
2040     }
2041
2042     /* if the registers have been saved already then
2043     do nothing */
2044     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2045         return ;
2046
2047     /* find the registers in use at this time 
2048     and push them away to safety */
2049     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2050                           ic->rUsed);
2051
2052     ic->regsSaved = 1;
2053     if (options.useXstack) {
2054         if (bitVectBitValue(rsave,R0_IDX))
2055             pic16_emitcode("mov","b,r0");
2056         pic16_emitcode("mov","r0,%s",spname);
2057         for (i = 0 ; i < pic16_nRegs ; i++) {
2058             if (bitVectBitValue(rsave,i)) {
2059                 if (i == R0_IDX)
2060                     pic16_emitcode("mov","a,b");
2061                 else
2062                     pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2063                 pic16_emitcode("movx","@r0,a");
2064                 pic16_emitcode("inc","r0");
2065             }
2066         }
2067         pic16_emitcode("mov","%s,r0",spname);
2068         if (bitVectBitValue(rsave,R0_IDX))
2069             pic16_emitcode("mov","r0,b");           
2070     }// else
2071     //for (i = 0 ; i < pic16_nRegs ; i++) {
2072     //    if (bitVectBitValue(rsave,i))
2073     //  pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2074     //}
2075
2076     dtype = operandType(IC_LEFT(ic));
2077     if (currFunc && dtype && 
2078         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2079         IFFUNC_ISISR(currFunc->type) &&
2080         !ic->bankSaved) 
2081
2082         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2083
2084 }
2085 /*-----------------------------------------------------------------*/
2086 /* unsaveRegisters - pop the pushed registers                      */
2087 /*-----------------------------------------------------------------*/
2088 static void unsaveRegisters (iCode *ic)
2089 {
2090     int i;
2091     bitVect *rsave;
2092
2093     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2094     /* find the registers in use at this time 
2095     and push them away to safety */
2096     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2097                           ic->rUsed);
2098     
2099     if (options.useXstack) {
2100         pic16_emitcode("mov","r0,%s",spname);   
2101         for (i =  pic16_nRegs ; i >= 0 ; i--) {
2102             if (bitVectBitValue(rsave,i)) {
2103                 pic16_emitcode("dec","r0");
2104                 pic16_emitcode("movx","a,@r0");
2105                 if (i == R0_IDX)
2106                     pic16_emitcode("mov","b,a");
2107                 else
2108                     pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2109             }       
2110
2111         }
2112         pic16_emitcode("mov","%s,r0",spname);
2113         if (bitVectBitValue(rsave,R0_IDX))
2114             pic16_emitcode("mov","r0,b");
2115     } //else
2116     //for (i =  pic16_nRegs ; i >= 0 ; i--) {
2117     //    if (bitVectBitValue(rsave,i))
2118     //  pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2119     //}
2120
2121 }  
2122
2123
2124 /*-----------------------------------------------------------------*/
2125 /* pushSide -                                                      */
2126 /*-----------------------------------------------------------------*/
2127 static void pushSide(operand * oper, int size)
2128 {
2129 #if 0
2130         int offset = 0;
2131     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2132         while (size--) {
2133                 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2134                 if (AOP_TYPE(oper) != AOP_REG &&
2135                     AOP_TYPE(oper) != AOP_DIR &&
2136                     strcmp(l,"a") ) {
2137                         pic16_emitcode("mov","a,%s",l);
2138                         pic16_emitcode("push","acc");
2139                 } else
2140                         pic16_emitcode("push","%s",l);
2141         }
2142 #endif
2143 }
2144
2145 /*-----------------------------------------------------------------*/
2146 /* assignResultValue -                                             */
2147 /*-----------------------------------------------------------------*/
2148 static void assignResultValue(operand * oper)
2149 {
2150   int size = AOP_SIZE(oper);
2151
2152   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2153
2154   DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2155
2156   if(!GpsuedoStkPtr) {
2157     /* The last byte in the assignment is in W */
2158     size--;
2159     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2160     GpsuedoStkPtr++;
2161   }
2162
2163   while (size--) {
2164     pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2165     GpsuedoStkPtr++;
2166     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2167   }
2168 }
2169
2170
2171 /*-----------------------------------------------------------------*/
2172 /* genIpush - genrate code for pushing this gets a little complex  */
2173 /*-----------------------------------------------------------------*/
2174 static void genIpush (iCode *ic)
2175 {
2176
2177   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2178 #if 0
2179     int size, offset = 0 ;
2180     char *l;
2181
2182
2183     /* if this is not a parm push : ie. it is spill push 
2184     and spill push is always done on the local stack */
2185     if (!ic->parmPush) {
2186
2187         /* and the item is spilt then do nothing */
2188         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2189             return ;
2190
2191         pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2192         size = AOP_SIZE(IC_LEFT(ic));
2193         /* push it on the stack */
2194         while(size--) {
2195             l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2196             if (*l == '#') {
2197                 MOVA(l);
2198                 l = "acc";
2199             }
2200             pic16_emitcode("push","%s",l);
2201         }
2202         return ;        
2203     }
2204
2205     /* this is a paramter push: in this case we call
2206     the routine to find the call and save those
2207     registers that need to be saved */   
2208     saveRegisters(ic);
2209
2210     /* then do the push */
2211     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2212
2213
2214         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2215     size = AOP_SIZE(IC_LEFT(ic));
2216
2217     while (size--) {
2218         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2219         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2220             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2221             strcmp(l,"a") ) {
2222             pic16_emitcode("mov","a,%s",l);
2223             pic16_emitcode("push","acc");
2224         } else
2225             pic16_emitcode("push","%s",l);
2226     }       
2227
2228     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2229 #endif
2230 }
2231
2232 /*-----------------------------------------------------------------*/
2233 /* genIpop - recover the registers: can happen only for spilling   */
2234 /*-----------------------------------------------------------------*/
2235 static void genIpop (iCode *ic)
2236 {
2237   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2238 #if 0
2239     int size,offset ;
2240
2241
2242     /* if the temp was not pushed then */
2243     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2244         return ;
2245
2246     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2247     size = AOP_SIZE(IC_LEFT(ic));
2248     offset = (size-1);
2249     while (size--) 
2250         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2251                                    FALSE,TRUE));
2252
2253     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2254 #endif
2255 }
2256
2257 /*-----------------------------------------------------------------*/
2258 /* unsaverbank - restores the resgister bank from stack            */
2259 /*-----------------------------------------------------------------*/
2260 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2261 {
2262   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2263 #if 0
2264     int i;
2265     asmop *aop ;
2266     regs *r = NULL;
2267
2268     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2269     if (popPsw) {
2270         if (options.useXstack) {
2271             aop = newAsmop(0);
2272             r = getFreePtr(ic,&aop,FALSE);
2273             
2274             
2275             pic16_emitcode("mov","%s,_spx",r->name);
2276             pic16_emitcode("movx","a,@%s",r->name);
2277             pic16_emitcode("mov","psw,a");
2278             pic16_emitcode("dec","%s",r->name);
2279             
2280         }else
2281             pic16_emitcode ("pop","psw");
2282     }
2283
2284     for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2285         if (options.useXstack) {       
2286             pic16_emitcode("movx","a,@%s",r->name);
2287             //pic16_emitcode("mov","(%s+%d),a",
2288             //       regspic16[i].base,8*bank+regspic16[i].offset);
2289             pic16_emitcode("dec","%s",r->name);
2290
2291         } else 
2292           pic16_emitcode("pop",""); //"(%s+%d)",
2293         //regspic16[i].base,8*bank); //+regspic16[i].offset);
2294     }
2295
2296     if (options.useXstack) {
2297
2298         pic16_emitcode("mov","_spx,%s",r->name);
2299         pic16_freeAsmop(NULL,aop,ic,TRUE);
2300
2301     }
2302 #endif 
2303 }
2304
2305 /*-----------------------------------------------------------------*/
2306 /* saverbank - saves an entire register bank on the stack          */
2307 /*-----------------------------------------------------------------*/
2308 static void saverbank (int bank, iCode *ic, bool pushPsw)
2309 {
2310   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2311 #if 0
2312     int i;
2313     asmop *aop ;
2314     regs *r = NULL;
2315
2316     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2317     if (options.useXstack) {
2318
2319         aop = newAsmop(0);
2320         r = getFreePtr(ic,&aop,FALSE);  
2321         pic16_emitcode("mov","%s,_spx",r->name);
2322
2323     }
2324
2325     for (i = 0 ; i < pic16_nRegs ;i++) {
2326         if (options.useXstack) {
2327             pic16_emitcode("inc","%s",r->name);
2328             //pic16_emitcode("mov","a,(%s+%d)",
2329             //         regspic16[i].base,8*bank+regspic16[i].offset);
2330             pic16_emitcode("movx","@%s,a",r->name);           
2331         } else 
2332           pic16_emitcode("push","");// "(%s+%d)",
2333                      //regspic16[i].base,8*bank+regspic16[i].offset);
2334     }
2335     
2336     if (pushPsw) {
2337         if (options.useXstack) {
2338             pic16_emitcode("mov","a,psw");
2339             pic16_emitcode("movx","@%s,a",r->name);     
2340             pic16_emitcode("inc","%s",r->name);
2341             pic16_emitcode("mov","_spx,%s",r->name);       
2342             pic16_freeAsmop (NULL,aop,ic,TRUE);
2343             
2344         } else
2345             pic16_emitcode("push","psw");
2346         
2347         pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2348     }
2349     ic->bankSaved = 1;
2350 #endif
2351 }
2352
2353 /*-----------------------------------------------------------------*/
2354 /* genCall - generates a call statement                            */
2355 /*-----------------------------------------------------------------*/
2356 static void genCall (iCode *ic)
2357 {
2358   sym_link *dtype;   
2359
2360   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2361
2362   /* if caller saves & we have not saved then */
2363   if (!ic->regsSaved)
2364     saveRegisters(ic);
2365
2366   /* if we are calling a function that is not using
2367      the same register bank then we need to save the
2368      destination registers on the stack */
2369   dtype = operandType(IC_LEFT(ic));
2370   if (currFunc && dtype && 
2371       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2372       IFFUNC_ISISR(currFunc->type) &&
2373       !ic->bankSaved) 
2374
2375     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2376
2377   /* if send set is not empty the assign */
2378   if (_G.sendSet) {
2379     iCode *sic;
2380     /* For the Pic port, there is no data stack.
2381      * So parameters passed to functions are stored
2382      * in registers. (The pCode optimizer will get
2383      * rid of most of these :).
2384      */
2385     int psuedoStkPtr=-1; 
2386     int firstTimeThruLoop = 1;
2387
2388     _G.sendSet = reverseSet(_G.sendSet);
2389
2390     /* First figure how many parameters are getting passed */
2391     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2392          sic = setNextItem(_G.sendSet)) {
2393
2394       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2395       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2396       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2397     }
2398
2399     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2400          sic = setNextItem(_G.sendSet)) {
2401       int size, offset = 0;
2402
2403       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2404       size = AOP_SIZE(IC_LEFT(sic));
2405
2406       while (size--) {
2407         DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2408                              pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2409
2410         if(!firstTimeThruLoop) {
2411           /* If this is not the first time we've been through the loop
2412            * then we need to save the parameter in a temporary
2413            * register. The last byte of the last parameter is
2414            * passed in W. */
2415           pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2416
2417         }
2418         firstTimeThruLoop=0;
2419
2420         //if (strcmp(l,fReturn[offset])) {
2421         mov2w (AOP(IC_LEFT(sic)),  offset);
2422 /*
2423         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2424              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2425           pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2426         else
2427           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2428 */
2429         //}
2430         offset++;
2431       }
2432       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2433     }
2434     _G.sendSet = NULL;
2435   }
2436   /* make the call */
2437   pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2438                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2439                                       OP_SYMBOL(IC_LEFT(ic))->name));
2440
2441   GpsuedoStkPtr=0;
2442   /* if we need assign a result value */
2443   if ((IS_ITEMP(IC_RESULT(ic)) && 
2444        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2445         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2446       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2447
2448     _G.accInUse++;
2449     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2450     _G.accInUse--;
2451
2452     assignResultValue(IC_RESULT(ic));
2453
2454     DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2455                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2456                 
2457     pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2458   }
2459
2460   /* adjust the stack for parameters if 
2461      required */
2462   if (ic->parmBytes) {
2463     int i;
2464     if (ic->parmBytes > 3) {
2465       pic16_emitcode("mov","a,%s",spname);
2466       pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2467       pic16_emitcode("mov","%s,a",spname);
2468     } else 
2469       for ( i = 0 ; i <  ic->parmBytes ;i++)
2470         pic16_emitcode("dec","%s",spname);
2471
2472   }
2473
2474   /* if register bank was saved then pop them */
2475   if (ic->bankSaved)
2476     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2477
2478   /* if we hade saved some registers then unsave them */
2479   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2480     unsaveRegisters (ic);
2481
2482
2483 }
2484
2485 /*-----------------------------------------------------------------*/
2486 /* genPcall - generates a call by pointer statement                */
2487 /*-----------------------------------------------------------------*/
2488 static void genPcall (iCode *ic)
2489 {
2490     sym_link *dtype;
2491     symbol *rlbl = newiTempLabel(NULL);
2492
2493
2494     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2495     /* if caller saves & we have not saved then */
2496     if (!ic->regsSaved)
2497         saveRegisters(ic);
2498
2499     /* if we are calling a function that is not using
2500     the same register bank then we need to save the
2501     destination registers on the stack */
2502     dtype = operandType(IC_LEFT(ic));
2503     if (currFunc && dtype && 
2504         IFFUNC_ISISR(currFunc->type) &&
2505         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2506         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2507
2508
2509     /* push the return address on to the stack */
2510     pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2511     pic16_emitcode("push","acc");    
2512     pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2513     pic16_emitcode("push","acc");
2514     
2515     if (options.model == MODEL_FLAT24)
2516     {
2517         pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2518         pic16_emitcode("push","acc");    
2519     }
2520
2521     /* now push the calling address */
2522     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2523
2524     pushSide(IC_LEFT(ic), FPTRSIZE);
2525
2526     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2527
2528     /* if send set is not empty the assign */
2529     if (_G.sendSet) {
2530         iCode *sic ;
2531
2532         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2533              sic = setNextItem(_G.sendSet)) {
2534             int size, offset = 0;
2535             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2536             size = AOP_SIZE(IC_LEFT(sic));
2537             while (size--) {
2538                 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2539                                 FALSE,FALSE);
2540                 if (strcmp(l,fReturn[offset]))
2541                     pic16_emitcode("mov","%s,%s",
2542                              fReturn[offset],
2543                              l);
2544                 offset++;
2545             }
2546             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2547         }
2548         _G.sendSet = NULL;
2549     }
2550
2551     pic16_emitcode("ret","");
2552     pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2553
2554
2555     /* if we need assign a result value */
2556     if ((IS_ITEMP(IC_RESULT(ic)) &&
2557          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2558           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2559         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2560
2561         _G.accInUse++;
2562         pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2563         _G.accInUse--;
2564         
2565         assignResultValue(IC_RESULT(ic));
2566
2567         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2568     }
2569
2570     /* adjust the stack for parameters if 
2571     required */
2572     if (ic->parmBytes) {
2573         int i;
2574         if (ic->parmBytes > 3) {
2575             pic16_emitcode("mov","a,%s",spname);
2576             pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2577             pic16_emitcode("mov","%s,a",spname);
2578         } else 
2579             for ( i = 0 ; i <  ic->parmBytes ;i++)
2580                 pic16_emitcode("dec","%s",spname);
2581
2582     }
2583
2584     /* if register bank was saved then unsave them */
2585     if (currFunc && dtype && 
2586         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2587         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2588
2589     /* if we hade saved some registers then
2590     unsave them */
2591     if (ic->regsSaved)
2592         unsaveRegisters (ic);
2593
2594 }
2595
2596 /*-----------------------------------------------------------------*/
2597 /* resultRemat - result  is rematerializable                       */
2598 /*-----------------------------------------------------------------*/
2599 static int resultRemat (iCode *ic)
2600 {
2601   //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2602   if (SKIP_IC(ic) || ic->op == IFX)
2603     return 0;
2604
2605   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2606     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2607     if (sym->remat && !POINTER_SET(ic)) 
2608       return 1;
2609   }
2610
2611   return 0;
2612 }
2613
2614 #if defined(__BORLANDC__) || defined(_MSC_VER)
2615 #define STRCASECMP stricmp
2616 #else
2617 #define STRCASECMP strcasecmp
2618 #endif
2619
2620 #if 0
2621 /*-----------------------------------------------------------------*/
2622 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2623 /*-----------------------------------------------------------------*/
2624 static bool inExcludeList(char *s)
2625 {
2626   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2627     int i =0;
2628     
2629     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2630     if (options.excludeRegs[i] &&
2631     STRCASECMP(options.excludeRegs[i],"none") == 0)
2632         return FALSE ;
2633
2634     for ( i = 0 ; options.excludeRegs[i]; i++) {
2635         if (options.excludeRegs[i] &&
2636         STRCASECMP(s,options.excludeRegs[i]) == 0)
2637             return TRUE;
2638     }
2639     return FALSE ;
2640 }
2641 #endif
2642
2643 /*-----------------------------------------------------------------*/
2644 /* genFunction - generated code for function entry                 */
2645 /*-----------------------------------------------------------------*/
2646 static void genFunction (iCode *ic)
2647 {
2648     symbol *sym;
2649     sym_link *ftype;
2650
2651     DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2652
2653     labelOffset += (max_key+4);
2654     max_key=0;
2655     GpsuedoStkPtr=0;
2656     _G.nRegsSaved = 0;
2657     /* create the function header */
2658     pic16_emitcode(";","-----------------------------------------");
2659     pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2660     pic16_emitcode(";","-----------------------------------------");
2661
2662     pic16_emitcode("","%s:",sym->rname);
2663     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2664
2665     ftype = operandType(IC_LEFT(ic));
2666
2667     /* if critical function then turn interrupts off */
2668     if (IFFUNC_ISCRITICAL(ftype))
2669         pic16_emitcode("clr","ea");
2670
2671     /* here we need to generate the equates for the
2672        register bank if required */
2673 #if 0
2674     if (FUNC_REGBANK(ftype) != rbank) {
2675         int i ;
2676
2677         rbank = FUNC_REGBANK(ftype);
2678         for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2679             if (strcmp(regspic16[i].base,"0") == 0)
2680                 pic16_emitcode("","%s = 0x%02x",
2681                          regspic16[i].dname,
2682                          8*rbank+regspic16[i].offset);
2683             else
2684                 pic16_emitcode ("","%s = %s + 0x%02x",
2685                           regspic16[i].dname,
2686                           regspic16[i].base,
2687                           8*rbank+regspic16[i].offset);
2688         }
2689     }
2690 #endif
2691
2692     /* if this is an interrupt service routine then
2693     save acc, b, dpl, dph  */
2694     if (IFFUNC_ISISR(sym->type)) {
2695       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2696       pic16_emitpcodeNULLop(POC_NOP);
2697       pic16_emitpcodeNULLop(POC_NOP);
2698       pic16_emitpcodeNULLop(POC_NOP);
2699       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
2700       pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2701       pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2702       pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
2703
2704       pic16_pBlockConvert2ISR(pb);
2705 #if 0  
2706         if (!inExcludeList("acc"))          
2707             pic16_emitcode ("push","acc");      
2708         if (!inExcludeList("b"))
2709             pic16_emitcode ("push","b");
2710         if (!inExcludeList("dpl"))
2711             pic16_emitcode ("push","dpl");
2712         if (!inExcludeList("dph"))
2713             pic16_emitcode ("push","dph");
2714         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2715         {
2716             pic16_emitcode ("push", "dpx");
2717             /* Make sure we're using standard DPTR */
2718             pic16_emitcode ("push", "dps");
2719             pic16_emitcode ("mov", "dps, #0x00");
2720             if (options.stack10bit)
2721             {   
2722                 /* This ISR could conceivably use DPTR2. Better save it. */
2723                 pic16_emitcode ("push", "dpl1");
2724                 pic16_emitcode ("push", "dph1");
2725                 pic16_emitcode ("push", "dpx1");
2726             }
2727         }
2728         /* if this isr has no bank i.e. is going to
2729            run with bank 0 , then we need to save more
2730            registers :-) */
2731         if (!FUNC_REGBANK(sym->type)) {
2732
2733             /* if this function does not call any other
2734                function then we can be economical and
2735                save only those registers that are used */
2736             if (! IFFUNC_HASFCALL(sym->type)) {
2737                 int i;
2738
2739                 /* if any registers used */
2740                 if (sym->regsUsed) {
2741                     /* save the registers used */
2742                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2743                         if (bitVectBitValue(sym->regsUsed,i) ||
2744                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2745                           pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                         
2746                     }
2747                 }
2748                 
2749             } else {
2750                 /* this function has  a function call cannot
2751                    determines register usage so we will have the
2752                    entire bank */
2753                 saverbank(0,ic,FALSE);
2754             }       
2755         }
2756 #endif
2757     } else {
2758         /* if callee-save to be used for this function
2759            then save the registers being used in this function */
2760         if (IFFUNC_CALLEESAVES(sym->type)) {
2761             int i;
2762             
2763             /* if any registers used */
2764             if (sym->regsUsed) {
2765                 /* save the registers used */
2766                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2767                     if (bitVectBitValue(sym->regsUsed,i) ||
2768                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2769                       //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2770                         _G.nRegsSaved++;
2771                     }
2772                 }
2773             }
2774         }
2775     }
2776
2777     /* set the register bank to the desired value */
2778     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2779         pic16_emitcode("push","psw");
2780         pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2781     }
2782
2783     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2784
2785         if (options.useXstack) {
2786             pic16_emitcode("mov","r0,%s",spname);
2787             pic16_emitcode("mov","a,_bp");
2788             pic16_emitcode("movx","@r0,a");
2789             pic16_emitcode("inc","%s",spname);
2790         }
2791         else
2792         {
2793             /* set up the stack */
2794             pic16_emitcode ("push","_bp");     /* save the callers stack  */
2795         }
2796         pic16_emitcode ("mov","_bp,%s",spname);
2797     }
2798
2799     /* adjust the stack for the function */
2800     if (sym->stack) {
2801
2802         int i = sym->stack;
2803         if (i > 256 ) 
2804             werror(W_STACK_OVERFLOW,sym->name);
2805
2806         if (i > 3 && sym->recvSize < 4) {              
2807
2808             pic16_emitcode ("mov","a,sp");
2809             pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2810             pic16_emitcode ("mov","sp,a");
2811            
2812         }
2813         else
2814             while(i--)
2815                 pic16_emitcode("inc","sp");
2816     }
2817
2818      if (sym->xstack) {
2819
2820         pic16_emitcode ("mov","a,_spx");
2821         pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2822         pic16_emitcode ("mov","_spx,a");
2823     }    
2824
2825 }
2826
2827 /*-----------------------------------------------------------------*/
2828 /* genEndFunction - generates epilogue for functions               */
2829 /*-----------------------------------------------------------------*/
2830 static void genEndFunction (iCode *ic)
2831 {
2832     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2833
2834     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2835
2836     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2837     {
2838         pic16_emitcode ("mov","%s,_bp",spname);
2839     }
2840
2841     /* if use external stack but some variables were
2842     added to the local stack then decrement the
2843     local stack */
2844     if (options.useXstack && sym->stack) {      
2845         pic16_emitcode("mov","a,sp");
2846         pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2847         pic16_emitcode("mov","sp,a");
2848     }
2849
2850
2851     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2852         if (options.useXstack) {
2853             pic16_emitcode("mov","r0,%s",spname);
2854             pic16_emitcode("movx","a,@r0");
2855             pic16_emitcode("mov","_bp,a");
2856             pic16_emitcode("dec","%s",spname);
2857         }
2858         else
2859         {
2860             pic16_emitcode ("pop","_bp");
2861         }
2862     }
2863
2864     /* restore the register bank  */    
2865     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2866         pic16_emitcode ("pop","psw");
2867
2868     if (IFFUNC_ISISR(sym->type)) {
2869
2870         /* now we need to restore the registers */
2871         /* if this isr has no bank i.e. is going to
2872            run with bank 0 , then we need to save more
2873            registers :-) */
2874         if (!FUNC_REGBANK(sym->type)) {
2875             
2876             /* if this function does not call any other
2877                function then we can be economical and
2878                save only those registers that are used */
2879             if (! IFFUNC_HASFCALL(sym->type)) {
2880                 int i;
2881                 
2882                 /* if any registers used */
2883                 if (sym->regsUsed) {
2884                     /* save the registers used */
2885                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2886                         if (bitVectBitValue(sym->regsUsed,i) ||
2887                           (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2888                           pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2889                     }
2890                 }
2891                 
2892             } else {
2893                 /* this function has  a function call cannot
2894                    determines register usage so we will have the
2895                    entire bank */
2896                 unsaverbank(0,ic,FALSE);
2897             }       
2898         }
2899 #if 0
2900         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2901         {
2902             if (options.stack10bit)
2903             {
2904                 pic16_emitcode ("pop", "dpx1");
2905                 pic16_emitcode ("pop", "dph1");
2906                 pic16_emitcode ("pop", "dpl1");
2907             }   
2908             pic16_emitcode ("pop", "dps");
2909             pic16_emitcode ("pop", "dpx");
2910         }
2911         if (!inExcludeList("dph"))
2912             pic16_emitcode ("pop","dph");
2913         if (!inExcludeList("dpl"))
2914             pic16_emitcode ("pop","dpl");
2915         if (!inExcludeList("b"))
2916             pic16_emitcode ("pop","b");
2917         if (!inExcludeList("acc"))
2918             pic16_emitcode ("pop","acc");
2919
2920         if (IFFUNC_ISCRITICAL(sym->type))
2921             pic16_emitcode("setb","ea");
2922 #endif
2923
2924         /* if debug then send end of function */
2925 /*      if (options.debug && currFunc) { */
2926         if (currFunc) {
2927             _G.debugLine = 1;
2928             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2929                      FileBaseName(ic->filename),currFunc->lastLine,
2930                      ic->level,ic->block); 
2931             if (IS_STATIC(currFunc->etype))         
2932                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2933             else
2934                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2935             _G.debugLine = 0;
2936         }
2937         
2938         pic16_emitcode ("reti","");
2939
2940         pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
2941         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2942         pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
2943         pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
2944         pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2945         pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2946
2947         pic16_emitpcodeNULLop(POC_RETFIE);
2948
2949     }
2950     else {
2951         if (IFFUNC_ISCRITICAL(sym->type))
2952             pic16_emitcode("setb","ea");
2953         
2954         if (IFFUNC_CALLEESAVES(sym->type)) {
2955             int i;
2956             
2957             /* if any registers used */
2958             if (sym->regsUsed) {
2959                 /* save the registers used */
2960                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2961                     if (bitVectBitValue(sym->regsUsed,i) ||
2962                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2963                       pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2964                 }
2965             }
2966             
2967         }
2968
2969         /* if debug then send end of function */
2970         if (currFunc) {
2971             _G.debugLine = 1;
2972             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2973                      FileBaseName(ic->filename),currFunc->lastLine,
2974                      ic->level,ic->block); 
2975             if (IS_STATIC(currFunc->etype))         
2976                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2977             else
2978                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2979             _G.debugLine = 0;
2980         }
2981
2982         pic16_emitcode ("return","");
2983         pic16_emitpcodeNULLop(POC_RETURN);
2984
2985         /* Mark the end of a function */
2986         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
2987     }
2988
2989 }
2990
2991 /*-----------------------------------------------------------------*/
2992 /* genRet - generate code for return statement                     */
2993 /*-----------------------------------------------------------------*/
2994 static void genRet (iCode *ic)
2995 {
2996   int size,offset = 0 , pushed = 0;
2997     
2998   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2999   /* if we have no return value then
3000      just generate the "ret" */
3001   if (!IC_LEFT(ic)) 
3002     goto jumpret;       
3003     
3004   /* we have something to return then
3005      move the return value into place */
3006   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3007   size = AOP_SIZE(IC_LEFT(ic));
3008     
3009   while (size--) {
3010     char *l ;
3011     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3012       /* #NOCHANGE */
3013       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3014                  FALSE,TRUE);
3015       pic16_emitcode("push","%s",l);
3016       pushed++;
3017     } else {
3018       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3019                  FALSE,FALSE);
3020       if (strcmp(fReturn[offset],l)) {
3021         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3022             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3023           pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3024         }else {
3025           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3026         }
3027         if(size) {
3028           pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3029         }
3030         offset++;
3031       }
3032     }
3033   }    
3034
3035   if (pushed) {
3036     while(pushed) {
3037       pushed--;
3038       if (strcmp(fReturn[pushed],"a"))
3039         pic16_emitcode("pop",fReturn[pushed]);
3040       else
3041         pic16_emitcode("pop","acc");
3042     }
3043   }
3044   pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3045     
3046  jumpret:
3047   /* generate a jump to the return label
3048      if the next is not the return statement */
3049   if (!(ic->next && ic->next->op == LABEL &&
3050         IC_LABEL(ic->next) == returnLabel)) {
3051         
3052     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3053     pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3054   }
3055     
3056 }
3057
3058 /*-----------------------------------------------------------------*/
3059 /* genLabel - generates a label                                    */
3060 /*-----------------------------------------------------------------*/
3061 static void genLabel (iCode *ic)
3062 {
3063     /* special case never generate */
3064     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3065     if (IC_LABEL(ic) == entryLabel)
3066         return ;
3067
3068     pic16_emitpLabel(IC_LABEL(ic)->key);
3069     pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3070 }
3071
3072 /*-----------------------------------------------------------------*/
3073 /* genGoto - generates a goto                                      */
3074 /*-----------------------------------------------------------------*/
3075 //tsd
3076 static void genGoto (iCode *ic)
3077 {
3078   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3079   pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3080 }
3081
3082
3083 /*-----------------------------------------------------------------*/
3084 /* genMultbits :- multiplication of bits                           */
3085 /*-----------------------------------------------------------------*/
3086 static void genMultbits (operand *left, 
3087                          operand *right, 
3088                          operand *result)
3089 {
3090   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3091
3092   if(!pic16_sameRegs(AOP(result),AOP(right)))
3093     pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),0));
3094
3095   pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3096   pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3097   pic16_emitpcode(POC_BCF,  pic16_popGet(AOP(result),0));
3098
3099 }
3100
3101
3102 /*-----------------------------------------------------------------*/
3103 /* genMultOneByte : 8 bit multiplication & division                */
3104 /*-----------------------------------------------------------------*/
3105 static void genMultOneByte (operand *left,
3106                             operand *right,
3107                             operand *result)
3108 {
3109   sym_link *opetype = operandType(result);
3110
3111   // symbol *lbl ;
3112   int size,offset;
3113
3114   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3115   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3116   DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3117
3118   /* (if two literals, the value is computed before) */
3119   /* if one literal, literal on the right */
3120   if (AOP_TYPE(left) == AOP_LIT){
3121     operand *t = right;
3122     right = left;
3123     left = t;
3124   }
3125
3126   size = AOP_SIZE(result);
3127   if(size == 1) {
3128
3129     if (AOP_TYPE(right) == AOP_LIT){
3130       pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3131                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3132                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3133                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3134       pic16_emitcode("call","genMultLit");
3135     } else {
3136       pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3137                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3138                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3139                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3140       pic16_emitcode("call","pic16_genMult8X8_8");
3141
3142     }
3143     pic16_genMult8X8_8 (left, right,result);
3144
3145
3146     /* signed or unsigned */
3147     //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3148     //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3149     //MOVA(l);       
3150     //pic16_emitcode("mul","ab");
3151     /* if result size = 1, mul signed = mul unsigned */
3152     //pic16_aopPut(AOP(result),"a",0);
3153
3154   } else {  // (size > 1)
3155
3156     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3157                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3158                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3159                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
3160
3161     if (SPEC_USIGN(opetype)){
3162       pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3163       pic16_genUMult8X8_16 (left, right, result, NULL);
3164
3165       if (size > 2) {
3166         /* for filling the MSBs */
3167         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),2));
3168         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),3));
3169       }
3170     }
3171     else{
3172       pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3173
3174       pic16_emitcode("mov","a,b");
3175
3176       /* adjust the MSB if left or right neg */
3177
3178       /* if one literal */
3179       if (AOP_TYPE(right) == AOP_LIT){
3180         pic16_emitcode("multiply ","right is a lit");
3181         /* AND literal negative */
3182         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3183           /* adjust MSB (c==0 after mul) */
3184           pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3185         }
3186       }
3187       else{
3188         pic16_genSMult8X8_16 (left, right, result, NULL);
3189       }
3190
3191       if(size > 2){
3192         pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3193         /* get the sign */
3194         pic16_emitcode("rlc","a");
3195         pic16_emitcode("subb","a,acc");
3196       }
3197     }
3198
3199     size -= 2;   
3200     offset = 2;
3201     if (size > 0)
3202       while (size--)
3203         pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3204     //pic16_aopPut(AOP(result),"a",offset++);
3205   }
3206 }
3207
3208 /*-----------------------------------------------------------------*/
3209 /* genMult - generates code for multiplication                     */
3210 /*-----------------------------------------------------------------*/
3211 static void genMult (iCode *ic)
3212 {
3213     operand *left = IC_LEFT(ic);
3214     operand *right = IC_RIGHT(ic);
3215     operand *result= IC_RESULT(ic);   
3216
3217     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3218     /* assign the amsops */
3219     pic16_aopOp (left,ic,FALSE);
3220     pic16_aopOp (right,ic,FALSE);
3221     pic16_aopOp (result,ic,TRUE);
3222
3223   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3224
3225     /* special cases first */
3226     /* both are bits */
3227     if (AOP_TYPE(left) == AOP_CRY &&
3228         AOP_TYPE(right)== AOP_CRY) {
3229         genMultbits(left,right,result);
3230         goto release ;
3231     }
3232
3233     /* if both are of size == 1 */
3234     if (AOP_SIZE(left) == 1 &&
3235         AOP_SIZE(right) == 1 ) {
3236         genMultOneByte(left,right,result);
3237         goto release ;
3238     }
3239
3240     pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3241
3242     /* should have been converted to function call */
3243     //assert(0) ;
3244
3245 release :
3246     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3248     pic16_freeAsmop(result,NULL,ic,TRUE); 
3249 }
3250
3251 /*-----------------------------------------------------------------*/
3252 /* genDivbits :- division of bits                                  */
3253 /*-----------------------------------------------------------------*/
3254 static void genDivbits (operand *left, 
3255                         operand *right, 
3256                         operand *result)
3257 {
3258
3259     char *l;
3260
3261     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3262     /* the result must be bit */    
3263     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3264     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3265
3266     MOVA(l);    
3267
3268     pic16_emitcode("div","ab");
3269     pic16_emitcode("rrc","a");
3270     pic16_aopPut(AOP(result),"c",0);
3271 }
3272
3273 /*-----------------------------------------------------------------*/
3274 /* genDivOneByte : 8 bit division                                  */
3275 /*-----------------------------------------------------------------*/
3276 static void genDivOneByte (operand *left,
3277                            operand *right,
3278                            operand *result)
3279 {
3280     sym_link *opetype = operandType(result);
3281     char *l ;
3282     symbol *lbl ;
3283     int size,offset;
3284
3285     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3286     size = AOP_SIZE(result) - 1;
3287     offset = 1;
3288     /* signed or unsigned */
3289     if (SPEC_USIGN(opetype)) {
3290         /* unsigned is easy */
3291         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3292         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3293         MOVA(l);        
3294         pic16_emitcode("div","ab");
3295         pic16_aopPut(AOP(result),"a",0);
3296         while (size--)
3297             pic16_aopPut(AOP(result),zero,offset++);
3298         return ;
3299     }
3300
3301     /* signed is a little bit more difficult */
3302
3303     /* save the signs of the operands */
3304     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3305     MOVA(l);    
3306     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3307     pic16_emitcode("push","acc"); /* save it on the stack */
3308
3309     /* now sign adjust for both left & right */
3310     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3311     MOVA(l);       
3312     lbl = newiTempLabel(NULL);
3313     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3314     pic16_emitcode("cpl","a");   
3315     pic16_emitcode("inc","a");
3316     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3317     pic16_emitcode("mov","b,a");
3318
3319     /* sign adjust left side */
3320     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3321     MOVA(l);
3322
3323     lbl = newiTempLabel(NULL);
3324     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3325     pic16_emitcode("cpl","a");
3326     pic16_emitcode("inc","a");
3327     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3328
3329     /* now the division */
3330     pic16_emitcode("div","ab");
3331     /* we are interested in the lower order
3332     only */
3333     pic16_emitcode("mov","b,a");
3334     lbl = newiTempLabel(NULL);
3335     pic16_emitcode("pop","acc");   
3336     /* if there was an over flow we don't 
3337     adjust the sign of the result */
3338     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3339     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3340     CLRC;
3341     pic16_emitcode("clr","a");
3342     pic16_emitcode("subb","a,b");
3343     pic16_emitcode("mov","b,a");
3344     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3345
3346     /* now we are done */
3347     pic16_aopPut(AOP(result),"b",0);
3348     if(size > 0){
3349         pic16_emitcode("mov","c,b.7");
3350         pic16_emitcode("subb","a,acc");   
3351     }
3352     while (size--)
3353         pic16_aopPut(AOP(result),"a",offset++);
3354
3355 }
3356
3357 /*-----------------------------------------------------------------*/
3358 /* genDiv - generates code for division                            */
3359 /*-----------------------------------------------------------------*/
3360 static void genDiv (iCode *ic)
3361 {
3362     operand *left = IC_LEFT(ic);
3363     operand *right = IC_RIGHT(ic);
3364     operand *result= IC_RESULT(ic);   
3365
3366     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3367     /* assign the amsops */
3368     pic16_aopOp (left,ic,FALSE);
3369     pic16_aopOp (right,ic,FALSE);
3370     pic16_aopOp (result,ic,TRUE);
3371
3372     /* special cases first */
3373     /* both are bits */
3374     if (AOP_TYPE(left) == AOP_CRY &&
3375         AOP_TYPE(right)== AOP_CRY) {
3376         genDivbits(left,right,result);
3377         goto release ;
3378     }
3379
3380     /* if both are of size == 1 */
3381     if (AOP_SIZE(left) == 1 &&
3382         AOP_SIZE(right) == 1 ) {
3383         genDivOneByte(left,right,result);
3384         goto release ;
3385     }
3386
3387     /* should have been converted to function call */
3388     assert(0);
3389 release :
3390     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3391     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3392     pic16_freeAsmop(result,NULL,ic,TRUE); 
3393 }
3394
3395 /*-----------------------------------------------------------------*/
3396 /* genModbits :- modulus of bits                                   */
3397 /*-----------------------------------------------------------------*/
3398 static void genModbits (operand *left, 
3399                         operand *right, 
3400                         operand *result)
3401 {
3402
3403     char *l;
3404
3405     /* the result must be bit */    
3406     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3407     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3408
3409     MOVA(l);       
3410
3411     pic16_emitcode("div","ab");
3412     pic16_emitcode("mov","a,b");
3413     pic16_emitcode("rrc","a");
3414     pic16_aopPut(AOP(result),"c",0);
3415 }
3416
3417 /*-----------------------------------------------------------------*/
3418 /* genModOneByte : 8 bit modulus                                   */
3419 /*-----------------------------------------------------------------*/
3420 static void genModOneByte (operand *left,
3421                            operand *right,
3422                            operand *result)
3423 {
3424     sym_link *opetype = operandType(result);
3425     char *l ;
3426     symbol *lbl ;
3427
3428     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3429     /* signed or unsigned */
3430     if (SPEC_USIGN(opetype)) {
3431         /* unsigned is easy */
3432         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3433         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3434         MOVA(l);    
3435         pic16_emitcode("div","ab");
3436         pic16_aopPut(AOP(result),"b",0);
3437         return ;
3438     }
3439
3440     /* signed is a little bit more difficult */
3441
3442     /* save the signs of the operands */
3443     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3444     MOVA(l);
3445
3446     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3447     pic16_emitcode("push","acc"); /* save it on the stack */
3448
3449     /* now sign adjust for both left & right */
3450     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3451     MOVA(l);
3452
3453     lbl = newiTempLabel(NULL);
3454     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3455     pic16_emitcode("cpl","a");   
3456     pic16_emitcode("inc","a");
3457     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3458     pic16_emitcode("mov","b,a"); 
3459
3460     /* sign adjust left side */
3461     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3462     MOVA(l);
3463
3464     lbl = newiTempLabel(NULL);
3465     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3466     pic16_emitcode("cpl","a");   
3467     pic16_emitcode("inc","a");
3468     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3469
3470     /* now the multiplication */
3471     pic16_emitcode("div","ab");
3472     /* we are interested in the lower order
3473     only */
3474     lbl = newiTempLabel(NULL);
3475     pic16_emitcode("pop","acc");   
3476     /* if there was an over flow we don't 
3477     adjust the sign of the result */
3478     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3479     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3480     CLRC ;
3481     pic16_emitcode("clr","a");
3482     pic16_emitcode("subb","a,b");
3483     pic16_emitcode("mov","b,a");
3484     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3485
3486     /* now we are done */
3487     pic16_aopPut(AOP(result),"b",0);
3488
3489 }
3490
3491 /*-----------------------------------------------------------------*/
3492 /* genMod - generates code for division                            */
3493 /*-----------------------------------------------------------------*/
3494 static void genMod (iCode *ic)
3495 {
3496     operand *left = IC_LEFT(ic);
3497     operand *right = IC_RIGHT(ic);
3498     operand *result= IC_RESULT(ic);  
3499
3500     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3501     /* assign the amsops */
3502     pic16_aopOp (left,ic,FALSE);
3503     pic16_aopOp (right,ic,FALSE);
3504     pic16_aopOp (result,ic,TRUE);
3505
3506     /* special cases first */
3507     /* both are bits */
3508     if (AOP_TYPE(left) == AOP_CRY &&
3509         AOP_TYPE(right)== AOP_CRY) {
3510         genModbits(left,right,result);
3511         goto release ;
3512     }
3513
3514     /* if both are of size == 1 */
3515     if (AOP_SIZE(left) == 1 &&
3516         AOP_SIZE(right) == 1 ) {
3517         genModOneByte(left,right,result);
3518         goto release ;
3519     }
3520
3521     /* should have been converted to function call */
3522     assert(0);
3523
3524 release :
3525     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3526     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527     pic16_freeAsmop(result,NULL,ic,TRUE); 
3528 }
3529
3530 /*-----------------------------------------------------------------*/
3531 /* genIfxJump :- will create a jump depending on the ifx           */
3532 /*-----------------------------------------------------------------*/
3533 /*
3534   note: May need to add parameter to indicate when a variable is in bit space.
3535 */
3536 static void genIfxJump (iCode *ic, char *jval)
3537 {
3538
3539     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3540     /* if true label then we jump if condition
3541     supplied is true */
3542     if ( IC_TRUE(ic) ) {
3543
3544         if(strcmp(jval,"a") == 0)
3545           emitSKPZ;
3546         else if (strcmp(jval,"c") == 0)
3547           emitSKPC;
3548         else {
3549           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3550           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1));
3551         }
3552
3553         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3554         pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3555
3556     }
3557     else {
3558         /* false label is present */
3559         if(strcmp(jval,"a") == 0)
3560           emitSKPNZ;
3561         else if (strcmp(jval,"c") == 0)
3562           emitSKPNC;
3563         else {
3564           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3565           pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1));
3566         }
3567
3568         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3569         pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3570
3571     }
3572
3573
3574     /* mark the icode as generated */
3575     ic->generated = 1;
3576 }
3577
3578 /*-----------------------------------------------------------------*/
3579 /* genSkip                                                         */
3580 /*-----------------------------------------------------------------*/
3581 static void genSkip(iCode *ifx,int status_bit)
3582 {
3583   if(!ifx)
3584     return;
3585
3586   if ( IC_TRUE(ifx) ) {
3587     switch(status_bit) {
3588     case 'z':
3589       emitSKPNZ;
3590       break;
3591
3592     case 'c':
3593       emitSKPNC;
3594       break;
3595
3596     case 'd':
3597       emitSKPDC;
3598       break;
3599
3600     }
3601
3602     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3603     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3604
3605   } else {
3606
3607     switch(status_bit) {
3608
3609     case 'z':
3610       emitSKPZ;
3611       break;
3612
3613     case 'c':
3614       emitSKPC;
3615       break;
3616
3617     case 'd':
3618       emitSKPDC;
3619       break;
3620     }
3621     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3622     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3623
3624   }
3625
3626 }
3627
3628 /*-----------------------------------------------------------------*/
3629 /* genSkipc                                                        */
3630 /*-----------------------------------------------------------------*/
3631 static void genSkipc(resolvedIfx *rifx)
3632 {
3633   if(!rifx)
3634     return;
3635
3636   if(rifx->condition)
3637     emitSKPC;
3638   else
3639     emitSKPNC;
3640
3641   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3642   rifx->generated = 1;
3643 }
3644
3645 /*-----------------------------------------------------------------*/
3646 /* genSkipz2                                                       */
3647 /*-----------------------------------------------------------------*/
3648 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3649 {
3650   if(!rifx)
3651     return;
3652
3653   if( (rifx->condition ^ invert_condition) & 1)
3654     emitSKPZ;
3655   else
3656     emitSKPNZ;
3657
3658   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3659   rifx->generated = 1;
3660 }
3661
3662 /*-----------------------------------------------------------------*/
3663 /* genSkipz                                                        */
3664 /*-----------------------------------------------------------------*/
3665 static void genSkipz(iCode *ifx, int condition)
3666 {
3667   if(!ifx)
3668     return;
3669
3670   if(condition)
3671     emitSKPNZ;
3672   else
3673     emitSKPZ;
3674
3675   if ( IC_TRUE(ifx) )
3676     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3677   else
3678     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3679
3680   if ( IC_TRUE(ifx) )
3681     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3682   else
3683     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3684
3685 }
3686 /*-----------------------------------------------------------------*/
3687 /* genSkipCond                                                     */
3688 /*-----------------------------------------------------------------*/
3689 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3690 {
3691   if(!rifx)
3692     return;
3693
3694   if(rifx->condition)
3695     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3696   else
3697     pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3698
3699
3700   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3701   rifx->generated = 1;
3702 }
3703
3704 #if 0
3705 /*-----------------------------------------------------------------*/
3706 /* genChkZeroes :- greater or less than comparison                 */
3707 /*     For each byte in a literal that is zero, inclusive or the   */
3708 /*     the corresponding byte in the operand with W                */
3709 /*     returns true if any of the bytes are zero                   */
3710 /*-----------------------------------------------------------------*/
3711 static int genChkZeroes(operand *op, int lit,  int size)
3712 {
3713
3714   int i;
3715   int flag =1;
3716
3717   while(size--) {
3718     i = (lit >> (size*8)) & 0xff;
3719
3720     if(i==0) {
3721       if(flag) 
3722         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3723       else
3724         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3725       flag = 0;
3726     }
3727   }
3728
3729   return (flag==0);
3730 }
3731 #endif
3732
3733 /*-----------------------------------------------------------------*/
3734 /* genCmp :- greater or less than comparison                       */
3735 /*-----------------------------------------------------------------*/
3736 static void genCmp (operand *left,operand *right,
3737                     operand *result, iCode *ifx, int sign)
3738 {
3739   int size; //, offset = 0 ;
3740   unsigned long lit = 0L,i = 0;
3741   resolvedIfx rFalseIfx;
3742   //  resolvedIfx rTrueIfx;
3743   symbol *truelbl;
3744   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3745 /*
3746   if(ifx) {
3747     DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3748     DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3749   }
3750 */
3751
3752   resolveIfx(&rFalseIfx,ifx);
3753   truelbl  = newiTempLabel(NULL);
3754   size = max(AOP_SIZE(left),AOP_SIZE(right));
3755
3756   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3757
3758 #define _swapp
3759
3760   /* if literal is on the right then swap with left */
3761   if ((AOP_TYPE(right) == AOP_LIT)) {
3762     operand *tmp = right ;
3763     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3764     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3765 #ifdef _swapp
3766
3767     lit = (lit - 1) & mask;
3768     right = left;
3769     left = tmp;
3770     rFalseIfx.condition ^= 1;
3771 #endif
3772
3773   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3774     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3775   }
3776
3777
3778   //if(IC_TRUE(ifx) == NULL)
3779   /* if left & right are bit variables */
3780   if (AOP_TYPE(left) == AOP_CRY &&
3781       AOP_TYPE(right) == AOP_CRY ) {
3782     pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3783     pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3784   } else {
3785     /* subtract right from left if at the
3786        end the carry flag is set then we know that
3787        left is greater than right */
3788
3789     //    {
3790
3791     symbol *lbl  = newiTempLabel(NULL);
3792
3793 #ifndef _swapp
3794     if(AOP_TYPE(right) == AOP_LIT) {
3795
3796       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3797
3798       DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3799
3800       /* special cases */
3801
3802       if(lit == 0) {
3803
3804         if(sign != 0) 
3805           genSkipCond(&rFalseIfx,left,size-1,7);
3806         else 
3807           /* no need to compare to 0...*/
3808           /* NOTE: this is a de-generate compare that most certainly 
3809            *       creates some dead code. */
3810           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3811
3812         if(ifx) ifx->generated = 1;
3813         return;
3814
3815       }
3816       size--;
3817
3818       if(size == 0) {
3819         //i = (lit >> (size*8)) & 0xff;
3820         DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3821         
3822         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3823
3824         i = ((0-lit) & 0xff);
3825         if(sign) {
3826           if( i == 0x81) { 
3827             /* lit is 0x7f, all signed chars are less than
3828              * this except for 0x7f itself */
3829             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3830             genSkipz2(&rFalseIfx,0);
3831           } else {
3832             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3833             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3834             genSkipc(&rFalseIfx);
3835           }
3836
3837         } else {
3838           if(lit == 1) {
3839             genSkipz2(&rFalseIfx,1);
3840           } else {
3841             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3842             genSkipc(&rFalseIfx);
3843           }
3844         }
3845
3846         if(ifx) ifx->generated = 1;
3847         return;
3848       }
3849
3850       /* chars are out of the way. now do ints and longs */
3851
3852
3853       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3854         
3855       /* special cases */
3856
3857       if(sign) {
3858
3859         if(lit == 0) {
3860           genSkipCond(&rFalseIfx,left,size,7);
3861           if(ifx) ifx->generated = 1;
3862           return;
3863         }
3864
3865         if(lit <0x100) {
3866           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3867
3868           //rFalseIfx.condition ^= 1;
3869           //genSkipCond(&rFalseIfx,left,size,7);
3870           //rFalseIfx.condition ^= 1;
3871
3872           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3873           if(rFalseIfx.condition)
3874             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3875           else
3876             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3877
3878           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3879           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3880           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3881
3882           while(size > 1)
3883             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3884
3885           if(rFalseIfx.condition) {
3886             emitSKPZ;
3887             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3888
3889           } else {
3890             emitSKPNZ;
3891           }
3892
3893           genSkipc(&rFalseIfx);
3894           pic16_emitpLabel(truelbl->key);
3895           if(ifx) ifx->generated = 1;
3896           return;
3897
3898         }
3899
3900         if(size == 1) {
3901
3902           if( (lit & 0xff) == 0) {
3903             /* lower byte is zero */
3904             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3905             i = ((lit >> 8) & 0xff) ^0x80;
3906             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3907             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3908             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3909             genSkipc(&rFalseIfx);
3910
3911
3912             if(ifx) ifx->generated = 1;
3913             return;
3914
3915           }
3916         } else {
3917           /* Special cases for signed longs */
3918           if( (lit & 0xffffff) == 0) {
3919             /* lower byte is zero */
3920             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3921             i = ((lit >> 8*3) & 0xff) ^0x80;
3922             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3923             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3924             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3925             genSkipc(&rFalseIfx);
3926
3927
3928             if(ifx) ifx->generated = 1;
3929             return;
3930
3931           }
3932
3933         }
3934
3935
3936         if(lit & (0x80 << (size*8))) {
3937           /* lit is negative */
3938           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3939
3940           //genSkipCond(&rFalseIfx,left,size,7);
3941
3942           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3943
3944           if(rFalseIfx.condition)
3945             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3946           else
3947             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3948
3949
3950         } else {
3951           /* lit is positive */
3952           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3953           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954           if(rFalseIfx.condition)
3955             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
3956           else
3957             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
3958
3959         }
3960
3961         /*
3962           This works, but is only good for ints.
3963           It also requires a "known zero" register.
3964           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3965           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3966           pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
3967           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3968           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3969           genSkipc(&rFalseIfx);
3970
3971           pic16_emitpLabel(truelbl->key);
3972           if(ifx) ifx->generated = 1;
3973           return;
3974         **/
3975           
3976         /* There are no more special cases, so perform a general compare */
3977   
3978         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3979         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3980
3981         while(size--) {
3982
3983           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3984           emitSKPNZ;
3985           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3986         }
3987         //rFalseIfx.condition ^= 1;
3988         genSkipc(&rFalseIfx);
3989
3990         pic16_emitpLabel(truelbl->key);
3991
3992         if(ifx) ifx->generated = 1;
3993         return;
3994
3995
3996       }
3997
3998
3999       /* sign is out of the way. So now do an unsigned compare */
4000       DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4001
4002
4003       /* General case - compare to an unsigned literal on the right.*/
4004
4005       i = (lit >> (size*8)) & 0xff;
4006       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4007       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4008       while(size--) {
4009         i = (lit >> (size*8)) & 0xff;
4010
4011         if(i) {
4012           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4013           emitSKPNZ;
4014           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4015         } else {
4016           /* this byte of the lit is zero, 
4017            *if it's not the last then OR in the variable */
4018           if(size)
4019             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4020         }
4021       }
4022
4023
4024       pic16_emitpLabel(lbl->key);
4025       //if(emitFinalCheck)
4026       genSkipc(&rFalseIfx);
4027       if(sign)
4028         pic16_emitpLabel(truelbl->key);
4029
4030       if(ifx) ifx->generated = 1;
4031       return;
4032
4033
4034     }
4035 #endif  // _swapp
4036
4037     if(AOP_TYPE(left) == AOP_LIT) {
4038       //symbol *lbl = newiTempLabel(NULL);
4039
4040       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4041
4042
4043       DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4044
4045       /* Special cases */
4046       if((lit == 0) && (sign == 0)){
4047
4048         size--;
4049         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4050         while(size) 
4051           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4052
4053         genSkipz2(&rFalseIfx,0);
4054         if(ifx) ifx->generated = 1;
4055         return;
4056       }
4057
4058       if(size==1) {
4059         /* Special cases */
4060         lit &= 0xff;
4061         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4062           /* degenerate compare can never be true */
4063           if(rFalseIfx.condition == 0)
4064             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4065
4066           if(ifx) ifx->generated = 1;
4067           return;
4068         }
4069
4070         if(sign) {
4071           /* signed comparisons to a literal byte */
4072
4073           int lp1 = (lit+1) & 0xff;
4074
4075           DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4076           switch (lp1) {
4077           case 0:
4078             rFalseIfx.condition ^= 1;
4079             genSkipCond(&rFalseIfx,right,0,7);
4080             break;
4081           case 0x7f:
4082             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4083             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4084             genSkipz2(&rFalseIfx,1);
4085             break;
4086           default:
4087             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4088             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4089             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4090             rFalseIfx.condition ^= 1;
4091             genSkipc(&rFalseIfx);
4092             break;
4093           }
4094         } else {
4095           /* unsigned comparisons to a literal byte */
4096
4097           switch(lit & 0xff ) {
4098           case 0:
4099             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4100             genSkipz2(&rFalseIfx,0);
4101             break;
4102           case 0x7f:
4103             rFalseIfx.condition ^= 1;
4104             genSkipCond(&rFalseIfx,right,0,7);
4105             break;
4106
4107           default:
4108             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4109             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4110             DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4111             rFalseIfx.condition ^= 1;
4112             if (AOP_TYPE(result) == AOP_CRY)
4113               genSkipc(&rFalseIfx);
4114             else {
4115               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4116               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4117             }         
4118             break;
4119           }
4120         }
4121
4122         if(ifx) ifx->generated = 1;
4123         //goto check_carry;
4124         return;
4125
4126       } else {
4127
4128         /* Size is greater than 1 */
4129
4130         if(sign) {
4131           int lp1 = lit+1;
4132
4133           size--;
4134
4135           if(lp1 == 0) {
4136             /* this means lit = 0xffffffff, or -1 */
4137
4138
4139             DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4140             rFalseIfx.condition ^= 1;
4141             genSkipCond(&rFalseIfx,right,size,7);
4142             if(ifx) ifx->generated = 1;
4143             return;
4144           }
4145
4146           if(lit == 0) {
4147             int s = size;
4148
4149             if(rFalseIfx.condition) {
4150               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4151               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4152             }
4153
4154             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4155             while(size--)
4156               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4157
4158
4159             emitSKPZ;
4160             if(rFalseIfx.condition) {
4161               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4162               pic16_emitpLabel(truelbl->key);
4163             }else {
4164               rFalseIfx.condition ^= 1;
4165               genSkipCond(&rFalseIfx,right,s,7);
4166             }
4167
4168             if(ifx) ifx->generated = 1;
4169             return;
4170           }
4171
4172           if((size == 1) &&  (0 == (lp1&0xff))) {
4173             /* lower byte of signed word is zero */
4174             DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4175             i = ((lp1 >> 8) & 0xff) ^0x80;
4176             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4177             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4178             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4179             rFalseIfx.condition ^= 1;
4180             genSkipc(&rFalseIfx);
4181
4182
4183             if(ifx) ifx->generated = 1;
4184             return;
4185           }
4186
4187           if(lit & (0x80 << (size*8))) {
4188             /* Lit is less than zero */
4189             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4190             //rFalseIfx.condition ^= 1;
4191             //genSkipCond(&rFalseIfx,left,size,7);
4192             //rFalseIfx.condition ^= 1;
4193             pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4194             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4195
4196             if(rFalseIfx.condition)
4197               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4198             else
4199               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4200
4201
4202           } else {
4203             /* Lit is greater than or equal to zero */
4204             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4205             //rFalseIfx.condition ^= 1;
4206             //genSkipCond(&rFalseIfx,right,size,7);
4207             //rFalseIfx.condition ^= 1;
4208
4209             //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4210             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4211
4212             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4213             if(rFalseIfx.condition)
4214               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4215             else
4216               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4217
4218           }
4219
4220
4221           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4222           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4223
4224           while(size--) {
4225
4226             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4227             emitSKPNZ;
4228             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4229           }
4230           rFalseIfx.condition ^= 1;
4231           //rFalseIfx.condition = 1;
4232           genSkipc(&rFalseIfx);
4233
4234           pic16_emitpLabel(truelbl->key);
4235
4236           if(ifx) ifx->generated = 1;
4237           return;
4238           // end of if (sign)
4239         } else {
4240
4241           /* compare word or long to an unsigned literal on the right.*/
4242
4243
4244           size--;
4245           if(lit < 0xff) {
4246             DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4247             switch (lit) {
4248             case 0:
4249               break; /* handled above */
4250 /*
4251             case 0xff:
4252               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4253               while(size--)
4254                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4255               genSkipz2(&rFalseIfx,0);
4256               break;
4257 */
4258             default:
4259               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4260               while(--size)
4261                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4262
4263               emitSKPZ;
4264               if(rFalseIfx.condition)
4265                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4266               else
4267                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4268
4269
4270               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4271               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4272
4273               rFalseIfx.condition ^= 1;
4274               genSkipc(&rFalseIfx);
4275             }
4276
4277             pic16_emitpLabel(truelbl->key);
4278
4279             if(ifx) ifx->generated = 1;
4280             return;
4281           }
4282
4283
4284           lit++;
4285           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4286           i = (lit >> (size*8)) & 0xff;
4287
4288           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4289           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4290
4291           while(size--) {
4292             i = (lit >> (size*8)) & 0xff;
4293
4294             if(i) {
4295               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4296               emitSKPNZ;
4297               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4298             } else {
4299               /* this byte of the lit is zero, 
4300                *if it's not the last then OR in the variable */
4301               if(size)
4302                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4303             }
4304           }
4305
4306
4307           pic16_emitpLabel(lbl->key);
4308
4309           rFalseIfx.condition ^= 1;
4310           genSkipc(&rFalseIfx);
4311         }
4312
4313         if(sign)
4314           pic16_emitpLabel(truelbl->key);
4315         if(ifx) ifx->generated = 1;
4316         return;
4317       }
4318     }
4319     /* Compare two variables */
4320
4321     DEBUGpic16_emitcode(";sign","%d",sign);
4322
4323     size--;
4324     if(sign) {
4325       /* Sigh. thus sucks... */
4326       if(size) {
4327         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4328         pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4329         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4330         pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4331         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4332         pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4333       } else {
4334         /* Signed char comparison */
4335         /* Special thanks to Nikolai Golovchenko for this snippet */
4336         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4337         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4338         pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
4339         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4340         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4341         pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4342
4343         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4344         genSkipc(&rFalseIfx);
4345           
4346         if(ifx) ifx->generated = 1;
4347         return;
4348       }
4349
4350     } else {
4351
4352       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4353       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4354     }
4355
4356
4357     /* The rest of the bytes of a multi-byte compare */
4358     while (size) {
4359
4360       emitSKPZ;
4361       pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
4362       size--;
4363
4364       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4365       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4366
4367
4368     }
4369
4370     pic16_emitpLabel(lbl->key);
4371
4372     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4373     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4374         (AOP_TYPE(result) == AOP_REG)) {
4375       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4376       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4377     } else {
4378       genSkipc(&rFalseIfx);
4379     }         
4380     //genSkipc(&rFalseIfx);
4381     if(ifx) ifx->generated = 1;
4382
4383     return;
4384
4385   }
4386
4387   // check_carry:
4388   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4389     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4390     pic16_outBitC(result);
4391   } else {
4392     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4393     /* if the result is used in the next
4394        ifx conditional branch then generate
4395        code a little differently */
4396     if (ifx )
4397       genIfxJump (ifx,"c");
4398     else
4399       pic16_outBitC(result);
4400     /* leave the result in acc */
4401   }
4402
4403 }
4404
4405 /*-----------------------------------------------------------------*/
4406 /* genCmpGt :- greater than comparison                             */
4407 /*-----------------------------------------------------------------*/
4408 static void genCmpGt (iCode *ic, iCode *ifx)
4409 {
4410     operand *left, *right, *result;
4411     sym_link *letype , *retype;
4412     int sign ;
4413
4414     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4415     left = IC_LEFT(ic);
4416     right= IC_RIGHT(ic);
4417     result = IC_RESULT(ic);
4418
4419     letype = getSpec(operandType(left));
4420     retype =getSpec(operandType(right));
4421     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4422     /* assign the amsops */
4423     pic16_aopOp (left,ic,FALSE);
4424     pic16_aopOp (right,ic,FALSE);
4425     pic16_aopOp (result,ic,TRUE);
4426
4427     genCmp(right, left, result, ifx, sign);
4428
4429     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4430     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4431     pic16_freeAsmop(result,NULL,ic,TRUE); 
4432 }
4433
4434 /*-----------------------------------------------------------------*/
4435 /* genCmpLt - less than comparisons                                */
4436 /*-----------------------------------------------------------------*/
4437 static void genCmpLt (iCode *ic, iCode *ifx)
4438 {
4439     operand *left, *right, *result;
4440     sym_link *letype , *retype;
4441     int sign ;
4442
4443     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4444     left = IC_LEFT(ic);
4445     right= IC_RIGHT(ic);
4446     result = IC_RESULT(ic);
4447
4448     letype = getSpec(operandType(left));
4449     retype =getSpec(operandType(right));
4450     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4451
4452     /* assign the amsops */
4453     pic16_aopOp (left,ic,FALSE);
4454     pic16_aopOp (right,ic,FALSE);
4455     pic16_aopOp (result,ic,TRUE);
4456
4457     genCmp(left, right, result, ifx, sign);
4458
4459     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4460     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4461     pic16_freeAsmop(result,NULL,ic,TRUE); 
4462 }
4463
4464 /*-----------------------------------------------------------------*/
4465 /* genc16bit2lit - compare a 16 bit value to a literal             */
4466 /*-----------------------------------------------------------------*/
4467 static void genc16bit2lit(operand *op, int lit, int offset)
4468 {
4469   int i;
4470
4471   DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4472   if( (lit&0xff) == 0) 
4473     i=1;
4474   else
4475     i=0;
4476
4477   switch( BYTEofLONG(lit,i)) { 
4478   case 0:
4479     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4480     break;
4481   case 1:
4482     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4483     break;
4484   case 0xff:
4485     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4486     break;
4487   default:
4488     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4489     pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4490   }
4491
4492   i ^= 1;
4493
4494   switch( BYTEofLONG(lit,i)) { 
4495   case 0:
4496     pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4497     break;
4498   case 1:
4499     emitSKPNZ;
4500     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4501     break;
4502   case 0xff:
4503     emitSKPNZ;
4504     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4505     break;
4506   default:
4507     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4508     emitSKPNZ;
4509     pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4510
4511   }
4512
4513 }
4514
4515 /*-----------------------------------------------------------------*/
4516 /* gencjneshort - compare and jump if not equal                    */
4517 /*-----------------------------------------------------------------*/
4518 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4519 {
4520   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4521   int offset = 0;
4522   int res_offset = 0;  /* the result may be a different size then left or right */
4523   int res_size = AOP_SIZE(result);
4524   resolvedIfx rIfx;
4525   symbol *lbl;
4526
4527   unsigned long lit = 0L;
4528   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4529   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4530   if(result)
4531     DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4532   resolveIfx(&rIfx,ifx);
4533   lbl =  newiTempLabel(NULL);
4534
4535
4536   /* if the left side is a literal or 
4537      if the right is in a pointer register and left 
4538      is not */
4539   if ((AOP_TYPE(left) == AOP_LIT) || 
4540       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4541     operand *t = right;
4542     right = left;
4543     left = t;
4544   }
4545   if(AOP_TYPE(right) == AOP_LIT)
4546     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4547
4548   /* if the right side is a literal then anything goes */
4549   if (AOP_TYPE(right) == AOP_LIT &&
4550       AOP_TYPE(left) != AOP_DIR ) {
4551     switch(size) {
4552     case 2:
4553       genc16bit2lit(left, lit, 0);
4554       emitSKPNZ;
4555       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4556       break;
4557     default:
4558       while (size--) {
4559         if(lit & 0xff) {
4560           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4561           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4562         } else {
4563           pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4564         }
4565
4566         emitSKPNZ;
4567         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4568         offset++;
4569         if(res_offset < res_size-1)
4570           res_offset++;
4571         lit >>= 8;
4572       }
4573       break;
4574     }
4575   }
4576
4577   /* if the right side is in a register or in direct space or
4578      if the left is a pointer register & right is not */    
4579   else if (AOP_TYPE(right) == AOP_REG ||
4580            AOP_TYPE(right) == AOP_DIR || 
4581            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4582            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4583     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4584     int lbl_key = lbl->key;
4585
4586     if(result) {
4587       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4588       //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4589     }else {
4590       DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4591       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4592               __FUNCTION__,__LINE__);
4593       return;
4594     }
4595
4596 /*     switch(size) { */
4597 /*     case 2: */
4598 /*       genc16bit2lit(left, lit, 0); */
4599 /*       emitSKPNZ; */
4600 /*       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4601 /*       break; */
4602 /*     default: */
4603     while (size--) {
4604       int emit_skip=1;
4605       if((AOP_TYPE(left) == AOP_DIR) && 
4606          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4607
4608         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4609         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4610
4611       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4612             
4613         switch (lit & 0xff) {
4614         case 0:
4615           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4616           break;
4617         case 1:
4618           pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4619           pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4620           //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4621           emit_skip=0;
4622           break;
4623         case 0xff:
4624           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4625           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4626           //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4627           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4628           emit_skip=0;
4629           break;
4630         default:
4631           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4632           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4633         }
4634         lit >>= 8;
4635
4636       } else {
4637         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4638       }
4639       if(emit_skip) {
4640         if(AOP_TYPE(result) == AOP_CRY) {
4641           pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4642           if(rIfx.condition)
4643             emitSKPNZ;
4644           else
4645             emitSKPZ;
4646           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4647         } else {
4648           /* fix me. probably need to check result size too */
4649           //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4650           if(rIfx.condition)
4651             emitSKPZ;
4652           else
4653             emitSKPNZ;
4654           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4655           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4656         }
4657         if(ifx)
4658           ifx->generated=1;
4659       }
4660       emit_skip++;
4661       offset++;
4662       if(res_offset < res_size-1)
4663         res_offset++;
4664     }
4665 /*       break; */
4666 /*     } */
4667   } else if(AOP_TYPE(right) == AOP_REG &&
4668             AOP_TYPE(left) != AOP_DIR){
4669
4670     while(size--) {
4671       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4672       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4673       pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4674       if(rIfx.condition)
4675         emitSKPNZ;
4676       else
4677         emitSKPZ;
4678       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4679       offset++;
4680       if(res_offset < res_size-1)
4681         res_offset++;
4682     }
4683       
4684   }else{
4685     /* right is a pointer reg need both a & b */
4686     while(size--) {
4687       char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4688       if(strcmp(l,"b"))
4689         pic16_emitcode("mov","b,%s",l);
4690       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4691       pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4692       offset++;
4693     }
4694   }
4695
4696   pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4697   if(!rIfx.condition)
4698     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4699
4700   pic16_emitpLabel(lbl->key);
4701
4702   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4703
4704   if(ifx)
4705     ifx->generated = 1;
4706 }
4707
4708 #if 0
4709 /*-----------------------------------------------------------------*/
4710 /* gencjne - compare and jump if not equal                         */
4711 /*-----------------------------------------------------------------*/
4712 static void gencjne(operand *left, operand *right, iCode *ifx)
4713 {
4714     symbol *tlbl  = newiTempLabel(NULL);
4715
4716     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4717     gencjneshort(left, right, lbl);
4718
4719     pic16_emitcode("mov","a,%s",one);
4720     pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4721     pic16_emitcode("","%05d_DS_:",lbl->key+100);
4722     pic16_emitcode("clr","a");
4723     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4724
4725     pic16_emitpLabel(lbl->key);
4726     pic16_emitpLabel(tlbl->key);
4727
4728 }
4729 #endif
4730
4731 /*-----------------------------------------------------------------*/
4732 /* genCmpEq - generates code for equal to                          */
4733 /*-----------------------------------------------------------------*/
4734 static void genCmpEq (iCode *ic, iCode *ifx)
4735 {
4736     operand *left, *right, *result;
4737     unsigned long lit = 0L;
4738     int size,offset=0;
4739
4740     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4741
4742     if(ifx)
4743       DEBUGpic16_emitcode ("; ifx is non-null","");
4744     else
4745       DEBUGpic16_emitcode ("; ifx is null","");
4746
4747     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4748     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4749     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4750
4751     size = max(AOP_SIZE(left),AOP_SIZE(right));
4752
4753     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4754
4755     /* if literal, literal on the right or 
4756     if the right is in a pointer register and left 
4757     is not */
4758     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4759         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4760       operand *tmp = right ;
4761       right = left;
4762       left = tmp;
4763     }
4764
4765
4766     if(ifx && !AOP_SIZE(result)){
4767         symbol *tlbl;
4768         /* if they are both bit variables */
4769         if (AOP_TYPE(left) == AOP_CRY &&
4770             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4771             if(AOP_TYPE(right) == AOP_LIT){
4772                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4773                 if(lit == 0L){
4774                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4775                     pic16_emitcode("cpl","c");
4776                 } else if(lit == 1L) {
4777                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4778                 } else {
4779                     pic16_emitcode("clr","c");
4780                 }
4781                 /* AOP_TYPE(right) == AOP_CRY */
4782             } else {
4783                 symbol *lbl = newiTempLabel(NULL);
4784                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785                 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4786                 pic16_emitcode("cpl","c");
4787                 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4788             }
4789             /* if true label then we jump if condition
4790             supplied is true */
4791             tlbl = newiTempLabel(NULL);
4792             if ( IC_TRUE(ifx) ) {
4793                 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4794                 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4795             } else {
4796                 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4797                 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4798             }
4799             pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4800
4801             {
4802               /* left and right are both bit variables, result is carry */
4803               resolvedIfx rIfx;
4804               
4805               resolveIfx(&rIfx,ifx);
4806
4807               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4808               pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4809               pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4810               pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4811               genSkipz2(&rIfx,0);
4812             }
4813         } else {
4814
4815           /* They're not both bit variables. Is the right a literal? */
4816           if(AOP_TYPE(right) == AOP_LIT) {
4817             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4818             
4819             switch(size) {
4820
4821             case 1:
4822               switch(lit & 0xff) {
4823               case 1:
4824                 if ( IC_TRUE(ifx) ) {
4825                   pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4826                   emitSKPNZ;
4827                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4828                 } else {
4829                   pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4830                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4831                 }
4832                 break;
4833               case 0xff:
4834                 if ( IC_TRUE(ifx) ) {
4835                   pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4836                   emitSKPNZ;
4837                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4838                 } else {
4839                   pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4840                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4841                 }
4842                 break;
4843               default:
4844                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4845                 if(lit)
4846                   pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4847                 genSkip(ifx,'z');
4848               }
4849
4850
4851               /* end of size == 1 */
4852               break;
4853               
4854             case 2:
4855               genc16bit2lit(left,lit,offset);
4856               genSkip(ifx,'z');
4857               break;
4858               /* end of size == 2 */
4859
4860             default:
4861               /* size is 4 */
4862               if(lit==0) {
4863                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4864                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4865                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4866                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4867
4868               } else {
4869
4870                 /* search for patterns that can be optimized */
4871
4872                 genc16bit2lit(left,lit,0);
4873                 lit >>= 16;
4874                 if(lit) {
4875                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4876                   //genSkip(ifx,'z');
4877                   genc16bit2lit(left,lit,2);
4878                 } else {
4879                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4880                   pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4881
4882                 }
4883                 
4884               }
4885
4886               genSkip(ifx,'z');
4887             }
4888           
4889             ifx->generated = 1;
4890             goto release ;
4891             
4892
4893           } else if(AOP_TYPE(right) == AOP_CRY ) {
4894             /* we know the left is not a bit, but that the right is */
4895             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4896             pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4897                       pic16_popGet(AOP(right),offset));
4898             pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4899
4900             /* if the two are equal, then W will be 0 and the Z bit is set
4901              * we could test Z now, or go ahead and check the high order bytes if
4902              * the variable we're comparing is larger than a byte. */
4903
4904             while(--size)
4905               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4906
4907             if ( IC_TRUE(ifx) ) {
4908               emitSKPNZ;
4909               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4910               pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4911             } else {
4912               emitSKPZ;
4913               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4914               pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4915             }
4916
4917           } else {
4918             /* They're both variables that are larger than bits */
4919             int s = size;
4920
4921             tlbl = newiTempLabel(NULL);
4922
4923             while(size--) {
4924               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4925               pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4926
4927               if ( IC_TRUE(ifx) ) {
4928                 if(size) {
4929                   emitSKPZ;
4930                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4931                   pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4932                 } else {
4933                   emitSKPNZ;
4934                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4935                   pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4936                 }
4937               } else {
4938                 emitSKPZ;
4939                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4940                 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4941               }
4942               offset++;
4943             }
4944             if(s>1 && IC_TRUE(ifx)) {
4945               pic16_emitpLabel(tlbl->key);
4946               pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4947             }
4948           }
4949         }
4950         /* mark the icode as generated */
4951         ifx->generated = 1;
4952         goto release ;
4953     }
4954
4955     /* if they are both bit variables */
4956     if (AOP_TYPE(left) == AOP_CRY &&
4957         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4958         if(AOP_TYPE(right) == AOP_LIT){
4959             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4960             if(lit == 0L){
4961                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4962                 pic16_emitcode("cpl","c");
4963             } else if(lit == 1L) {
4964                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4965             } else {
4966                 pic16_emitcode("clr","c");
4967             }
4968             /* AOP_TYPE(right) == AOP_CRY */
4969         } else {
4970             symbol *lbl = newiTempLabel(NULL);
4971             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972             pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4973             pic16_emitcode("cpl","c");
4974             pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4975         }
4976         /* c = 1 if egal */
4977         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4978             pic16_outBitC(result);
4979             goto release ;
4980         }
4981         if (ifx) {
4982             genIfxJump (ifx,"c");
4983             goto release ;
4984         }
4985         /* if the result is used in an arithmetic operation
4986         then put the result in place */
4987         pic16_outBitC(result);
4988     } else {
4989       
4990       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4991       gencjne(left,right,result,ifx);
4992 /*
4993       if(ifx) 
4994         gencjne(left,right,newiTempLabel(NULL));
4995       else {
4996         if(IC_TRUE(ifx)->key)
4997           gencjne(left,right,IC_TRUE(ifx)->key);
4998         else
4999           gencjne(left,right,IC_FALSE(ifx)->key);
5000         ifx->generated = 1;
5001         goto release ;
5002       }
5003       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5004         pic16_aopPut(AOP(result),"a",0);
5005         goto release ;
5006       }
5007
5008       if (ifx) {
5009         genIfxJump (ifx,"a");
5010         goto release ;
5011       }
5012 */
5013       /* if the result is used in an arithmetic operation
5014          then put the result in place */
5015 /*
5016       if (AOP_TYPE(result) != AOP_CRY) 
5017         pic16_outAcc(result);
5018 */
5019       /* leave the result in acc */
5020     }
5021
5022 release:
5023     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5024     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5025     pic16_freeAsmop(result,NULL,ic,TRUE);
5026 }
5027
5028 /*-----------------------------------------------------------------*/
5029 /* ifxForOp - returns the icode containing the ifx for operand     */
5030 /*-----------------------------------------------------------------*/
5031 static iCode *ifxForOp ( operand *op, iCode *ic )
5032 {
5033     /* if true symbol then needs to be assigned */
5034     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5035     if (IS_TRUE_SYMOP(op))
5036         return NULL ;
5037
5038     /* if this has register type condition and
5039     the next instruction is ifx with the same operand
5040     and live to of the operand is upto the ifx only then */
5041     if (ic->next &&
5042         ic->next->op == IFX &&
5043         IC_COND(ic->next)->key == op->key &&
5044         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5045         return ic->next;
5046
5047     if (ic->next &&
5048         ic->next->op == IFX &&
5049         IC_COND(ic->next)->key == op->key) {
5050       DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5051       return ic->next;
5052     }
5053
5054     DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5055     if (ic->next &&
5056         ic->next->op == IFX)
5057       DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5058
5059     if (ic->next &&
5060         ic->next->op == IFX &&
5061         IC_COND(ic->next)->key == op->key) {
5062       DEBUGpic16_emitcode ("; "," key is okay");
5063       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5064                            OP_SYMBOL(op)->liveTo,
5065                            ic->next->seq);
5066     }
5067
5068
5069     return NULL;
5070 }
5071 /*-----------------------------------------------------------------*/
5072 /* genAndOp - for && operation                                     */
5073 /*-----------------------------------------------------------------*/
5074 static void genAndOp (iCode *ic)
5075 {
5076     operand *left,*right, *result;
5077 /*     symbol *tlbl; */
5078
5079     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5080     /* note here that && operations that are in an
5081     if statement are taken away by backPatchLabels
5082     only those used in arthmetic operations remain */
5083     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5084     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5085     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5086
5087     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5088
5089     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5090     pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5091     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5092
5093     /* if both are bit variables */
5094 /*     if (AOP_TYPE(left) == AOP_CRY && */
5095 /*         AOP_TYPE(right) == AOP_CRY ) { */
5096 /*         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5097 /*         pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5098 /*         pic16_outBitC(result); */
5099 /*     } else { */
5100 /*         tlbl = newiTempLabel(NULL); */
5101 /*         pic16_toBoolean(left);     */
5102 /*         pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5103 /*         pic16_toBoolean(right); */
5104 /*         pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5105 /*         pic16_outBitAcc(result); */
5106 /*     } */
5107
5108     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5109     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110     pic16_freeAsmop(result,NULL,ic,TRUE);
5111 }
5112
5113
5114 /*-----------------------------------------------------------------*/
5115 /* genOrOp - for || operation                                      */
5116 /*-----------------------------------------------------------------*/
5117 /*
5118   tsd pic port -
5119   modified this code, but it doesn't appear to ever get called
5120 */
5121
5122 static void genOrOp (iCode *ic)
5123 {
5124     operand *left,*right, *result;
5125     symbol *tlbl;
5126
5127     /* note here that || operations that are in an
5128     if statement are taken away by backPatchLabels
5129     only those used in arthmetic operations remain */
5130     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5131     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5132     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5133     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5134
5135     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5136
5137     /* if both are bit variables */
5138     if (AOP_TYPE(left) == AOP_CRY &&
5139         AOP_TYPE(right) == AOP_CRY ) {
5140       pic16_emitcode("clrc","");
5141       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5142                AOP(left)->aopu.aop_dir,
5143                AOP(left)->aopu.aop_dir);
5144       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5145                AOP(right)->aopu.aop_dir,
5146                AOP(right)->aopu.aop_dir);
5147       pic16_emitcode("setc","");
5148
5149     } else {
5150         tlbl = newiTempLabel(NULL);
5151         pic16_toBoolean(left);
5152         emitSKPZ;
5153         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5154         pic16_toBoolean(right);
5155         pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5156
5157         pic16_outBitAcc(result);
5158     }
5159
5160     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5161     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5162     pic16_freeAsmop(result,NULL,ic,TRUE);            
5163 }
5164
5165 /*-----------------------------------------------------------------*/
5166 /* isLiteralBit - test if lit == 2^n                               */
5167 /*-----------------------------------------------------------------*/
5168 static int isLiteralBit(unsigned long lit)
5169 {
5170     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5171     0x100L,0x200L,0x400L,0x800L,
5172     0x1000L,0x2000L,0x4000L,0x8000L,
5173     0x10000L,0x20000L,0x40000L,0x80000L,
5174     0x100000L,0x200000L,0x400000L,0x800000L,
5175     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5176     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5177     int idx;
5178     
5179     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5180     for(idx = 0; idx < 32; idx++)
5181         if(lit == pw[idx])
5182             return idx+1;
5183     return 0;
5184 }
5185
5186 /*-----------------------------------------------------------------*/
5187 /* continueIfTrue -                                                */
5188 /*-----------------------------------------------------------------*/
5189 static void continueIfTrue (iCode *ic)
5190 {
5191     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5192     if(IC_TRUE(ic))
5193         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5194     ic->generated = 1;
5195 }
5196
5197 /*-----------------------------------------------------------------*/
5198 /* jmpIfTrue -                                                     */
5199 /*-----------------------------------------------------------------*/
5200 static void jumpIfTrue (iCode *ic)
5201 {
5202     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5203     if(!IC_TRUE(ic))
5204         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5205     ic->generated = 1;
5206 }
5207
5208 /*-----------------------------------------------------------------*/
5209 /* jmpTrueOrFalse -                                                */
5210 /*-----------------------------------------------------------------*/
5211 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5212 {
5213     // ugly but optimized by peephole
5214     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5215     if(IC_TRUE(ic)){
5216         symbol *nlbl = newiTempLabel(NULL);
5217         pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5218         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5219         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5220         pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5221     }
5222     else{
5223         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5224         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5225     }
5226     ic->generated = 1;
5227 }
5228
5229 /*-----------------------------------------------------------------*/
5230 /* genAnd  - code for and                                          */
5231 /*-----------------------------------------------------------------*/
5232 static void genAnd (iCode *ic, iCode *ifx)
5233 {
5234   operand *left, *right, *result;
5235   int size, offset=0;  
5236   unsigned long lit = 0L;
5237   int bytelit = 0;
5238   resolvedIfx rIfx;
5239
5240
5241   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5242   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5243   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5244   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5245
5246   resolveIfx(&rIfx,ifx);
5247
5248   /* if left is a literal & right is not then exchange them */
5249   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5250       AOP_NEEDSACC(left)) {
5251     operand *tmp = right ;
5252     right = left;
5253     left = tmp;
5254   }
5255
5256   /* if result = right then exchange them */
5257   if(pic16_sameRegs(AOP(result),AOP(right))){
5258     operand *tmp = right ;
5259     right = left;
5260     left = tmp;
5261   }
5262
5263   /* if right is bit then exchange them */
5264   if (AOP_TYPE(right) == AOP_CRY &&
5265       AOP_TYPE(left) != AOP_CRY){
5266     operand *tmp = right ;
5267     right = left;
5268     left = tmp;
5269   }
5270   if(AOP_TYPE(right) == AOP_LIT)
5271     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5272
5273   size = AOP_SIZE(result);
5274
5275   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5276
5277   // if(bit & yy)
5278   // result = bit & yy;
5279   if (AOP_TYPE(left) == AOP_CRY){
5280     // c = bit & literal;
5281     if(AOP_TYPE(right) == AOP_LIT){
5282       if(lit & 1) {
5283         if(size && pic16_sameRegs(AOP(result),AOP(left)))
5284           // no change
5285           goto release;
5286         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5287       } else {
5288         // bit(result) = 0;
5289         if(size && (AOP_TYPE(result) == AOP_CRY)){
5290           pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5291           goto release;
5292         }
5293         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5294           jumpIfTrue(ifx);
5295           goto release;
5296         }
5297         pic16_emitcode("clr","c");
5298       }
5299     } else {
5300       if (AOP_TYPE(right) == AOP_CRY){
5301         // c = bit & bit;
5302         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5303         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5304       } else {
5305         // c = bit & val;
5306         MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5307         // c = lsb
5308         pic16_emitcode("rrc","a");
5309         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5310       }
5311     }
5312     // bit = c
5313     // val = c
5314     if(size)
5315       pic16_outBitC(result);
5316     // if(bit & ...)
5317     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5318       genIfxJump(ifx, "c");           
5319     goto release ;
5320   }
5321
5322   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5323   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5324   if((AOP_TYPE(right) == AOP_LIT) &&
5325      (AOP_TYPE(result) == AOP_CRY) &&
5326      (AOP_TYPE(left) != AOP_CRY)){
5327     int posbit = isLiteralBit(lit);
5328     /* left &  2^n */
5329     if(posbit){
5330       posbit--;
5331       //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5332       // bit = left & 2^n
5333       if(size)
5334         pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5335       // if(left &  2^n)
5336       else{
5337         if(ifx){
5338 /*
5339           if(IC_TRUE(ifx)) {
5340             pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5341             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5342           } else {
5343             pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5344             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5345           }
5346 */
5347           pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5348                     pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5349           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5350           
5351           ifx->generated = 1;
5352         }
5353         goto release;
5354       }
5355     } else {
5356       symbol *tlbl = newiTempLabel(NULL);
5357       int sizel = AOP_SIZE(left);
5358       if(size)
5359         pic16_emitcode("setb","c");
5360       while(sizel--){
5361         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5362           MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5363           // byte ==  2^n ?
5364           if((posbit = isLiteralBit(bytelit)) != 0)
5365             pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5366           else{
5367             if(bytelit != 0x0FFL)
5368               pic16_emitcode("anl","a,%s",
5369                              pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5370             pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5371           }
5372         }
5373         offset++;
5374       }
5375       // bit = left & literal
5376       if(size){
5377         pic16_emitcode("clr","c");
5378         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5379       }
5380       // if(left & literal)
5381       else{
5382         if(ifx)
5383           jmpTrueOrFalse(ifx, tlbl);
5384         goto release ;
5385       }
5386     }
5387     pic16_outBitC(result);
5388     goto release ;
5389   }
5390
5391   /* if left is same as result */
5392   if(pic16_sameRegs(AOP(result),AOP(left))){
5393     int know_W = -1;
5394     for(;size--; offset++,lit>>=8) {
5395       if(AOP_TYPE(right) == AOP_LIT){
5396         switch(lit & 0xff) {
5397         case 0x00:
5398           /*  and'ing with 0 has clears the result */
5399           pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5400           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5401           break;
5402         case 0xff:
5403           /* and'ing with 0xff is a nop when the result and left are the same */
5404           break;
5405
5406         default:
5407           {
5408             int p = my_powof2( (~lit) & 0xff );
5409             if(p>=0) {
5410               /* only one bit is set in the literal, so use a bcf instruction */
5411               pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5412               pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5413
5414             } else {
5415               pic16_emitcode("movlw","0x%x", (lit & 0xff));
5416               pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5417               if(know_W != (lit&0xff))
5418                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5419               know_W = lit &0xff;
5420               pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5421             }
5422           }    
5423         }
5424       } else {
5425         if (AOP_TYPE(left) == AOP_ACC) {
5426           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5427         } else {                    
5428           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5429           pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5430
5431         }
5432       }
5433     }
5434
5435   } else {
5436     // left & result in different registers
5437     if(AOP_TYPE(result) == AOP_CRY){
5438       // result = bit
5439       // if(size), result in bit
5440       // if(!size && ifx), conditional oper: if(left & right)
5441       symbol *tlbl = newiTempLabel(NULL);
5442       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5443       if(size)
5444         pic16_emitcode("setb","c");
5445       while(sizer--){
5446         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5447         pic16_emitcode("anl","a,%s",
5448                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5449         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5450         offset++;
5451       }
5452       if(size){
5453         CLRC;
5454         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5455         pic16_outBitC(result);
5456       } else if(ifx)
5457         jmpTrueOrFalse(ifx, tlbl);
5458     } else {
5459       for(;(size--);offset++) {
5460         // normal case
5461         // result = left & right
5462         if(AOP_TYPE(right) == AOP_LIT){
5463           int t = (lit >> (offset*8)) & 0x0FFL;
5464           switch(t) { 
5465           case 0x00:
5466             pic16_emitcode("clrf","%s",
5467                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5468             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5469             break;
5470           case 0xff:
5471             pic16_emitcode("movf","%s,w",
5472                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5473             pic16_emitcode("movwf","%s",
5474                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5475             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5476             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5477             break;
5478           default:
5479             pic16_emitcode("movlw","0x%x",t);
5480             pic16_emitcode("andwf","%s,w",
5481                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5482             pic16_emitcode("movwf","%s",
5483                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5484               
5485             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5486             pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5487             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5488           }
5489           continue;
5490         }
5491
5492         if (AOP_TYPE(left) == AOP_ACC) {
5493           pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5494           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5495         } else {
5496           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5497           pic16_emitcode("andwf","%s,w",
5498                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5499           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5500           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5501         }
5502         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5503         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5504       }
5505     }
5506   }
5507
5508   release :
5509     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5510   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511   pic16_freeAsmop(result,NULL,ic,TRUE);     
5512 }
5513
5514 /*-----------------------------------------------------------------*/
5515 /* genOr  - code for or                                            */
5516 /*-----------------------------------------------------------------*/
5517 static void genOr (iCode *ic, iCode *ifx)
5518 {
5519     operand *left, *right, *result;
5520     int size, offset=0;
5521     unsigned long lit = 0L;
5522
5523     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5524
5525     pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5526     pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5527     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5528
5529     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5530
5531     /* if left is a literal & right is not then exchange them */
5532     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5533         AOP_NEEDSACC(left)) {
5534         operand *tmp = right ;
5535         right = left;
5536         left = tmp;
5537     }
5538
5539     /* if result = right then exchange them */
5540     if(pic16_sameRegs(AOP(result),AOP(right))){
5541         operand *tmp = right ;
5542         right = left;
5543         left = tmp;
5544     }
5545
5546     /* if right is bit then exchange them */
5547     if (AOP_TYPE(right) == AOP_CRY &&
5548         AOP_TYPE(left) != AOP_CRY){
5549         operand *tmp = right ;
5550         right = left;
5551         left = tmp;
5552     }
5553
5554     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5555
5556     if(AOP_TYPE(right) == AOP_LIT)
5557         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5558
5559     size = AOP_SIZE(result);
5560
5561     // if(bit | yy)
5562     // xx = bit | yy;
5563     if (AOP_TYPE(left) == AOP_CRY){
5564         if(AOP_TYPE(right) == AOP_LIT){
5565             // c = bit & literal;
5566             if(lit){
5567                 // lit != 0 => result = 1
5568                 if(AOP_TYPE(result) == AOP_CRY){
5569                   if(size)
5570                     pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5571                   //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5572                   //     AOP(result)->aopu.aop_dir,
5573                   //     AOP(result)->aopu.aop_dir);
5574                     else if(ifx)
5575                         continueIfTrue(ifx);
5576                     goto release;
5577                 }
5578             } else {
5579                 // lit == 0 => result = left
5580                 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5581                     goto release;
5582                 pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5583             }
5584         } else {
5585             if (AOP_TYPE(right) == AOP_CRY){
5586               if(pic16_sameRegs(AOP(result),AOP(left))){
5587                 // c = bit | bit;
5588                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5589                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5590                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5591
5592                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5593                          AOP(result)->aopu.aop_dir,
5594                          AOP(result)->aopu.aop_dir);
5595                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5596                          AOP(right)->aopu.aop_dir,
5597                          AOP(right)->aopu.aop_dir);
5598                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5599                          AOP(result)->aopu.aop_dir,
5600                          AOP(result)->aopu.aop_dir);
5601               } else {
5602                 if( AOP_TYPE(result) == AOP_ACC) {
5603                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5604                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5605                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5606                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5607
5608                 } else {
5609
5610                   pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5611                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5612                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5613                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5614
5615                   pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5616                                  AOP(result)->aopu.aop_dir,
5617                                  AOP(result)->aopu.aop_dir);
5618                   pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5619                                  AOP(right)->aopu.aop_dir,
5620                                  AOP(right)->aopu.aop_dir);
5621                   pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5622                                  AOP(left)->aopu.aop_dir,
5623                                  AOP(left)->aopu.aop_dir);
5624                   pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5625                                  AOP(result)->aopu.aop_dir,
5626                                  AOP(result)->aopu.aop_dir);
5627                 }
5628               }
5629             } else {
5630                 // c = bit | val;
5631                 symbol *tlbl = newiTempLabel(NULL);
5632                 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5633
5634
5635                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
5636                 if( AOP_TYPE(right) == AOP_ACC) {
5637                   pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5638                   emitSKPNZ;
5639                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5640                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
5641                 }
5642
5643
5644
5645                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5646                     pic16_emitcode(";XXX setb","c");
5647                 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5648                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5649                 pic16_toBoolean(right);
5650                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5651                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5652                     jmpTrueOrFalse(ifx, tlbl);
5653                     goto release;
5654                 } else {
5655                     CLRC;
5656                     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5657                 }
5658             }
5659         }
5660         // bit = c
5661         // val = c
5662         if(size)
5663             pic16_outBitC(result);
5664         // if(bit | ...)
5665         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5666             genIfxJump(ifx, "c");           
5667         goto release ;
5668     }
5669
5670     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5671     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5672     if((AOP_TYPE(right) == AOP_LIT) &&
5673        (AOP_TYPE(result) == AOP_CRY) &&
5674        (AOP_TYPE(left) != AOP_CRY)){
5675         if(lit){
5676           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5677             // result = 1
5678             if(size)
5679                 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5680             else 
5681                 continueIfTrue(ifx);
5682             goto release;
5683         } else {
5684           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5685             // lit = 0, result = boolean(left)
5686             if(size)
5687                 pic16_emitcode(";XXX setb","c");
5688             pic16_toBoolean(right);
5689             if(size){
5690                 symbol *tlbl = newiTempLabel(NULL);
5691                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5692                 CLRC;
5693                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5694             } else {
5695                 genIfxJump (ifx,"a");
5696                 goto release;
5697             }
5698         }
5699         pic16_outBitC(result);
5700         goto release ;
5701     }
5702
5703     /* if left is same as result */
5704     if(pic16_sameRegs(AOP(result),AOP(left))){
5705       int know_W = -1;
5706       for(;size--; offset++,lit>>=8) {
5707         if(AOP_TYPE(right) == AOP_LIT){
5708           if((lit & 0xff) == 0)
5709             /*  or'ing with 0 has no effect */
5710             continue;
5711           else {
5712             int p = my_powof2(lit & 0xff);
5713             if(p>=0) {
5714               /* only one bit is set in the literal, so use a bsf instruction */
5715               pic16_emitpcode(POC_BSF,
5716                         pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5717             } else {
5718               if(know_W != (lit & 0xff))
5719                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5720               know_W = lit & 0xff;
5721               pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5722             }
5723                     
5724           }
5725         } else {
5726           if (AOP_TYPE(left) == AOP_ACC) {
5727             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
5728             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5729           } else {                  
5730             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5731             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
5732
5733             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5734             pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5735
5736           }
5737         }
5738       }
5739     } else {
5740         // left & result in different registers
5741         if(AOP_TYPE(result) == AOP_CRY){
5742             // result = bit
5743             // if(size), result in bit
5744             // if(!size && ifx), conditional oper: if(left | right)
5745             symbol *tlbl = newiTempLabel(NULL);
5746             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5747             pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5748
5749
5750             if(size)
5751                 pic16_emitcode(";XXX setb","c");
5752             while(sizer--){
5753                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5754                 pic16_emitcode(";XXX orl","a,%s",
5755                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5756                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5757                 offset++;
5758             }
5759             if(size){
5760                 CLRC;
5761                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5762                 pic16_outBitC(result);
5763             } else if(ifx)
5764                 jmpTrueOrFalse(ifx, tlbl);
5765         } else for(;(size--);offset++){
5766           // normal case
5767           // result = left & right
5768           if(AOP_TYPE(right) == AOP_LIT){
5769             int t = (lit >> (offset*8)) & 0x0FFL;
5770             switch(t) { 
5771             case 0x00:
5772               pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
5773               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5774
5775               pic16_emitcode("movf","%s,w",
5776                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5777               pic16_emitcode("movwf","%s",
5778                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5779               break;
5780             default:
5781               pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
5782               pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5783               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5784
5785               pic16_emitcode("movlw","0x%x",t);
5786               pic16_emitcode("iorwf","%s,w",
5787                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5788               pic16_emitcode("movwf","%s",
5789                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5790               
5791             }
5792             continue;
5793           }
5794
5795           // faster than result <- left, anl result,right
5796           // and better if result is SFR
5797           if (AOP_TYPE(left) == AOP_ACC) {
5798             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
5799             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5800           } else {
5801             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
5802             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
5803
5804             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5805             pic16_emitcode("iorwf","%s,w",
5806                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5807           }
5808           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
5809           pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5810         }
5811     }
5812
5813 release :
5814     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5815     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5816     pic16_freeAsmop(result,NULL,ic,TRUE);     
5817 }
5818
5819 /*-----------------------------------------------------------------*/
5820 /* genXor - code for xclusive or                                   */
5821 /*-----------------------------------------------------------------*/
5822 static void genXor (iCode *ic, iCode *ifx)
5823 {
5824   operand *left, *right, *result;
5825   int size, offset=0;
5826   unsigned long lit = 0L;
5827
5828   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5829
5830   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5831   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5832   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5833
5834   /* if left is a literal & right is not ||
5835      if left needs acc & right does not */
5836   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5837       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5838     operand *tmp = right ;
5839     right = left;
5840     left = tmp;
5841   }
5842
5843   /* if result = right then exchange them */
5844   if(pic16_sameRegs(AOP(result),AOP(right))){
5845     operand *tmp = right ;
5846     right = left;
5847     left = tmp;
5848   }
5849
5850   /* if right is bit then exchange them */
5851   if (AOP_TYPE(right) == AOP_CRY &&
5852       AOP_TYPE(left) != AOP_CRY){
5853     operand *tmp = right ;
5854     right = left;
5855     left = tmp;
5856   }
5857   if(AOP_TYPE(right) == AOP_LIT)
5858     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5859
5860   size = AOP_SIZE(result);
5861
5862   // if(bit ^ yy)
5863   // xx = bit ^ yy;
5864   if (AOP_TYPE(left) == AOP_CRY){
5865     if(AOP_TYPE(right) == AOP_LIT){
5866       // c = bit & literal;
5867       if(lit>>1){
5868         // lit>>1  != 0 => result = 1
5869         if(AOP_TYPE(result) == AOP_CRY){
5870           if(size)
5871             {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
5872             pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5873           else if(ifx)
5874             continueIfTrue(ifx);
5875           goto release;
5876         }
5877         pic16_emitcode("setb","c");
5878       } else{
5879         // lit == (0 or 1)
5880         if(lit == 0){
5881           // lit == 0, result = left
5882           if(size && pic16_sameRegs(AOP(result),AOP(left)))
5883             goto release;
5884           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5885         } else{
5886           // lit == 1, result = not(left)
5887           if(size && pic16_sameRegs(AOP(result),AOP(left))){
5888             pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
5889             pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
5890             pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5891             goto release;
5892           } else {
5893             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5894             pic16_emitcode("cpl","c");
5895           }
5896         }
5897       }
5898
5899     } else {
5900       // right != literal
5901       symbol *tlbl = newiTempLabel(NULL);
5902       if (AOP_TYPE(right) == AOP_CRY){
5903         // c = bit ^ bit;
5904         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5905       }
5906       else{
5907         int sizer = AOP_SIZE(right);
5908         // c = bit ^ val
5909         // if val>>1 != 0, result = 1
5910         pic16_emitcode("setb","c");
5911         while(sizer){
5912           MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5913           if(sizer == 1)
5914             // test the msb of the lsb
5915             pic16_emitcode("anl","a,#0xfe");
5916           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5917           sizer--;
5918         }
5919         // val = (0,1)
5920         pic16_emitcode("rrc","a");
5921       }
5922       pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5923       pic16_emitcode("cpl","c");
5924       pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5925     }
5926     // bit = c
5927     // val = c
5928     if(size)
5929       pic16_outBitC(result);
5930     // if(bit | ...)
5931     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5932       genIfxJump(ifx, "c");           
5933     goto release ;
5934   }
5935
5936   if(pic16_sameRegs(AOP(result),AOP(left))){
5937     /* if left is same as result */
5938     for(;size--; offset++) {
5939       if(AOP_TYPE(right) == AOP_LIT){
5940         int t  = (lit >> (offset*8)) & 0x0FFL;
5941         if(t == 0x00L)
5942           continue;
5943         else
5944           if (IS_AOP_PREG(left)) {
5945             MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5946             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5947             pic16_aopPut(AOP(result),"a",offset);
5948           } else {
5949             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5950             pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5951             pic16_emitcode("xrl","%s,%s",
5952                            pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5953                            pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5954           }
5955       } else {
5956         if (AOP_TYPE(left) == AOP_ACC)
5957           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5958         else {
5959           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5960           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5961 /*
5962           if (IS_AOP_PREG(left)) {
5963             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5964             pic16_aopPut(AOP(result),"a",offset);
5965           } else
5966             pic16_emitcode("xrl","%s,a",
5967                            pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5968 */
5969         }
5970       }
5971     }
5972   } else {
5973     // left & result in different registers
5974     if(AOP_TYPE(result) == AOP_CRY){
5975       // result = bit
5976       // if(size), result in bit
5977       // if(!size && ifx), conditional oper: if(left ^ right)
5978       symbol *tlbl = newiTempLabel(NULL);
5979       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5980       if(size)
5981         pic16_emitcode("setb","c");
5982       while(sizer--){
5983         if((AOP_TYPE(right) == AOP_LIT) &&
5984            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5985           MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5986         } else {
5987           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5988           pic16_emitcode("xrl","a,%s",
5989                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5990         }
5991         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5992         offset++;
5993       }
5994       if(size){
5995         CLRC;
5996         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5997         pic16_outBitC(result);
5998       } else if(ifx)
5999         jmpTrueOrFalse(ifx, tlbl);
6000     } else for(;(size--);offset++){
6001       // normal case
6002       // result = left & right
6003       if(AOP_TYPE(right) == AOP_LIT){
6004         int t = (lit >> (offset*8)) & 0x0FFL;
6005         switch(t) { 
6006         case 0x00:
6007           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6008           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6009           pic16_emitcode("movf","%s,w",
6010                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6011           pic16_emitcode("movwf","%s",
6012                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6013           break;
6014         case 0xff:
6015           pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6016           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6017           pic16_emitcode("comf","%s,w",
6018                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6019           pic16_emitcode("movwf","%s",
6020                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6021           break;
6022         default:
6023           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6024           pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6025           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6026           pic16_emitcode("movlw","0x%x",t);
6027           pic16_emitcode("xorwf","%s,w",
6028                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6029           pic16_emitcode("movwf","%s",
6030                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6031
6032         }
6033         continue;
6034       }
6035
6036       // faster than result <- left, anl result,right
6037       // and better if result is SFR
6038       if (AOP_TYPE(left) == AOP_ACC) {
6039         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6040         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6041       } else {
6042         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6043         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6044         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6045         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6046       }
6047       if ( AOP_TYPE(result) != AOP_ACC){
6048         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6049         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6050       }
6051     }
6052   }
6053
6054   release :
6055     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6056   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057   pic16_freeAsmop(result,NULL,ic,TRUE);     
6058 }
6059
6060 /*-----------------------------------------------------------------*/
6061 /* genInline - write the inline code out                           */
6062 /*-----------------------------------------------------------------*/
6063 static void genInline (iCode *ic)
6064 {
6065     char *buffer, *bp, *bp1;
6066     
6067     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6068
6069     _G.inLine += (!options.asmpeep);
6070
6071     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6072     strcpy(buffer,IC_INLINE(ic));
6073
6074     /* emit each line as a code */
6075     while (*bp) {
6076         if (*bp == '\n') {
6077             *bp++ = '\0';
6078
6079             if(*bp1)
6080               pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6081             bp1 = bp;
6082         } else {
6083             if (*bp == ':') {
6084                 bp++;
6085                 *bp = '\0';
6086                 bp++;
6087                 pic16_emitcode(bp1,"");
6088                 bp1 = bp;
6089             } else
6090                 bp++;
6091         }
6092     }
6093     if ((bp1 != bp) && *bp1)
6094       pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6095
6096     Safe_free(buffer);
6097
6098     _G.inLine -= (!options.asmpeep);
6099 }
6100
6101 /*-----------------------------------------------------------------*/
6102 /* genRRC - rotate right with carry                                */
6103 /*-----------------------------------------------------------------*/
6104 static void genRRC (iCode *ic)
6105 {
6106   operand *left , *result ;
6107   int size, offset = 0, same;
6108
6109   /* rotate right with carry */
6110   left = IC_LEFT(ic);
6111   result=IC_RESULT(ic);
6112   pic16_aopOp (left,ic,FALSE);
6113   pic16_aopOp (result,ic,FALSE);
6114
6115   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6116
6117   same = pic16_sameRegs(AOP(result),AOP(left));
6118
6119   size = AOP_SIZE(result);    
6120
6121   /* get the lsb and put it into the carry */
6122   pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6123
6124   offset = 0 ;
6125
6126   while(size--) {
6127
6128     if(same) {
6129       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6130     } else {
6131       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6132       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6133     }
6134
6135     offset++;
6136   }
6137
6138   pic16_freeAsmop(left,NULL,ic,TRUE);
6139   pic16_freeAsmop(result,NULL,ic,TRUE);
6140 }
6141
6142 /*-----------------------------------------------------------------*/
6143 /* genRLC - generate code for rotate left with carry               */
6144 /*-----------------------------------------------------------------*/
6145 static void genRLC (iCode *ic)
6146 {    
6147   operand *left , *result ;
6148   int size, offset = 0;
6149   int same;
6150
6151   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6152   /* rotate right with carry */
6153   left = IC_LEFT(ic);
6154   result=IC_RESULT(ic);
6155   pic16_aopOp (left,ic,FALSE);
6156   pic16_aopOp (result,ic,FALSE);
6157
6158   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6159
6160   same = pic16_sameRegs(AOP(result),AOP(left));
6161
6162   /* move it to the result */
6163   size = AOP_SIZE(result);    
6164
6165   /* get the msb and put it into the carry */
6166   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6167
6168   offset = 0 ;
6169
6170   while(size--) {
6171
6172     if(same) {
6173       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6174     } else {
6175       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6176       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6177     }
6178
6179     offset++;
6180   }
6181
6182
6183   pic16_freeAsmop(left,NULL,ic,TRUE);
6184   pic16_freeAsmop(result,NULL,ic,TRUE);
6185 }
6186
6187 /*-----------------------------------------------------------------*/
6188 /* genGetHbit - generates code get highest order bit               */
6189 /*-----------------------------------------------------------------*/
6190 static void genGetHbit (iCode *ic)
6191 {
6192     operand *left, *result;
6193     left = IC_LEFT(ic);
6194     result=IC_RESULT(ic);
6195     pic16_aopOp (left,ic,FALSE);
6196     pic16_aopOp (result,ic,FALSE);
6197
6198     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6199     /* get the highest order byte into a */
6200     MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6201     if(AOP_TYPE(result) == AOP_CRY){
6202         pic16_emitcode("rlc","a");
6203         pic16_outBitC(result);
6204     }
6205     else{
6206         pic16_emitcode("rl","a");
6207         pic16_emitcode("anl","a,#0x01");
6208         pic16_outAcc(result);
6209     }
6210
6211
6212     pic16_freeAsmop(left,NULL,ic,TRUE);
6213     pic16_freeAsmop(result,NULL,ic,TRUE);
6214 }
6215
6216 /*-----------------------------------------------------------------*/
6217 /* AccRol - rotate left accumulator by known count                 */
6218 /*-----------------------------------------------------------------*/
6219 static void AccRol (int shCount)
6220 {
6221     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6222     shCount &= 0x0007;              // shCount : 0..7
6223     switch(shCount){
6224         case 0 :
6225             break;
6226         case 1 :
6227             pic16_emitcode("rl","a");
6228             break;
6229         case 2 :
6230             pic16_emitcode("rl","a");
6231             pic16_emitcode("rl","a");
6232             break;
6233         case 3 :
6234             pic16_emitcode("swap","a");
6235             pic16_emitcode("rr","a");
6236             break;
6237         case 4 :
6238             pic16_emitcode("swap","a");
6239             break;
6240         case 5 :
6241             pic16_emitcode("swap","a");
6242             pic16_emitcode("rl","a");
6243             break;
6244         case 6 :
6245             pic16_emitcode("rr","a");
6246             pic16_emitcode("rr","a");
6247             break;
6248         case 7 :
6249             pic16_emitcode("rr","a");
6250             break;
6251     }
6252 }
6253
6254 /*-----------------------------------------------------------------*/
6255 /* AccLsh - left shift accumulator by known count                  */
6256 /*-----------------------------------------------------------------*/
6257 static void AccLsh (int shCount)
6258 {
6259     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6260     if(shCount != 0){
6261         if(shCount == 1)
6262             pic16_emitcode("add","a,acc");
6263         else 
6264             if(shCount == 2) {
6265             pic16_emitcode("add","a,acc");
6266             pic16_emitcode("add","a,acc");
6267         } else {
6268             /* rotate left accumulator */
6269             AccRol(shCount);
6270             /* and kill the lower order bits */
6271             pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6272         }
6273     }
6274 }
6275
6276 /*-----------------------------------------------------------------*/
6277 /* AccRsh - right shift accumulator by known count                 */
6278 /*-----------------------------------------------------------------*/
6279 static void AccRsh (int shCount)
6280 {
6281     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6282     if(shCount != 0){
6283         if(shCount == 1){
6284             CLRC;
6285             pic16_emitcode("rrc","a");
6286         } else {
6287             /* rotate right accumulator */
6288             AccRol(8 - shCount);
6289             /* and kill the higher order bits */
6290             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6291         }
6292     }
6293 }
6294
6295 #if 0
6296 /*-----------------------------------------------------------------*/
6297 /* AccSRsh - signed right shift accumulator by known count                 */
6298 /*-----------------------------------------------------------------*/
6299 static void AccSRsh (int shCount)
6300 {
6301     symbol *tlbl ;
6302     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6303     if(shCount != 0){
6304         if(shCount == 1){
6305             pic16_emitcode("mov","c,acc.7");
6306             pic16_emitcode("rrc","a");
6307         } else if(shCount == 2){
6308             pic16_emitcode("mov","c,acc.7");
6309             pic16_emitcode("rrc","a");
6310             pic16_emitcode("mov","c,acc.7");
6311             pic16_emitcode("rrc","a");
6312         } else {
6313             tlbl = newiTempLabel(NULL);
6314             /* rotate right accumulator */
6315             AccRol(8 - shCount);
6316             /* and kill the higher order bits */
6317             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6318             pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6319             pic16_emitcode("orl","a,#0x%02x",
6320                      (unsigned char)~SRMask[shCount]);
6321             pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6322         }
6323     }
6324 }
6325 #endif
6326 /*-----------------------------------------------------------------*/
6327 /* shiftR1Left2Result - shift right one byte from left to result   */
6328 /*-----------------------------------------------------------------*/
6329 static void shiftR1Left2ResultSigned (operand *left, int offl,
6330                                 operand *result, int offr,
6331                                 int shCount)
6332 {
6333   int same;
6334
6335   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6336
6337   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6338
6339   switch(shCount) {
6340   case 1:
6341     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6342     if(same) 
6343       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6344     else {
6345       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6346       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6347     }
6348
6349     break;
6350   case 2:
6351
6352     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6353     if(same) 
6354       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6355     else {
6356       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6357       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6358     }
6359     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6360     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6361
6362     break;
6363
6364   case 3:
6365     if(same)
6366       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6367     else {
6368       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6369       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6370     }
6371
6372     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6373     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6374     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6375
6376     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6377     pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6378
6379     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6380     break;
6381
6382   case 4:
6383     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6384     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
6385     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6386     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
6387     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6388     break;
6389   case 5:
6390     if(same) {
6391       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
6392     } else {
6393       pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
6394       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6395     }
6396     pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
6397     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
6398     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6399     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
6400     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6401     break;
6402
6403   case 6:
6404     if(same) {
6405       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6406       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6407       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6408       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6409       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6410       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6411     } else {
6412       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6413       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6414       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6415       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6416       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6417     }
6418     break;
6419
6420   case 7:
6421     if(same) {
6422       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6423       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6424       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6425       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6426     } else {
6427       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6428       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6429       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6430     }
6431
6432   default:
6433     break;
6434   }
6435 }
6436
6437 /*-----------------------------------------------------------------*/
6438 /* shiftR1Left2Result - shift right one byte from left to result   */
6439 /*-----------------------------------------------------------------*/
6440 static void shiftR1Left2Result (operand *left, int offl,
6441                                 operand *result, int offr,
6442                                 int shCount, int sign)
6443 {
6444   int same;
6445
6446   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6447
6448   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6449
6450   /* Copy the msb into the carry if signed. */
6451   if(sign) {
6452     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6453     return;
6454   }
6455
6456
6457
6458   switch(shCount) {
6459   case 1:
6460     emitCLRC;
6461     if(same) 
6462       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6463     else {
6464       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6465       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6466     }
6467     break;
6468   case 2:
6469     emitCLRC;
6470     if(same) {
6471       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6472     } else {
6473       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6474       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6475     }
6476     emitCLRC;
6477     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6478
6479     break;
6480   case 3:
6481     if(same)
6482       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6483     else {
6484       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6485       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6486     }
6487
6488     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6489     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6490     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6491     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6492     break;
6493       
6494   case 4:
6495     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6496     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6497     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6498     break;
6499
6500   case 5:
6501     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6502     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6503     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6504     emitCLRC;
6505     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6506
6507     break;
6508   case 6:
6509
6510     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl));
6511     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6512     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6513     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6514     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
6515     break;
6516
6517   case 7:
6518
6519     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6520     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6521     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6522
6523     break;
6524
6525   default:
6526     break;
6527   }
6528 }
6529
6530 /*-----------------------------------------------------------------*/
6531 /* shiftL1Left2Result - shift left one byte from left to result    */
6532 /*-----------------------------------------------------------------*/
6533 static void shiftL1Left2Result (operand *left, int offl,
6534                                 operand *result, int offr, int shCount)
6535 {
6536   int same;
6537
6538   //    char *l;
6539   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6540
6541   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6542   DEBUGpic16_emitcode ("; ***","same =  %d",same);
6543     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6544     //    MOVA(l);
6545     /* shift left accumulator */
6546     //AccLsh(shCount); // don't comment out just yet...
6547   //    pic16_aopPut(AOP(result),"a",offr);
6548
6549   switch(shCount) {
6550   case 1:
6551     /* Shift left 1 bit position */
6552     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6553     if(same) {
6554       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6555     } else {
6556       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6557       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6558     }
6559     break;
6560   case 2:
6561     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6562     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6563     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6564     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6565     break;
6566   case 3:
6567     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6568     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6569     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6570     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6571     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6572     break;
6573   case 4:
6574     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6575     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6576     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6577     break;
6578   case 5:
6579     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6580     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6581     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6582     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6583     break;
6584   case 6:
6585     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6586     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6587     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6588     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6589     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6590     break;
6591   case 7:
6592     pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6593     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6594     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6595     break;
6596
6597   default:
6598     DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6599   }
6600
6601 }
6602
6603 /*-----------------------------------------------------------------*/
6604 /* movLeft2Result - move byte from left to result                  */
6605 /*-----------------------------------------------------------------*/
6606 static void movLeft2Result (operand *left, int offl,
6607                             operand *result, int offr)
6608 {
6609   char *l;
6610   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6611   if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6612     l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6613
6614     if (*l == '@' && (IS_AOP_PREG(result))) {
6615       pic16_emitcode("mov","a,%s",l);
6616       pic16_aopPut(AOP(result),"a",offr);
6617     } else {
6618       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6619       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6620     }
6621   }
6622 }
6623
6624 /*-----------------------------------------------------------------*/
6625 /* shiftL2Left2Result - shift left two bytes from left to result   */
6626 /*-----------------------------------------------------------------*/
6627 static void shiftL2Left2Result (operand *left, int offl,
6628                                 operand *result, int offr, int shCount)
6629 {
6630
6631
6632   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6633
6634   if(pic16_sameRegs(AOP(result), AOP(left))) {
6635     switch(shCount) {
6636     case 0:
6637       break;
6638     case 1:
6639     case 2:
6640     case 3:
6641
6642       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6643       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6644       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6645
6646       while(--shCount) {
6647         emitCLRC;
6648         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6649         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6650       }
6651
6652       break;
6653     case 4:
6654     case 5:
6655       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6656       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6657       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6658       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6659       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6660       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6661       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6662       if(shCount >=5) {
6663         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6664         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6665       }
6666       break;
6667     case 6:
6668       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6669       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6670       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6671       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6672       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6673       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6674       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6675       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6676       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6677       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6678       break;
6679     case 7:
6680       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6681       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6682       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6683       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6684       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6685     }
6686
6687   } else {
6688     switch(shCount) {
6689     case 0:
6690       break;
6691     case 1:
6692     case 2:
6693     case 3:
6694       /* note, use a mov/add for the shift since the mov has a
6695          chance of getting optimized out */
6696       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6697       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6698       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6699       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl+MSB16));
6700       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6701
6702       while(--shCount) {
6703         emitCLRC;
6704         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6705         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6706       }
6707       break;
6708
6709     case 4:
6710     case 5:
6711       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6712       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6713       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6714       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6715       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6716       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6717       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6718       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6719
6720
6721       if(shCount == 5) {
6722         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6723         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6724       }
6725       break;
6726     case 6:
6727       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6728       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6729       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6730       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6731
6732       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
6733       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6734       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6735       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6736       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6737       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6738       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6739       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6740       break;
6741     case 7:
6742       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6743       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6744       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6745       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6746       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6747     }
6748   }
6749
6750 }
6751 /*-----------------------------------------------------------------*/
6752 /* shiftR2Left2Result - shift right two bytes from left to result  */
6753 /*-----------------------------------------------------------------*/
6754 static void shiftR2Left2Result (operand *left, int offl,
6755                                 operand *result, int offr,
6756                                 int shCount, int sign)
6757 {
6758   int same=0;
6759
6760   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6761   same = pic16_sameRegs(AOP(result), AOP(left));
6762
6763   if(same && ((offl + MSB16) == offr)){
6764     same=1;
6765     /* don't crash result[offr] */
6766     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6767     pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6768   }
6769 /* else {
6770     movLeft2Result(left,offl, result, offr);
6771     MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6772   }
6773 */
6774   /* a:x >> shCount (x = lsb(result))*/
6775 /*
6776   if(sign)
6777     AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6778   else {
6779     AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6780 */
6781   switch(shCount) {
6782   case 0:
6783     break;
6784   case 1:
6785   case 2:
6786   case 3:
6787     if(sign)
6788       pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6789     else
6790       emitCLRC;
6791
6792     if(same) {
6793       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6794       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6795     } else {
6796       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6797       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6798       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6799       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6800     }
6801
6802     while(--shCount) {
6803       if(sign)
6804         pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6805       else
6806         emitCLRC;
6807       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6808       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6809     }
6810     break;
6811   case 4:
6812   case 5:
6813     if(same) {
6814
6815       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6816       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6817       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6818
6819       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6820       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6821       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6822       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6823     } else {
6824       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6825       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6826       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6827
6828       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6829       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6830       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6831       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6832       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6833     }
6834
6835     if(shCount >=5) {
6836       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6837       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6838     }
6839
6840     if(sign) {
6841       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6842       pic16_emitpcode(POC_BTFSC, 
6843                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6844       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6845     }
6846
6847     break;
6848
6849   case 6:
6850     if(same) {
6851
6852       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6853       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6854
6855       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6856       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6857       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6858       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6859       if(sign) {
6860         pic16_emitpcode(POC_BTFSC, 
6861                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6862         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6863       }
6864       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6865       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6866       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6867       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6868     } else {
6869       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6870       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6871       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6872       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6873       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6874       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6875       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6876       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6877       if(sign) {
6878         pic16_emitpcode(POC_BTFSC, 
6879                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6880         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6881       }
6882       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6883       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
6884
6885         
6886     }
6887
6888     break;
6889   case 7:
6890     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6891     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6892     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6893     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6894     if(sign) {
6895       emitSKPNC;
6896       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6897     } else 
6898       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
6899   }
6900 }
6901
6902
6903 /*-----------------------------------------------------------------*/
6904 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6905 /*-----------------------------------------------------------------*/
6906 static void shiftLLeftOrResult (operand *left, int offl,
6907                                 operand *result, int offr, int shCount)
6908 {
6909     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6910     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6911     /* shift left accumulator */
6912     AccLsh(shCount);
6913     /* or with result */
6914     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6915     /* back to result */
6916     pic16_aopPut(AOP(result),"a",offr);
6917 }
6918
6919 /*-----------------------------------------------------------------*/
6920 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6921 /*-----------------------------------------------------------------*/
6922 static void shiftRLeftOrResult (operand *left, int offl,
6923                                 operand *result, int offr, int shCount)
6924 {
6925     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6926     MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6927     /* shift right accumulator */
6928     AccRsh(shCount);
6929     /* or with result */
6930     pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6931     /* back to result */
6932     pic16_aopPut(AOP(result),"a",offr);
6933 }
6934
6935 /*-----------------------------------------------------------------*/
6936 /* genlshOne - left shift a one byte quantity by known count       */
6937 /*-----------------------------------------------------------------*/
6938 static void genlshOne (operand *result, operand *left, int shCount)
6939 {       
6940     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6941     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6942 }
6943
6944 /*-----------------------------------------------------------------*/
6945 /* genlshTwo - left shift two bytes by known amount != 0           */
6946 /*-----------------------------------------------------------------*/
6947 static void genlshTwo (operand *result,operand *left, int shCount)
6948 {
6949     int size;
6950     
6951     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6952     size = pic16_getDataSize(result);
6953
6954     /* if shCount >= 8 */
6955     if (shCount >= 8) {
6956         shCount -= 8 ;
6957
6958         if (size > 1){
6959             if (shCount)
6960                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6961             else 
6962                 movLeft2Result(left, LSB, result, MSB16);
6963         }
6964         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6965     }
6966
6967     /*  1 <= shCount <= 7 */
6968     else {  
6969         if(size == 1)
6970             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6971         else 
6972             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6973     }
6974 }
6975
6976 /*-----------------------------------------------------------------*/
6977 /* shiftLLong - shift left one long from left to result            */
6978 /* offl = LSB or MSB16                                             */
6979 /*-----------------------------------------------------------------*/
6980 static void shiftLLong (operand *left, operand *result, int offr )
6981 {
6982     char *l;
6983     int size = AOP_SIZE(result);
6984
6985     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6986     if(size >= LSB+offr){
6987         l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
6988         MOVA(l);
6989         pic16_emitcode("add","a,acc");
6990         if (pic16_sameRegs(AOP(left),AOP(result)) && 
6991             size >= MSB16+offr && offr != LSB )
6992             pic16_emitcode("xch","a,%s",
6993                      pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6994         else        
6995             pic16_aopPut(AOP(result),"a",LSB+offr);
6996     }
6997
6998     if(size >= MSB16+offr){
6999         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7000             l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7001             MOVA(l);
7002         }
7003         pic16_emitcode("rlc","a");
7004         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7005             size >= MSB24+offr && offr != LSB)
7006             pic16_emitcode("xch","a,%s",
7007                      pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7008         else        
7009             pic16_aopPut(AOP(result),"a",MSB16+offr);
7010     }
7011
7012     if(size >= MSB24+offr){
7013         if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7014             l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7015             MOVA(l);
7016         }
7017         pic16_emitcode("rlc","a");
7018         if (pic16_sameRegs(AOP(left),AOP(result)) && 
7019             size >= MSB32+offr && offr != LSB )
7020             pic16_emitcode("xch","a,%s",
7021                      pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7022         else        
7023             pic16_aopPut(AOP(result),"a",MSB24+offr);
7024     }
7025
7026     if(size > MSB32+offr){
7027         if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7028             l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7029             MOVA(l);    
7030         }
7031         pic16_emitcode("rlc","a");
7032         pic16_aopPut(AOP(result),"a",MSB32+offr);
7033     }
7034     if(offr != LSB)
7035         pic16_aopPut(AOP(result),zero,LSB);       
7036 }
7037
7038 /*-----------------------------------------------------------------*/
7039 /* genlshFour - shift four byte by a known amount != 0             */
7040 /*-----------------------------------------------------------------*/
7041 static void genlshFour (operand *result, operand *left, int shCount)
7042 {
7043     int size;
7044
7045     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7046     size = AOP_SIZE(result);
7047
7048     /* if shifting more that 3 bytes */
7049     if (shCount >= 24 ) {
7050         shCount -= 24;
7051         if (shCount)
7052             /* lowest order of left goes to the highest
7053             order of the destination */
7054             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7055         else
7056             movLeft2Result(left, LSB, result, MSB32);
7057         pic16_aopPut(AOP(result),zero,LSB);
7058         pic16_aopPut(AOP(result),zero,MSB16);
7059         pic16_aopPut(AOP(result),zero,MSB32);
7060         return;
7061     }
7062
7063     /* more than two bytes */
7064     else if ( shCount >= 16 ) {
7065         /* lower order two bytes goes to higher order two bytes */
7066         shCount -= 16;
7067         /* if some more remaining */
7068         if (shCount)
7069             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7070         else {
7071             movLeft2Result(left, MSB16, result, MSB32);
7072             movLeft2Result(left, LSB, result, MSB24);
7073         }
7074         pic16_aopPut(AOP(result),zero,MSB16);
7075         pic16_aopPut(AOP(result),zero,LSB);
7076         return;
7077     }    
7078
7079     /* if more than 1 byte */
7080     else if ( shCount >= 8 ) {
7081         /* lower order three bytes goes to higher order  three bytes */
7082         shCount -= 8;
7083         if(size == 2){
7084             if(shCount)
7085                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7086             else
7087                 movLeft2Result(left, LSB, result, MSB16);
7088         }
7089         else{   /* size = 4 */
7090             if(shCount == 0){
7091                 movLeft2Result(left, MSB24, result, MSB32);
7092                 movLeft2Result(left, MSB16, result, MSB24);
7093                 movLeft2Result(left, LSB, result, MSB16);
7094                 pic16_aopPut(AOP(result),zero,LSB);
7095             }
7096             else if(shCount == 1)
7097                 shiftLLong(left, result, MSB16);
7098             else{
7099                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7100                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7101                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7102                 pic16_aopPut(AOP(result),zero,LSB);
7103             }
7104         }
7105     }
7106
7107     /* 1 <= shCount <= 7 */
7108     else if(shCount <= 2){
7109         shiftLLong(left, result, LSB);
7110         if(shCount == 2)
7111             shiftLLong(result, result, LSB);
7112     }
7113     /* 3 <= shCount <= 7, optimize */
7114     else{
7115         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7116         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7117         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7118     }
7119 }
7120
7121 /*-----------------------------------------------------------------*/
7122 /* genLeftShiftLiteral - left shifting by known count              */
7123 /*-----------------------------------------------------------------*/
7124 static void genLeftShiftLiteral (operand *left,
7125                                  operand *right,
7126                                  operand *result,
7127                                  iCode *ic)
7128 {    
7129     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7130     int size;
7131
7132     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7133     pic16_freeAsmop(right,NULL,ic,TRUE);
7134
7135     pic16_aopOp(left,ic,FALSE);
7136     pic16_aopOp(result,ic,FALSE);
7137
7138     size = getSize(operandType(result));
7139
7140 #if VIEW_SIZE
7141     pic16_emitcode("; shift left ","result %d, left %d",size,
7142              AOP_SIZE(left));
7143 #endif
7144
7145     /* I suppose that the left size >= result size */
7146     if(shCount == 0){
7147         while(size--){
7148             movLeft2Result(left, size, result, size);
7149         }
7150     }
7151
7152     else if(shCount >= (size * 8))
7153         while(size--)
7154             pic16_aopPut(AOP(result),zero,size);
7155     else{
7156         switch (size) {
7157             case 1:
7158                 genlshOne (result,left,shCount);
7159                 break;
7160
7161             case 2:
7162             case 3:
7163                 genlshTwo (result,left,shCount);
7164                 break;
7165
7166             case 4:
7167                 genlshFour (result,left,shCount);
7168                 break;
7169         }
7170     }
7171     pic16_freeAsmop(left,NULL,ic,TRUE);
7172     pic16_freeAsmop(result,NULL,ic,TRUE);
7173 }
7174
7175 /*-----------------------------------------------------------------*
7176  * genMultiAsm - repeat assembly instruction for size of register.
7177  * if endian == 1, then the high byte (i.e base address + size of 
7178  * register) is used first else the low byte is used first;
7179  *-----------------------------------------------------------------*/
7180 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7181 {
7182
7183   int offset = 0;
7184
7185   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7186
7187   if(!reg)
7188     return;
7189
7190   if(!endian) {
7191     endian = 1;
7192   } else {
7193     endian = -1;
7194     offset = size-1;
7195   }
7196
7197   while(size--) {
7198     pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
7199     offset += endian;
7200   }
7201
7202 }
7203 /*-----------------------------------------------------------------*/
7204 /* genLeftShift - generates code for left shifting                 */
7205 /*-----------------------------------------------------------------*/
7206 static void genLeftShift (iCode *ic)
7207 {
7208   operand *left,*right, *result;
7209   int size, offset;
7210   char *l;
7211   symbol *tlbl , *tlbl1;
7212   pCodeOp *pctemp;
7213
7214   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7215
7216   right = IC_RIGHT(ic);
7217   left  = IC_LEFT(ic);
7218   result = IC_RESULT(ic);
7219
7220   pic16_aopOp(right,ic,FALSE);
7221
7222   /* if the shift count is known then do it 
7223      as efficiently as possible */
7224   if (AOP_TYPE(right) == AOP_LIT) {
7225     genLeftShiftLiteral (left,right,result,ic);
7226     return ;
7227   }
7228
7229   /* shift count is unknown then we have to form 
7230      a loop get the loop count in B : Note: we take
7231      only the lower order byte since shifting
7232      more that 32 bits make no sense anyway, ( the
7233      largest size of an object can be only 32 bits ) */  
7234
7235     
7236   pic16_aopOp(left,ic,FALSE);
7237   pic16_aopOp(result,ic,FALSE);
7238
7239   /* now move the left to the result if they are not the
7240      same */
7241   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7242       AOP_SIZE(result) > 1) {
7243
7244     size = AOP_SIZE(result);
7245     offset=0;
7246     while (size--) {
7247       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7248       if (*l == '@' && (IS_AOP_PREG(result))) {
7249
7250         pic16_emitcode("mov","a,%s",l);
7251         pic16_aopPut(AOP(result),"a",offset);
7252       } else {
7253         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7254         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7255         //pic16_aopPut(AOP(result),l,offset);
7256       }
7257       offset++;
7258     }
7259   }
7260
7261   size = AOP_SIZE(result);
7262
7263   /* if it is only one byte then */
7264   if (size == 1) {
7265     if(optimized_for_speed) {
7266       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7267       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
7268       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7269       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7270       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7271       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7272       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7273       pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
7274       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
7275       pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
7276       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7277       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7278     } else {
7279
7280       tlbl = newiTempLabel(NULL);
7281       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7282         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7283         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7284       }
7285
7286       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7287       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7288       pic16_emitpLabel(tlbl->key);
7289       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7290       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7291       emitSKPC;
7292       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7293     }
7294     goto release ;
7295   }
7296     
7297   if (pic16_sameRegs(AOP(left),AOP(result))) {
7298
7299     tlbl = newiTempLabel(NULL);
7300     pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7301     genMultiAsm(POC_RRCF, result, size,1);
7302     pic16_emitpLabel(tlbl->key);
7303     genMultiAsm(POC_RLCF, result, size,0);
7304     pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7305     emitSKPC;
7306     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7307     goto release;
7308   }
7309
7310   //tlbl = newiTempLabel(NULL);
7311   //offset = 0 ;   
7312   //tlbl1 = newiTempLabel(NULL);
7313
7314   //reAdjustPreg(AOP(result));    
7315     
7316   //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7317   //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7318   //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7319   //MOVA(l);
7320   //pic16_emitcode("add","a,acc");         
7321   //pic16_aopPut(AOP(result),"a",offset++);
7322   //while (--size) {
7323   //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7324   //  MOVA(l);
7325   //  pic16_emitcode("rlc","a");         
7326   //  pic16_aopPut(AOP(result),"a",offset++);
7327   //}
7328   //reAdjustPreg(AOP(result));
7329
7330   //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7331   //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7332
7333
7334   tlbl = newiTempLabel(NULL);
7335   tlbl1= newiTempLabel(NULL);
7336
7337   size = AOP_SIZE(result);
7338   offset = 1;
7339
7340   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7341
7342   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7343
7344   /* offset should be 0, 1 or 3 */
7345   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7346   emitSKPNZ;
7347   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7348
7349   pic16_emitpcode(POC_MOVWF, pctemp);
7350
7351
7352   pic16_emitpLabel(tlbl->key);
7353
7354   emitCLRC;
7355   pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
7356   while(--size)
7357     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
7358
7359   pic16_emitpcode(POC_DECFSZ,  pctemp);
7360   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7361   pic16_emitpLabel(tlbl1->key);
7362
7363   pic16_popReleaseTempReg(pctemp);
7364
7365
7366  release:
7367   pic16_freeAsmop (right,NULL,ic,TRUE);
7368   pic16_freeAsmop(left,NULL,ic,TRUE);
7369   pic16_freeAsmop(result,NULL,ic,TRUE);
7370 }
7371
7372 /*-----------------------------------------------------------------*/
7373 /* genrshOne - right shift a one byte quantity by known count      */
7374 /*-----------------------------------------------------------------*/
7375 static void genrshOne (operand *result, operand *left,
7376                        int shCount, int sign)
7377 {
7378     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7379     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7380 }
7381
7382 /*-----------------------------------------------------------------*/
7383 /* genrshTwo - right shift two bytes by known amount != 0          */
7384 /*-----------------------------------------------------------------*/
7385 static void genrshTwo (operand *result,operand *left,
7386                        int shCount, int sign)
7387 {
7388   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7389   /* if shCount >= 8 */
7390   if (shCount >= 8) {
7391     shCount -= 8 ;
7392     if (shCount)
7393       shiftR1Left2Result(left, MSB16, result, LSB,
7394                          shCount, sign);
7395     else
7396       movLeft2Result(left, MSB16, result, LSB);
7397
7398     pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7399
7400     if(sign) {
7401       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7402       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7403     }
7404   }
7405
7406   /*  1 <= shCount <= 7 */
7407   else
7408     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7409 }
7410
7411 /*-----------------------------------------------------------------*/
7412 /* shiftRLong - shift right one long from left to result           */
7413 /* offl = LSB or MSB16                                             */
7414 /*-----------------------------------------------------------------*/
7415 static void shiftRLong (operand *left, int offl,
7416                         operand *result, int sign)
7417 {
7418     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7419     if(!sign)
7420         pic16_emitcode("clr","c");
7421     MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7422     if(sign)
7423         pic16_emitcode("mov","c,acc.7");
7424     pic16_emitcode("rrc","a");
7425     pic16_aopPut(AOP(result),"a",MSB32-offl);
7426     if(offl == MSB16)
7427         /* add sign of "a" */
7428         pic16_addSign(result, MSB32, sign);
7429
7430     MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7431     pic16_emitcode("rrc","a");
7432     pic16_aopPut(AOP(result),"a",MSB24-offl);
7433
7434     MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7435     pic16_emitcode("rrc","a");
7436     pic16_aopPut(AOP(result),"a",MSB16-offl);
7437
7438     if(offl == LSB){
7439         MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7440         pic16_emitcode("rrc","a");
7441         pic16_aopPut(AOP(result),"a",LSB);
7442     }
7443 }
7444
7445 /*-----------------------------------------------------------------*/
7446 /* genrshFour - shift four byte by a known amount != 0             */
7447 /*-----------------------------------------------------------------*/
7448 static void genrshFour (operand *result, operand *left,
7449                         int shCount, int sign)
7450 {
7451   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7452   /* if shifting more that 3 bytes */
7453   if(shCount >= 24 ) {
7454     shCount -= 24;
7455     if(shCount)
7456       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7457     else
7458       movLeft2Result(left, MSB32, result, LSB);
7459
7460     pic16_addSign(result, MSB16, sign);
7461   }
7462   else if(shCount >= 16){
7463     shCount -= 16;
7464     if(shCount)
7465       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7466     else{
7467       movLeft2Result(left, MSB24, result, LSB);
7468       movLeft2Result(left, MSB32, result, MSB16);
7469     }
7470     pic16_addSign(result, MSB24, sign);
7471   }
7472   else if(shCount >= 8){
7473     shCount -= 8;
7474     if(shCount == 1)
7475       shiftRLong(left, MSB16, result, sign);
7476     else if(shCount == 0){
7477       movLeft2Result(left, MSB16, result, LSB);
7478       movLeft2Result(left, MSB24, result, MSB16);
7479       movLeft2Result(left, MSB32, result, MSB24);
7480       pic16_addSign(result, MSB32, sign);
7481     }
7482     else{
7483       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7484       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7485       /* the last shift is signed */
7486       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7487       pic16_addSign(result, MSB32, sign);
7488     }
7489   }
7490   else{   /* 1 <= shCount <= 7 */
7491     if(shCount <= 2){
7492       shiftRLong(left, LSB, result, sign);
7493       if(shCount == 2)
7494         shiftRLong(result, LSB, result, sign);
7495     }
7496     else{
7497       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7498       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7499       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7500     }
7501   }
7502 }
7503
7504 /*-----------------------------------------------------------------*/
7505 /* genRightShiftLiteral - right shifting by known count            */
7506 /*-----------------------------------------------------------------*/
7507 static void genRightShiftLiteral (operand *left,
7508                                   operand *right,
7509                                   operand *result,
7510                                   iCode *ic,
7511                                   int sign)
7512 {    
7513   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7514   int lsize,res_size;
7515
7516   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7517   pic16_freeAsmop(right,NULL,ic,TRUE);
7518
7519   pic16_aopOp(left,ic,FALSE);
7520   pic16_aopOp(result,ic,FALSE);
7521
7522 #if VIEW_SIZE
7523   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7524                  AOP_SIZE(left));
7525 #endif
7526
7527   lsize = pic16_getDataSize(left);
7528   res_size = pic16_getDataSize(result);
7529   /* test the LEFT size !!! */
7530
7531   /* I suppose that the left size >= result size */
7532   if(shCount == 0){
7533     while(res_size--)
7534       movLeft2Result(left, lsize, result, res_size);
7535   }
7536
7537   else if(shCount >= (lsize * 8)){
7538
7539     if(res_size == 1) {
7540       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7541       if(sign) {
7542         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7543         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7544       }
7545     } else {
7546
7547       if(sign) {
7548         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7549         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7550         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7551         while(res_size--)
7552           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7553
7554       } else {
7555
7556         while(res_size--)
7557           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7558       }
7559     }
7560   } else {
7561
7562     switch (res_size) {
7563     case 1:
7564       genrshOne (result,left,shCount,sign);
7565       break;
7566
7567     case 2:
7568       genrshTwo (result,left,shCount,sign);
7569       break;
7570
7571     case 4:
7572       genrshFour (result,left,shCount,sign);
7573       break;
7574     default :
7575       break;
7576     }
7577
7578   }
7579
7580   pic16_freeAsmop(left,NULL,ic,TRUE);
7581   pic16_freeAsmop(result,NULL,ic,TRUE);
7582 }
7583
7584 /*-----------------------------------------------------------------*/
7585 /* genSignedRightShift - right shift of signed number              */
7586 /*-----------------------------------------------------------------*/
7587 static void genSignedRightShift (iCode *ic)
7588 {
7589   operand *right, *left, *result;
7590   int size, offset;
7591   //  char *l;
7592   symbol *tlbl, *tlbl1 ;
7593   pCodeOp *pctemp;
7594
7595   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7596
7597   /* we do it the hard way put the shift count in b
7598      and loop thru preserving the sign */
7599   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7600
7601   right = IC_RIGHT(ic);
7602   left  = IC_LEFT(ic);
7603   result = IC_RESULT(ic);
7604
7605   pic16_aopOp(right,ic,FALSE);  
7606   pic16_aopOp(left,ic,FALSE);
7607   pic16_aopOp(result,ic,FALSE);
7608
7609
7610   if ( AOP_TYPE(right) == AOP_LIT) {
7611     genRightShiftLiteral (left,right,result,ic,1);
7612     return ;
7613   }
7614   /* shift count is unknown then we have to form 
7615      a loop get the loop count in B : Note: we take
7616      only the lower order byte since shifting
7617      more that 32 bits make no sense anyway, ( the
7618      largest size of an object can be only 32 bits ) */  
7619
7620   //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7621   //pic16_emitcode("inc","b");
7622   //pic16_freeAsmop (right,NULL,ic,TRUE);
7623   //pic16_aopOp(left,ic,FALSE);
7624   //pic16_aopOp(result,ic,FALSE);
7625
7626   /* now move the left to the result if they are not the
7627      same */
7628   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7629       AOP_SIZE(result) > 1) {
7630
7631     size = AOP_SIZE(result);
7632     offset=0;
7633     while (size--) { 
7634       /*
7635         l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7636         if (*l == '@' && IS_AOP_PREG(result)) {
7637
7638         pic16_emitcode("mov","a,%s",l);
7639         pic16_aopPut(AOP(result),"a",offset);
7640         } else
7641         pic16_aopPut(AOP(result),l,offset);
7642       */
7643       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7644       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7645
7646       offset++;
7647     }
7648   }
7649
7650   /* mov the highest order bit to OVR */    
7651   tlbl = newiTempLabel(NULL);
7652   tlbl1= newiTempLabel(NULL);
7653
7654   size = AOP_SIZE(result);
7655   offset = size - 1;
7656
7657   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7658
7659   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7660
7661   /* offset should be 0, 1 or 3 */
7662   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7663   emitSKPNZ;
7664   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7665
7666   pic16_emitpcode(POC_MOVWF, pctemp);
7667
7668
7669   pic16_emitpLabel(tlbl->key);
7670
7671   pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
7672   pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
7673
7674   while(--size) {
7675     pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
7676   }
7677
7678   pic16_emitpcode(POC_DECFSZ,  pctemp);
7679   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7680   pic16_emitpLabel(tlbl1->key);
7681
7682   pic16_popReleaseTempReg(pctemp);
7683 #if 0
7684   size = AOP_SIZE(result);
7685   offset = size - 1;
7686   pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7687   pic16_emitcode("rlc","a");
7688   pic16_emitcode("mov","ov,c");
7689   /* if it is only one byte then */
7690   if (size == 1) {
7691     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7692     MOVA(l);
7693     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7694     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7695     pic16_emitcode("mov","c,ov");
7696     pic16_emitcode("rrc","a");
7697     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7698     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7699     pic16_aopPut(AOP(result),"a",0);
7700     goto release ;
7701   }
7702
7703   reAdjustPreg(AOP(result));
7704   pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705   pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7706   pic16_emitcode("mov","c,ov");
7707   while (size--) {
7708     l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7709     MOVA(l);
7710     pic16_emitcode("rrc","a");         
7711     pic16_aopPut(AOP(result),"a",offset--);
7712   }
7713   reAdjustPreg(AOP(result));
7714   pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7715   pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7716
7717  release:
7718 #endif
7719
7720   pic16_freeAsmop(left,NULL,ic,TRUE);
7721   pic16_freeAsmop(result,NULL,ic,TRUE);
7722   pic16_freeAsmop(right,NULL,ic,TRUE);
7723 }
7724
7725 /*-----------------------------------------------------------------*/
7726 /* genRightShift - generate code for right shifting                */
7727 /*-----------------------------------------------------------------*/
7728 static void genRightShift (iCode *ic)
7729 {
7730     operand *right, *left, *result;
7731     sym_link *retype ;
7732     int size, offset;
7733     char *l;
7734     symbol *tlbl, *tlbl1 ;
7735
7736     /* if signed then we do it the hard way preserve the
7737     sign bit moving it inwards */
7738     retype = getSpec(operandType(IC_RESULT(ic)));
7739     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7740
7741     if (!SPEC_USIGN(retype)) {
7742         genSignedRightShift (ic);
7743         return ;
7744     }
7745
7746     /* signed & unsigned types are treated the same : i.e. the
7747     signed is NOT propagated inwards : quoting from the
7748     ANSI - standard : "for E1 >> E2, is equivalent to division
7749     by 2**E2 if unsigned or if it has a non-negative value,
7750     otherwise the result is implementation defined ", MY definition
7751     is that the sign does not get propagated */
7752
7753     right = IC_RIGHT(ic);
7754     left  = IC_LEFT(ic);
7755     result = IC_RESULT(ic);
7756
7757     pic16_aopOp(right,ic,FALSE);
7758
7759     /* if the shift count is known then do it 
7760     as efficiently as possible */
7761     if (AOP_TYPE(right) == AOP_LIT) {
7762         genRightShiftLiteral (left,right,result,ic, 0);
7763         return ;
7764     }
7765
7766     /* shift count is unknown then we have to form 
7767     a loop get the loop count in B : Note: we take
7768     only the lower order byte since shifting
7769     more that 32 bits make no sense anyway, ( the
7770     largest size of an object can be only 32 bits ) */  
7771
7772     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7773     pic16_emitcode("inc","b");
7774     pic16_aopOp(left,ic,FALSE);
7775     pic16_aopOp(result,ic,FALSE);
7776
7777     /* now move the left to the result if they are not the
7778     same */
7779     if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7780         AOP_SIZE(result) > 1) {
7781
7782         size = AOP_SIZE(result);
7783         offset=0;
7784         while (size--) {
7785             l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7786             if (*l == '@' && IS_AOP_PREG(result)) {
7787
7788                 pic16_emitcode("mov","a,%s",l);
7789                 pic16_aopPut(AOP(result),"a",offset);
7790             } else
7791                 pic16_aopPut(AOP(result),l,offset);
7792             offset++;
7793         }
7794     }
7795
7796     tlbl = newiTempLabel(NULL);
7797     tlbl1= newiTempLabel(NULL);
7798     size = AOP_SIZE(result);
7799     offset = size - 1;
7800
7801     /* if it is only one byte then */
7802     if (size == 1) {
7803
7804       tlbl = newiTempLabel(NULL);
7805       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7806         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7807         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7808       }
7809
7810       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7811       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7812       pic16_emitpLabel(tlbl->key);
7813       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7814       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7815       emitSKPC;
7816       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7817
7818       goto release ;
7819     }
7820
7821     reAdjustPreg(AOP(result));
7822     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7823     pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7824     CLRC;
7825     while (size--) {
7826         l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7827         MOVA(l);
7828         pic16_emitcode("rrc","a");         
7829         pic16_aopPut(AOP(result),"a",offset--);
7830     }
7831     reAdjustPreg(AOP(result));
7832
7833     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7834     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7835
7836 release:
7837     pic16_freeAsmop(left,NULL,ic,TRUE);
7838     pic16_freeAsmop (right,NULL,ic,TRUE);
7839     pic16_freeAsmop(result,NULL,ic,TRUE);
7840 }
7841
7842 /*-----------------------------------------------------------------*/
7843 /* genUnpackBits - generates code for unpacking bits               */
7844 /*-----------------------------------------------------------------*/
7845 static void genUnpackBits (operand *result, char *rname, int ptype)
7846 {    
7847     int shCnt ;
7848     int rlen = 0 ;
7849     sym_link *etype;
7850     int offset = 0 ;
7851
7852     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7853     etype = getSpec(operandType(result));
7854
7855     /* read the first byte  */
7856     switch (ptype) {
7857
7858     case POINTER:
7859     case IPOINTER:
7860         pic16_emitcode("mov","a,@%s",rname);
7861         break;
7862         
7863     case PPOINTER:
7864         pic16_emitcode("movx","a,@%s",rname);
7865         break;
7866         
7867     case FPOINTER:
7868         pic16_emitcode("movx","a,@dptr");
7869         break;
7870
7871     case CPOINTER:
7872         pic16_emitcode("clr","a");
7873         pic16_emitcode("movc","a","@a+dptr");
7874         break;
7875
7876     case GPOINTER:
7877         pic16_emitcode("lcall","__gptrget");
7878         break;
7879     }
7880
7881     /* if we have bitdisplacement then it fits   */
7882     /* into this byte completely or if length is */
7883     /* less than a byte                          */
7884     if ((shCnt = SPEC_BSTR(etype)) || 
7885         (SPEC_BLEN(etype) <= 8))  {
7886
7887         /* shift right acc */
7888         AccRsh(shCnt);
7889
7890         pic16_emitcode("anl","a,#0x%02x",
7891                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7892         pic16_aopPut(AOP(result),"a",offset);
7893         return ;
7894     }
7895
7896     /* bit field did not fit in a byte  */
7897     rlen = SPEC_BLEN(etype) - 8;
7898     pic16_aopPut(AOP(result),"a",offset++);
7899
7900     while (1)  {
7901
7902         switch (ptype) {
7903         case POINTER:
7904         case IPOINTER:
7905             pic16_emitcode("inc","%s",rname);
7906             pic16_emitcode("mov","a,@%s",rname);
7907             break;
7908             
7909         case PPOINTER:
7910             pic16_emitcode("inc","%s",rname);
7911             pic16_emitcode("movx","a,@%s",rname);
7912             break;
7913
7914         case FPOINTER:
7915             pic16_emitcode("inc","dptr");
7916             pic16_emitcode("movx","a,@dptr");
7917             break;
7918             
7919         case CPOINTER:
7920             pic16_emitcode("clr","a");
7921             pic16_emitcode("inc","dptr");
7922             pic16_emitcode("movc","a","@a+dptr");
7923             break;
7924             
7925         case GPOINTER:
7926             pic16_emitcode("inc","dptr");
7927             pic16_emitcode("lcall","__gptrget");
7928             break;
7929         }
7930
7931         rlen -= 8;            
7932         /* if we are done */
7933         if ( rlen <= 0 )
7934             break ;
7935         
7936         pic16_aopPut(AOP(result),"a",offset++);
7937                               
7938     }
7939     
7940     if (rlen) {
7941         pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7942         pic16_aopPut(AOP(result),"a",offset);          
7943     }
7944     
7945     return ;
7946 }
7947
7948 #if 0
7949 /*-----------------------------------------------------------------*/
7950 /* genDataPointerGet - generates code when ptr offset is known     */
7951 /*-----------------------------------------------------------------*/
7952 static void genDataPointerGet (operand *left, 
7953                                operand *result, 
7954                                iCode *ic)
7955 {
7956   int size , offset = 0;
7957
7958
7959   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7960
7961
7962   /* optimization - most of the time, left and result are the same
7963    * address, but different types. for the pic code, we could omit
7964    * the following
7965    */
7966
7967   pic16_aopOp(result,ic,TRUE);
7968
7969   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7970
7971   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7972
7973   size = AOP_SIZE(result);
7974
7975   while (size--) {
7976     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7977     offset++;
7978   }
7979
7980   pic16_freeAsmop(left,NULL,ic,TRUE);
7981   pic16_freeAsmop(result,NULL,ic,TRUE);
7982 }
7983 #endif
7984 /*-----------------------------------------------------------------*/
7985 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
7986 /*-----------------------------------------------------------------*/
7987 static void genNearPointerGet (operand *left, 
7988                                operand *result, 
7989                                iCode *ic)
7990 {
7991     asmop *aop = NULL;
7992     //regs *preg = NULL ;
7993     char *rname ;
7994     sym_link *rtype, *retype;
7995     sym_link *ltype = operandType(left);    
7996     //char buffer[80];
7997
7998     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7999
8000     rtype = operandType(result);
8001     retype= getSpec(rtype);
8002     
8003     pic16_aopOp(left,ic,FALSE);
8004     
8005     /* if left is rematerialisable and
8006        result is not bit variable type and
8007        the left is pointer to data space i.e
8008        lower 128 bytes of space */
8009     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8010         !IS_BITVAR(retype)         &&
8011         DCL_TYPE(ltype) == POINTER) {
8012       //genDataPointerGet (left,result,ic);
8013         return ;
8014     }
8015     
8016     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8017
8018         /* if the value is already in a pointer register
8019        then don't need anything more */
8020     if (!AOP_INPREG(AOP(left))) {
8021         /* otherwise get a free pointer register */
8022     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8023 /*
8024         aop = newAsmop(0);
8025         preg = getFreePtr(ic,&aop,FALSE);
8026         pic16_emitcode("mov","%s,%s",
8027                 preg->name,
8028                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8029         rname = preg->name ;
8030 */
8031     rname ="BAD";
8032     } else
8033         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8034     
8035     pic16_aopOp (result,ic,FALSE);
8036     
8037       /* if bitfield then unpack the bits */
8038     if (IS_BITVAR(retype)) 
8039         genUnpackBits (result,rname,POINTER);
8040     else {
8041         /* we have can just get the values */
8042       int size = AOP_SIZE(result);
8043       int offset = 0 ;  
8044         
8045       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8046
8047       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8048       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8049       while(size--) {
8050         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8051         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8052         if(size)
8053           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8054       }
8055 /*
8056         while (size--) {
8057             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8058
8059                 pic16_emitcode("mov","a,@%s",rname);
8060                 pic16_aopPut(AOP(result),"a",offset);
8061             } else {
8062                 sprintf(buffer,"@%s",rname);
8063                 pic16_aopPut(AOP(result),buffer,offset);
8064             }
8065             offset++ ;
8066             if (size)
8067                 pic16_emitcode("inc","%s",rname);
8068         }
8069 */
8070     }
8071
8072     /* now some housekeeping stuff */
8073     if (aop) {
8074         /* we had to allocate for this iCode */
8075     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8076         pic16_freeAsmop(NULL,aop,ic,TRUE);
8077     } else { 
8078         /* we did not allocate which means left
8079            already in a pointer register, then
8080            if size > 0 && this could be used again
8081            we have to point it back to where it 
8082            belongs */
8083     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8084         if (AOP_SIZE(result) > 1 &&
8085             !OP_SYMBOL(left)->remat &&
8086             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8087               ic->depth )) {
8088             int size = AOP_SIZE(result) - 1;
8089             while (size--)
8090                 pic16_emitcode("dec","%s",rname);
8091         }
8092     }
8093
8094     /* done */
8095     pic16_freeAsmop(left,NULL,ic,TRUE);
8096     pic16_freeAsmop(result,NULL,ic,TRUE);
8097      
8098 }
8099
8100 /*-----------------------------------------------------------------*/
8101 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
8102 /*-----------------------------------------------------------------*/
8103 static void genPagedPointerGet (operand *left, 
8104                                operand *result, 
8105                                iCode *ic)
8106 {
8107     asmop *aop = NULL;
8108     regs *preg = NULL ;
8109     char *rname ;
8110     sym_link *rtype, *retype;    
8111
8112     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8113
8114     rtype = operandType(result);
8115     retype= getSpec(rtype);
8116     
8117     pic16_aopOp(left,ic,FALSE);
8118
8119   /* if the value is already in a pointer register
8120        then don't need anything more */
8121     if (!AOP_INPREG(AOP(left))) {
8122         /* otherwise get a free pointer register */
8123         aop = newAsmop(0);
8124         preg = getFreePtr(ic,&aop,FALSE);
8125         pic16_emitcode("mov","%s,%s",
8126                 preg->name,
8127                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8128         rname = preg->name ;
8129     } else
8130         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8131     
8132     pic16_freeAsmop(left,NULL,ic,TRUE);
8133     pic16_aopOp (result,ic,FALSE);
8134
8135     /* if bitfield then unpack the bits */
8136     if (IS_BITVAR(retype)) 
8137         genUnpackBits (result,rname,PPOINTER);
8138     else {
8139         /* we have can just get the values */
8140         int size = AOP_SIZE(result);
8141         int offset = 0 ;        
8142         
8143         while (size--) {
8144             
8145             pic16_emitcode("movx","a,@%s",rname);
8146             pic16_aopPut(AOP(result),"a",offset);
8147             
8148             offset++ ;
8149             
8150             if (size)
8151                 pic16_emitcode("inc","%s",rname);
8152         }
8153     }
8154
8155     /* now some housekeeping stuff */
8156     if (aop) {
8157         /* we had to allocate for this iCode */
8158         pic16_freeAsmop(NULL,aop,ic,TRUE);
8159     } else { 
8160         /* we did not allocate which means left
8161            already in a pointer register, then
8162            if size > 0 && this could be used again
8163            we have to point it back to where it 
8164            belongs */
8165         if (AOP_SIZE(result) > 1 &&
8166             !OP_SYMBOL(left)->remat &&
8167             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8168               ic->depth )) {
8169             int size = AOP_SIZE(result) - 1;
8170             while (size--)
8171                 pic16_emitcode("dec","%s",rname);
8172         }
8173     }
8174
8175     /* done */
8176     pic16_freeAsmop(result,NULL,ic,TRUE);
8177     
8178         
8179 }
8180
8181 /*-----------------------------------------------------------------*/
8182 /* genFarPointerGet - gget value from far space                    */
8183 /*-----------------------------------------------------------------*/
8184 static void genFarPointerGet (operand *left,
8185                               operand *result, iCode *ic)
8186 {
8187     int size, offset ;
8188     sym_link *retype = getSpec(operandType(result));
8189
8190     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8191
8192     pic16_aopOp(left,ic,FALSE);
8193
8194     /* if the operand is already in dptr 
8195     then we do nothing else we move the value to dptr */
8196     if (AOP_TYPE(left) != AOP_STR) {
8197         /* if this is remateriazable */
8198         if (AOP_TYPE(left) == AOP_IMMD)
8199             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8200         else { /* we need to get it byte by byte */
8201             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8202             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8203             if (options.model == MODEL_FLAT24)
8204             {
8205                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8206             }
8207         }
8208     }
8209     /* so dptr know contains the address */
8210     pic16_freeAsmop(left,NULL,ic,TRUE);
8211     pic16_aopOp(result,ic,FALSE);
8212
8213     /* if bit then unpack */
8214     if (IS_BITVAR(retype)) 
8215         genUnpackBits(result,"dptr",FPOINTER);
8216     else {
8217         size = AOP_SIZE(result);
8218         offset = 0 ;
8219
8220         while (size--) {
8221             pic16_emitcode("movx","a,@dptr");
8222             pic16_aopPut(AOP(result),"a",offset++);
8223             if (size)
8224                 pic16_emitcode("inc","dptr");
8225         }
8226     }
8227
8228     pic16_freeAsmop(result,NULL,ic,TRUE);
8229 }
8230 #if 0
8231 /*-----------------------------------------------------------------*/
8232 /* genCodePointerGet - get value from code space                  */
8233 /*-----------------------------------------------------------------*/
8234 static void genCodePointerGet (operand *left,
8235                                 operand *result, iCode *ic)
8236 {
8237     int size, offset ;
8238     sym_link *retype = getSpec(operandType(result));
8239
8240     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8241
8242     pic16_aopOp(left,ic,FALSE);
8243
8244     /* if the operand is already in dptr 
8245     then we do nothing else we move the value to dptr */
8246     if (AOP_TYPE(left) != AOP_STR) {
8247         /* if this is remateriazable */
8248         if (AOP_TYPE(left) == AOP_IMMD)
8249             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8250         else { /* we need to get it byte by byte */
8251             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8252             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8253             if (options.model == MODEL_FLAT24)
8254             {
8255                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8256             }
8257         }
8258     }
8259     /* so dptr know contains the address */
8260     pic16_freeAsmop(left,NULL,ic,TRUE);
8261     pic16_aopOp(result,ic,FALSE);
8262
8263     /* if bit then unpack */
8264     if (IS_BITVAR(retype)) 
8265         genUnpackBits(result,"dptr",CPOINTER);
8266     else {
8267         size = AOP_SIZE(result);
8268         offset = 0 ;
8269
8270         while (size--) {
8271             pic16_emitcode("clr","a");
8272             pic16_emitcode("movc","a,@a+dptr");
8273             pic16_aopPut(AOP(result),"a",offset++);
8274             if (size)
8275                 pic16_emitcode("inc","dptr");
8276         }
8277     }
8278
8279     pic16_freeAsmop(result,NULL,ic,TRUE);
8280 }
8281 #endif
8282 /*-----------------------------------------------------------------*/
8283 /* genGenPointerGet - gget value from generic pointer space        */
8284 /*-----------------------------------------------------------------*/
8285 static void genGenPointerGet (operand *left,
8286                               operand *result, iCode *ic)
8287 {
8288   int size, offset ;
8289   sym_link *retype = getSpec(operandType(result));
8290
8291   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8292   pic16_aopOp(left,ic,FALSE);
8293   pic16_aopOp(result,ic,FALSE);
8294
8295
8296   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8297
8298   /* if the operand is already in dptr 
8299      then we do nothing else we move the value to dptr */
8300   //  if (AOP_TYPE(left) != AOP_STR) {
8301     /* if this is remateriazable */
8302     if (AOP_TYPE(left) == AOP_IMMD) {
8303       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8304       pic16_emitcode("mov","b,#%d",pointerCode(retype));
8305     }
8306     else { /* we need to get it byte by byte */
8307
8308       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8309       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8310
8311       size = AOP_SIZE(result);
8312       offset = 0 ;
8313
8314       while(size--) {
8315         pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8316         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8317         if(size)
8318           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8319       }
8320       goto release;
8321     }
8322     //}
8323   /* so dptr know contains the address */
8324
8325   /* if bit then unpack */
8326   //if (IS_BITVAR(retype)) 
8327   //  genUnpackBits(result,"dptr",GPOINTER);
8328
8329  release:
8330   pic16_freeAsmop(left,NULL,ic,TRUE);
8331   pic16_freeAsmop(result,NULL,ic,TRUE);
8332
8333 }
8334
8335 /*-----------------------------------------------------------------*/
8336 /* genConstPointerGet - get value from const generic pointer space */
8337 /*-----------------------------------------------------------------*/
8338 static void genConstPointerGet (operand *left,
8339                                 operand *result, iCode *ic)
8340 {
8341   //sym_link *retype = getSpec(operandType(result));
8342   symbol *albl = newiTempLabel(NULL);
8343   symbol *blbl = newiTempLabel(NULL);
8344   PIC_OPCODE poc;
8345
8346   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8347   pic16_aopOp(left,ic,FALSE);
8348   pic16_aopOp(result,ic,FALSE);
8349
8350
8351   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8352
8353   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8354
8355   pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8356   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8357   pic16_emitpLabel(albl->key);
8358
8359   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8360     
8361   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8362   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8363   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8364   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8365
8366   pic16_emitpLabel(blbl->key);
8367
8368   pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8369
8370
8371   pic16_freeAsmop(left,NULL,ic,TRUE);
8372   pic16_freeAsmop(result,NULL,ic,TRUE);
8373
8374 }
8375 /*-----------------------------------------------------------------*/
8376 /* genPointerGet - generate code for pointer get                   */
8377 /*-----------------------------------------------------------------*/
8378 static void genPointerGet (iCode *ic)
8379 {
8380     operand *left, *result ;
8381     sym_link *type, *etype;
8382     int p_type;
8383
8384     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8385
8386     left = IC_LEFT(ic);
8387     result = IC_RESULT(ic) ;
8388
8389     /* depending on the type of pointer we need to
8390     move it to the correct pointer register */
8391     type = operandType(left);
8392     etype = getSpec(type);
8393
8394     if (IS_PTR_CONST(type))
8395       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8396
8397     /* if left is of type of pointer then it is simple */
8398     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8399         p_type = DCL_TYPE(type);
8400     else {
8401         /* we have to go by the storage class */
8402         p_type = PTR_TYPE(SPEC_OCLS(etype));
8403
8404         DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8405
8406         if (SPEC_OCLS(etype)->codesp ) {
8407           DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8408           //p_type = CPOINTER ; 
8409         }
8410         else
8411             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8412               DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8413                /*p_type = FPOINTER ;*/ 
8414             else
8415                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8416                   DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8417 /*                  p_type = PPOINTER; */
8418                 else
8419                     if (SPEC_OCLS(etype) == idata )
8420                       DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8421 /*                      p_type = IPOINTER; */
8422                     else
8423                       DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8424 /*                      p_type = POINTER ; */
8425     }
8426
8427     /* now that we have the pointer type we assign
8428     the pointer values */
8429     switch (p_type) {
8430
8431     case POINTER:       
8432     case IPOINTER:
8433         genNearPointerGet (left,result,ic);
8434         break;
8435
8436     case PPOINTER:
8437         genPagedPointerGet(left,result,ic);
8438         break;
8439
8440     case FPOINTER:
8441         genFarPointerGet (left,result,ic);
8442         break;
8443
8444     case CPOINTER:
8445         genConstPointerGet (left,result,ic);
8446         //pic16_emitcodePointerGet (left,result,ic);
8447         break;
8448
8449     case GPOINTER:
8450       if (IS_PTR_CONST(type))
8451         genConstPointerGet (left,result,ic);
8452       else
8453         genGenPointerGet (left,result,ic);
8454       break;
8455     }
8456
8457 }
8458
8459 /*-----------------------------------------------------------------*/
8460 /* genPackBits - generates code for packed bit storage             */
8461 /*-----------------------------------------------------------------*/
8462 static void genPackBits (sym_link    *etype ,
8463                          operand *right ,
8464                          char *rname, int p_type)
8465 {
8466     int shCount = 0 ;
8467     int offset = 0  ;
8468     int rLen = 0 ;
8469     int blen, bstr ;   
8470     char *l ;
8471
8472     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8473     blen = SPEC_BLEN(etype);
8474     bstr = SPEC_BSTR(etype);
8475
8476     l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8477     MOVA(l);   
8478
8479     /* if the bit lenth is less than or    */
8480     /* it exactly fits a byte then         */
8481     if (SPEC_BLEN(etype) <= 8 )  {
8482         shCount = SPEC_BSTR(etype) ;
8483
8484         /* shift left acc */
8485         AccLsh(shCount);
8486
8487         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8488
8489
8490             switch (p_type) {
8491                 case POINTER:
8492                     pic16_emitcode ("mov","b,a");
8493                     pic16_emitcode("mov","a,@%s",rname);
8494                     break;
8495
8496                 case FPOINTER:
8497                     pic16_emitcode ("mov","b,a");
8498                     pic16_emitcode("movx","a,@dptr");
8499                     break;
8500
8501                 case GPOINTER:
8502                     pic16_emitcode ("push","b");
8503                     pic16_emitcode ("push","acc");
8504                     pic16_emitcode ("lcall","__gptrget");
8505                     pic16_emitcode ("pop","b");
8506                     break;
8507             }
8508
8509             pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8510                       ((unsigned char)(0xFF << (blen+bstr)) | 
8511                        (unsigned char)(0xFF >> (8-bstr)) ) );
8512             pic16_emitcode ("orl","a,b");
8513             if (p_type == GPOINTER)
8514                 pic16_emitcode("pop","b");
8515         }
8516     }
8517
8518     switch (p_type) {
8519         case POINTER:
8520             pic16_emitcode("mov","@%s,a",rname);
8521             break;
8522
8523         case FPOINTER:
8524             pic16_emitcode("movx","@dptr,a");
8525             break;
8526
8527         case GPOINTER:
8528             DEBUGpic16_emitcode(";lcall","__gptrput");
8529             break;
8530     }
8531
8532     /* if we r done */
8533     if ( SPEC_BLEN(etype) <= 8 )
8534         return ;
8535
8536     pic16_emitcode("inc","%s",rname);
8537     rLen = SPEC_BLEN(etype) ;     
8538
8539     /* now generate for lengths greater than one byte */
8540     while (1) {
8541
8542         l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8543
8544         rLen -= 8 ;
8545         if (rLen <= 0 )
8546             break ;
8547
8548         switch (p_type) {
8549             case POINTER:
8550                 if (*l == '@') {
8551                     MOVA(l);
8552                     pic16_emitcode("mov","@%s,a",rname);
8553                 } else
8554                     pic16_emitcode("mov","@%s,%s",rname,l);
8555                 break;
8556
8557             case FPOINTER:
8558                 MOVA(l);
8559                 pic16_emitcode("movx","@dptr,a");
8560                 break;
8561
8562             case GPOINTER:
8563                 MOVA(l);
8564                 DEBUGpic16_emitcode(";lcall","__gptrput");
8565                 break;  
8566         }   
8567         pic16_emitcode ("inc","%s",rname);
8568     }
8569
8570     MOVA(l);
8571
8572     /* last last was not complete */
8573     if (rLen)   {
8574         /* save the byte & read byte */
8575         switch (p_type) {
8576             case POINTER:
8577                 pic16_emitcode ("mov","b,a");
8578                 pic16_emitcode("mov","a,@%s",rname);
8579                 break;
8580
8581             case FPOINTER:
8582                 pic16_emitcode ("mov","b,a");
8583                 pic16_emitcode("movx","a,@dptr");
8584                 break;
8585
8586             case GPOINTER:
8587                 pic16_emitcode ("push","b");
8588                 pic16_emitcode ("push","acc");
8589                 pic16_emitcode ("lcall","__gptrget");
8590                 pic16_emitcode ("pop","b");
8591                 break;
8592         }
8593
8594         pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8595         pic16_emitcode ("orl","a,b");
8596     }
8597
8598     if (p_type == GPOINTER)
8599         pic16_emitcode("pop","b");
8600
8601     switch (p_type) {
8602
8603     case POINTER:
8604         pic16_emitcode("mov","@%s,a",rname);
8605         break;
8606         
8607     case FPOINTER:
8608         pic16_emitcode("movx","@dptr,a");
8609         break;
8610         
8611     case GPOINTER:
8612         DEBUGpic16_emitcode(";lcall","__gptrput");
8613         break;                  
8614     }
8615 }
8616 /*-----------------------------------------------------------------*/
8617 /* genDataPointerSet - remat pointer to data space                 */
8618 /*-----------------------------------------------------------------*/
8619 static void genDataPointerSet(operand *right,
8620                               operand *result,
8621                               iCode *ic)
8622 {
8623     int size, offset = 0 ;
8624     char *l, buffer[256];
8625
8626     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8627     pic16_aopOp(right,ic,FALSE);
8628     
8629     l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8630     size = AOP_SIZE(right);
8631 /*
8632     if ( AOP_TYPE(result) == AOP_PCODE) {
8633       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8634               AOP(result)->aopu.pcop->name,
8635               PCOI(AOP(result)->aopu.pcop)->offset);
8636     }
8637 */
8638
8639     // tsd, was l+1 - the underline `_' prefix was being stripped
8640     while (size--) {
8641       if (offset) {
8642         sprintf(buffer,"(%s + %d)",l,offset);
8643         fprintf(stderr,"oops  %s\n",buffer);
8644       } else
8645         sprintf(buffer,"%s",l);
8646
8647         if (AOP_TYPE(right) == AOP_LIT) {
8648           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8649           lit = lit >> (8*offset);
8650           if(lit&0xff) {
8651             pic16_emitcode("movlw","%d",lit);
8652             pic16_emitcode("movwf","%s",buffer);
8653
8654             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8655             //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8656             pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8657
8658           } else {
8659             pic16_emitcode("clrf","%s",buffer);
8660             //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8661             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8662           }
8663         }else {
8664           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8665           pic16_emitcode("movwf","%s",buffer);
8666
8667           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8668           //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8669           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8670
8671         }
8672
8673         offset++;
8674     }
8675
8676     pic16_freeAsmop(right,NULL,ic,TRUE);
8677     pic16_freeAsmop(result,NULL,ic,TRUE);
8678 }
8679
8680 /*-----------------------------------------------------------------*/
8681 /* genNearPointerSet - pic16_emitcode for near pointer put                */
8682 /*-----------------------------------------------------------------*/
8683 static void genNearPointerSet (operand *right,
8684                                operand *result, 
8685                                iCode *ic)
8686 {
8687   asmop *aop = NULL;
8688   char *l;
8689   sym_link *retype;
8690   sym_link *ptype = operandType(result);
8691
8692     
8693   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8694   retype= getSpec(operandType(right));
8695
8696   pic16_aopOp(result,ic,FALSE);
8697
8698     
8699   /* if the result is rematerializable &
8700      in data space & not a bit variable */
8701   //if (AOP_TYPE(result) == AOP_IMMD &&
8702   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8703       DCL_TYPE(ptype) == POINTER   &&
8704       !IS_BITVAR(retype)) {
8705     genDataPointerSet (right,result,ic);
8706     pic16_freeAsmop(result,NULL,ic,TRUE);
8707     return;
8708   }
8709
8710   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8711   pic16_aopOp(right,ic,FALSE);
8712   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8713
8714   /* if the value is already in a pointer register
8715      then don't need anything more */
8716   if (!AOP_INPREG(AOP(result))) {
8717     /* otherwise get a free pointer register */
8718     //aop = newAsmop(0);
8719     //preg = getFreePtr(ic,&aop,FALSE);
8720     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8721     //pic16_emitcode("mov","%s,%s",
8722     //         preg->name,
8723     //         pic16_aopGet(AOP(result),0,FALSE,TRUE));
8724     //rname = preg->name ;
8725     //pic16_emitcode("movwf","fsr0");
8726     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8727     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8728     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8729     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8730     goto release;
8731
8732   }// else
8733   //   rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8734
8735
8736   /* if bitfield then unpack the bits */
8737   if (IS_BITVAR(retype)) {
8738     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8739            "The programmer is obviously confused");
8740     //genPackBits (retype,right,rname,POINTER);
8741     exit(1);
8742   }
8743   else {
8744     /* we have can just get the values */
8745     int size = AOP_SIZE(right);
8746     int offset = 0 ;    
8747
8748     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8749     while (size--) {
8750       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8751       if (*l == '@' ) {
8752         //MOVA(l);
8753         //pic16_emitcode("mov","@%s,a",rname);
8754         pic16_emitcode("movf","indf0,w ;1");
8755       } else {
8756
8757         if (AOP_TYPE(right) == AOP_LIT) {
8758           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8759           if(lit) {
8760             pic16_emitcode("movlw","%s",l);
8761             pic16_emitcode("movwf","indf0 ;2");
8762           } else 
8763             pic16_emitcode("clrf","indf0");
8764         }else {
8765           pic16_emitcode("movf","%s,w",l);
8766           pic16_emitcode("movwf","indf0 ;2");
8767         }
8768         //pic16_emitcode("mov","@%s,%s",rname,l);
8769       }
8770       if (size)
8771         pic16_emitcode("incf","fsr0,f ;3");
8772       //pic16_emitcode("inc","%s",rname);
8773       offset++;
8774     }
8775   }
8776
8777   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8778   /* now some housekeeping stuff */
8779   if (aop) {
8780     /* we had to allocate for this iCode */
8781     pic16_freeAsmop(NULL,aop,ic,TRUE);
8782   } else { 
8783     /* we did not allocate which means left
8784        already in a pointer register, then
8785        if size > 0 && this could be used again
8786        we have to point it back to where it 
8787        belongs */
8788     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8789     if (AOP_SIZE(right) > 1 &&
8790         !OP_SYMBOL(result)->remat &&
8791         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8792           ic->depth )) {
8793       int size = AOP_SIZE(right) - 1;
8794       while (size--)
8795         pic16_emitcode("decf","fsr0,f");
8796       //pic16_emitcode("dec","%s",rname);
8797     }
8798   }
8799
8800   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8801   /* done */
8802  release:
8803   pic16_freeAsmop(right,NULL,ic,TRUE);
8804   pic16_freeAsmop(result,NULL,ic,TRUE);
8805 }
8806
8807 /*-----------------------------------------------------------------*/
8808 /* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
8809 /*-----------------------------------------------------------------*/
8810 static void genPagedPointerSet (operand *right,
8811                                operand *result, 
8812                                iCode *ic)
8813 {
8814     asmop *aop = NULL;
8815     regs *preg = NULL ;
8816     char *rname , *l;
8817     sym_link *retype;
8818        
8819     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8820
8821     retype= getSpec(operandType(right));
8822     
8823     pic16_aopOp(result,ic,FALSE);
8824     
8825     /* if the value is already in a pointer register
8826        then don't need anything more */
8827     if (!AOP_INPREG(AOP(result))) {
8828         /* otherwise get a free pointer register */
8829         aop = newAsmop(0);
8830         preg = getFreePtr(ic,&aop,FALSE);
8831         pic16_emitcode("mov","%s,%s",
8832                 preg->name,
8833                 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8834         rname = preg->name ;
8835     } else
8836         rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8837     
8838     pic16_freeAsmop(result,NULL,ic,TRUE);
8839     pic16_aopOp (right,ic,FALSE);
8840
8841     /* if bitfield then unpack the bits */
8842     if (IS_BITVAR(retype)) 
8843         genPackBits (retype,right,rname,PPOINTER);
8844     else {
8845         /* we have can just get the values */
8846         int size = AOP_SIZE(right);
8847         int offset = 0 ;        
8848         
8849         while (size--) {
8850             l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8851             
8852             MOVA(l);
8853             pic16_emitcode("movx","@%s,a",rname);
8854
8855             if (size)
8856                 pic16_emitcode("inc","%s",rname);
8857
8858             offset++;
8859         }
8860     }
8861     
8862     /* now some housekeeping stuff */
8863     if (aop) {
8864         /* we had to allocate for this iCode */
8865         pic16_freeAsmop(NULL,aop,ic,TRUE);
8866     } else { 
8867         /* we did not allocate which means left
8868            already in a pointer register, then
8869            if size > 0 && this could be used again
8870            we have to point it back to where it 
8871            belongs */
8872         if (AOP_SIZE(right) > 1 &&
8873             !OP_SYMBOL(result)->remat &&
8874             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8875               ic->depth )) {
8876             int size = AOP_SIZE(right) - 1;
8877             while (size--)
8878                 pic16_emitcode("dec","%s",rname);
8879         }
8880     }
8881
8882     /* done */
8883     pic16_freeAsmop(right,NULL,ic,TRUE);
8884     
8885         
8886 }
8887
8888 /*-----------------------------------------------------------------*/
8889 /* genFarPointerSet - set value from far space                     */
8890 /*-----------------------------------------------------------------*/
8891 static void genFarPointerSet (operand *right,
8892                               operand *result, iCode *ic)
8893 {
8894     int size, offset ;
8895     sym_link *retype = getSpec(operandType(right));
8896
8897     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8898     pic16_aopOp(result,ic,FALSE);
8899
8900     /* if the operand is already in dptr 
8901     then we do nothing else we move the value to dptr */
8902     if (AOP_TYPE(result) != AOP_STR) {
8903         /* if this is remateriazable */
8904         if (AOP_TYPE(result) == AOP_IMMD)
8905             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8906         else { /* we need to get it byte by byte */
8907             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8908             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8909             if (options.model == MODEL_FLAT24)
8910             {
8911                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8912             }
8913         }
8914     }
8915     /* so dptr know contains the address */
8916     pic16_freeAsmop(result,NULL,ic,TRUE);
8917     pic16_aopOp(right,ic,FALSE);
8918
8919     /* if bit then unpack */
8920     if (IS_BITVAR(retype)) 
8921         genPackBits(retype,right,"dptr",FPOINTER);
8922     else {
8923         size = AOP_SIZE(right);
8924         offset = 0 ;
8925
8926         while (size--) {
8927             char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8928             MOVA(l);
8929             pic16_emitcode("movx","@dptr,a");
8930             if (size)
8931                 pic16_emitcode("inc","dptr");
8932         }
8933     }
8934
8935     pic16_freeAsmop(right,NULL,ic,TRUE);
8936 }
8937
8938 /*-----------------------------------------------------------------*/
8939 /* genGenPointerSet - set value from generic pointer space         */
8940 /*-----------------------------------------------------------------*/
8941 static void genGenPointerSet (operand *right,
8942                               operand *result, iCode *ic)
8943 {
8944   int size, offset ;
8945   sym_link *retype = getSpec(operandType(right));
8946
8947   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8948
8949   pic16_aopOp(result,ic,FALSE);
8950   pic16_aopOp(right,ic,FALSE);
8951   size = AOP_SIZE(right);
8952
8953   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8954
8955   /* if the operand is already in dptr 
8956      then we do nothing else we move the value to dptr */
8957   if (AOP_TYPE(result) != AOP_STR) {
8958     /* if this is remateriazable */
8959     if (AOP_TYPE(result) == AOP_IMMD) {
8960       pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8961       pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8962     }
8963     else { /* we need to get it byte by byte */
8964       //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8965       size = AOP_SIZE(right);
8966       offset = 0 ;
8967
8968       /* hack hack! see if this the FSR. If so don't load W */
8969       if(AOP_TYPE(right) != AOP_ACC) {
8970
8971
8972         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8973         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8974
8975         if(AOP_SIZE(result) > 1) {
8976           pic16_emitpcode(POC_BCF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8977           pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8978           pic16_emitpcode(POC_BSF,  pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8979
8980         }
8981
8982         //if(size==2)
8983         //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8984         //if(size==4) {
8985         //  pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
8986         //  pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
8987         //}
8988
8989         while(size--) {
8990           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
8991           pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
8992           
8993           if(size)
8994             pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8995         }
8996
8997
8998         goto release;
8999       } 
9000
9001       if(aopIdx(AOP(result),0) != 4) {
9002
9003         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9004         goto release;
9005       }
9006
9007       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9008       goto release;
9009
9010     }
9011   }
9012   /* so dptr know contains the address */
9013
9014
9015   /* if bit then unpack */
9016   if (IS_BITVAR(retype)) 
9017     genPackBits(retype,right,"dptr",GPOINTER);
9018   else {
9019     size = AOP_SIZE(right);
9020     offset = 0 ;
9021
9022   DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9023
9024     while (size--) {
9025
9026       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9027       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9028
9029       if (AOP_TYPE(right) == AOP_LIT) 
9030         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9031       else
9032         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9033
9034       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9035
9036       offset++;
9037     }
9038   }
9039
9040  release:
9041   pic16_freeAsmop(right,NULL,ic,TRUE);
9042   pic16_freeAsmop(result,NULL,ic,TRUE);
9043 }
9044
9045 /*-----------------------------------------------------------------*/
9046 /* genPointerSet - stores the value into a pointer location        */
9047 /*-----------------------------------------------------------------*/
9048 static void genPointerSet (iCode *ic)
9049 {    
9050     operand *right, *result ;
9051     sym_link *type, *etype;
9052     int p_type;
9053
9054     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9055
9056     right = IC_RIGHT(ic);
9057     result = IC_RESULT(ic) ;
9058
9059     /* depending on the type of pointer we need to
9060     move it to the correct pointer register */
9061     type = operandType(result);
9062     etype = getSpec(type);
9063     /* if left is of type of pointer then it is simple */
9064     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9065         p_type = DCL_TYPE(type);
9066     }
9067     else {
9068         /* we have to go by the storage class */
9069         p_type = PTR_TYPE(SPEC_OCLS(etype));
9070
9071 /*      if (SPEC_OCLS(etype)->codesp ) { */
9072 /*          p_type = CPOINTER ;  */
9073 /*      } */
9074 /*      else */
9075 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9076 /*              p_type = FPOINTER ; */
9077 /*          else */
9078 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9079 /*                  p_type = PPOINTER ; */
9080 /*              else */
9081 /*                  if (SPEC_OCLS(etype) == idata ) */
9082 /*                      p_type = IPOINTER ; */
9083 /*                  else */
9084 /*                      p_type = POINTER ; */
9085     }
9086
9087     /* now that we have the pointer type we assign
9088     the pointer values */
9089     switch (p_type) {
9090
9091     case POINTER:
9092     case IPOINTER:
9093         genNearPointerSet (right,result,ic);
9094         break;
9095
9096     case PPOINTER:
9097         genPagedPointerSet (right,result,ic);
9098         break;
9099
9100     case FPOINTER:
9101         genFarPointerSet (right,result,ic);
9102         break;
9103
9104     case GPOINTER:
9105         genGenPointerSet (right,result,ic);
9106         break;
9107
9108     default:
9109       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9110               "genPointerSet: illegal pointer type");
9111     }
9112 }
9113
9114 /*-----------------------------------------------------------------*/
9115 /* genIfx - generate code for Ifx statement                        */
9116 /*-----------------------------------------------------------------*/
9117 static void genIfx (iCode *ic, iCode *popIc)
9118 {
9119   operand *cond = IC_COND(ic);
9120   int isbit =0;
9121
9122   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9123
9124   pic16_aopOp(cond,ic,FALSE);
9125
9126   /* get the value into acc */
9127   if (AOP_TYPE(cond) != AOP_CRY)
9128     pic16_toBoolean(cond);
9129   else
9130     isbit = 1;
9131   /* the result is now in the accumulator */
9132   pic16_freeAsmop(cond,NULL,ic,TRUE);
9133
9134   /* if there was something to be popped then do it */
9135   if (popIc)
9136     genIpop(popIc);
9137
9138   /* if the condition is  a bit variable */
9139   if (isbit && IS_ITEMP(cond) && 
9140       SPIL_LOC(cond)) {
9141     genIfxJump(ic,SPIL_LOC(cond)->rname);
9142     DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9143   }
9144   else {
9145     if (isbit && !IS_ITEMP(cond))
9146       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9147     else
9148       genIfxJump(ic,"a");
9149   }
9150   ic->generated = 1;
9151
9152 }
9153
9154 /*-----------------------------------------------------------------*/
9155 /* genAddrOf - generates code for address of                       */
9156 /*-----------------------------------------------------------------*/
9157 static void genAddrOf (iCode *ic)
9158 {
9159   operand *right, *result, *left;
9160   int size, offset ;
9161
9162   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9163
9164
9165   //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9166
9167   pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9168   pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9169   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9170
9171   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9172
9173   size = AOP_SIZE(IC_RESULT(ic));
9174   offset = 0;
9175
9176   while (size--) {
9177     pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9178     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9179     offset++;
9180   }
9181
9182   pic16_freeAsmop(left,NULL,ic,FALSE);
9183   pic16_freeAsmop(result,NULL,ic,TRUE);
9184
9185 }
9186
9187 #if 0
9188 /*-----------------------------------------------------------------*/
9189 /* genFarFarAssign - assignment when both are in far space         */
9190 /*-----------------------------------------------------------------*/
9191 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9192 {
9193     int size = AOP_SIZE(right);
9194     int offset = 0;
9195     char *l ;
9196     /* first push the right side on to the stack */
9197     while (size--) {
9198         l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9199         MOVA(l);
9200         pic16_emitcode ("push","acc");
9201     }
9202     
9203     pic16_freeAsmop(right,NULL,ic,FALSE);
9204     /* now assign DPTR to result */
9205     pic16_aopOp(result,ic,FALSE);
9206     size = AOP_SIZE(result);
9207     while (size--) {
9208         pic16_emitcode ("pop","acc");
9209         pic16_aopPut(AOP(result),"a",--offset);
9210     }
9211     pic16_freeAsmop(result,NULL,ic,FALSE);
9212         
9213 }
9214 #endif
9215
9216 /*-----------------------------------------------------------------*/
9217 /* genAssign - generate code for assignment                        */
9218 /*-----------------------------------------------------------------*/
9219 static void genAssign (iCode *ic)
9220 {
9221   operand *result, *right;
9222   int size, offset,know_W;
9223   unsigned long lit = 0L;
9224
9225   result = IC_RESULT(ic);
9226   right  = IC_RIGHT(ic) ;
9227
9228   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9229
9230   /* if they are the same */
9231   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9232     return ;
9233
9234   pic16_aopOp(right,ic,FALSE);
9235   pic16_aopOp(result,ic,TRUE);
9236
9237   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9238
9239   /* if they are the same registers */
9240   if (pic16_sameRegs(AOP(right),AOP(result)))
9241     goto release;
9242
9243   /* if the result is a bit */
9244   if (AOP_TYPE(result) == AOP_CRY) {
9245
9246     /* if the right size is a literal then
9247        we know what the value is */
9248     if (AOP_TYPE(right) == AOP_LIT) {
9249           
9250       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9251                   pic16_popGet(AOP(result),0));
9252
9253       if (((int) operandLitValue(right))) 
9254         pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9255                        AOP(result)->aopu.aop_dir,
9256                        AOP(result)->aopu.aop_dir);
9257       else
9258         pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9259                        AOP(result)->aopu.aop_dir,
9260                        AOP(result)->aopu.aop_dir);
9261       goto release;
9262     }
9263
9264     /* the right is also a bit variable */
9265     if (AOP_TYPE(right) == AOP_CRY) {
9266       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9267       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9268       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9269
9270       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9271                      AOP(result)->aopu.aop_dir,
9272                      AOP(result)->aopu.aop_dir);
9273       pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9274                      AOP(right)->aopu.aop_dir,
9275                      AOP(right)->aopu.aop_dir);
9276       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9277                      AOP(result)->aopu.aop_dir,
9278                      AOP(result)->aopu.aop_dir);
9279       goto release ;
9280     }
9281
9282     /* we need to or */
9283     pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9284     pic16_toBoolean(right);
9285     emitSKPZ;
9286     pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9287     //pic16_aopPut(AOP(result),"a",0);
9288     goto release ;
9289   }
9290
9291   /* bit variables done */
9292   /* general case */
9293   size = AOP_SIZE(result);
9294   offset = 0 ;
9295   if(AOP_TYPE(right) == AOP_LIT)
9296     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9297
9298   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9299   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9300     if(aopIdx(AOP(result),0) == 4) {
9301   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9302       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9303       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9304       goto release;
9305     } else
9306       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9307   }
9308
9309   know_W=-1;
9310   while (size--) {
9311   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9312     if(AOP_TYPE(right) == AOP_LIT) {
9313       if(lit&0xff) {
9314         if(know_W != (lit&0xff))
9315           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9316         know_W = lit&0xff;
9317         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9318       } else
9319         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9320
9321       lit >>= 8;
9322
9323     } else if (AOP_TYPE(right) == AOP_CRY) {
9324       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9325       if(offset == 0) {
9326         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9327         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9328       }
9329     } else {
9330   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9331       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9332       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9333     }
9334             
9335     offset++;
9336   }
9337
9338     
9339  release:
9340   pic16_freeAsmop (right,NULL,ic,FALSE);
9341   pic16_freeAsmop (result,NULL,ic,TRUE);
9342 }   
9343
9344 /*-----------------------------------------------------------------*/
9345 /* genJumpTab - genrates code for jump table                       */
9346 /*-----------------------------------------------------------------*/
9347 static void genJumpTab (iCode *ic)
9348 {
9349     symbol *jtab;
9350     char *l;
9351
9352     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9353
9354     pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9355     /* get the condition into accumulator */
9356     l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9357     MOVA(l);
9358     /* multiply by three */
9359     pic16_emitcode("add","a,acc");
9360     pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9361
9362     jtab = newiTempLabel(NULL);
9363     pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9364     pic16_emitcode("jmp","@a+dptr");
9365     pic16_emitcode("","%05d_DS_:",jtab->key+100);
9366
9367     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9368     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9369     emitSKPNC;
9370     pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9371     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9372     pic16_emitpLabel(jtab->key);
9373
9374     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9375
9376     /* now generate the jump labels */
9377     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9378          jtab = setNextItem(IC_JTLABELS(ic))) {
9379         pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9380         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9381         
9382     }
9383
9384 }
9385
9386 /*-----------------------------------------------------------------*/
9387 /* genMixedOperation - gen code for operators between mixed types  */
9388 /*-----------------------------------------------------------------*/
9389 /*
9390   TSD - Written for the PIC port - but this unfortunately is buggy.
9391   This routine is good in that it is able to efficiently promote 
9392   types to different (larger) sizes. Unfortunately, the temporary
9393   variables that are optimized out by this routine are sometimes
9394   used in other places. So until I know how to really parse the 
9395   iCode tree, I'm going to not be using this routine :(.
9396 */
9397 static int genMixedOperation (iCode *ic)
9398 {
9399 #if 0
9400   operand *result = IC_RESULT(ic);
9401   sym_link *ctype = operandType(IC_LEFT(ic));
9402   operand *right = IC_RIGHT(ic);
9403   int ret = 0;
9404   int big,small;
9405   int offset;
9406
9407   iCode *nextic;
9408   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9409
9410   pic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9411
9412   nextic = ic->next;
9413   if(!nextic)
9414     return 0;
9415
9416   nextright = IC_RIGHT(nextic);
9417   nextleft  = IC_LEFT(nextic);
9418   nextresult = IC_RESULT(nextic);
9419
9420   pic16_aopOp(right,ic,FALSE);
9421   pic16_aopOp(result,ic,FALSE);
9422   pic16_aopOp(nextright,  nextic, FALSE);
9423   pic16_aopOp(nextleft,   nextic, FALSE);
9424   pic16_aopOp(nextresult, nextic, FALSE);
9425
9426   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9427
9428     operand *t = right;
9429     right = nextright;
9430     nextright = t; 
9431
9432     pic16_emitcode(";remove right +","");
9433
9434   } else   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9435 /*
9436     operand *t = right;
9437     right = nextleft;
9438     nextleft = t; 
9439 */
9440     pic16_emitcode(";remove left +","");
9441   } else
9442     return 0;
9443
9444   big = AOP_SIZE(nextleft);
9445   small = AOP_SIZE(nextright);
9446
9447   switch(nextic->op) {
9448
9449   case '+':
9450     pic16_emitcode(";optimize a +","");
9451     /* if unsigned or not an integral type */
9452     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9453       pic16_emitcode(";add a bit to something","");
9454     } else {
9455
9456       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9457
9458       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9459         pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9460         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9461       } else
9462         pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9463
9464       offset = 0;
9465       while(--big) {
9466
9467         offset++;
9468
9469         if(--small) {
9470           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9471             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9472             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9473           }
9474
9475           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9476           emitSKPNC;
9477           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9478                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9479                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9480           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9481           pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9482
9483         } else {
9484           pic16_emitcode("rlf","known_zero,w");
9485
9486           /*
9487             if right is signed
9488               btfsc  right,7
9489                addlw ff
9490           */
9491           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9492             pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9494           } else {
9495             pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9496           }
9497         }
9498       }
9499       ret = 1;
9500     }
9501   }
9502   ret = 1;
9503
9504 release:
9505   pic16_freeAsmop(right,NULL,ic,TRUE);
9506   pic16_freeAsmop(result,NULL,ic,TRUE);
9507   pic16_freeAsmop(nextright,NULL,ic,TRUE);
9508   pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9509   if(ret)
9510     nextic->generated = 1;
9511
9512   return ret;
9513 #else
9514   return 0;
9515 #endif
9516 }
9517 /*-----------------------------------------------------------------*/
9518 /* genCast - gen code for casting                                  */
9519 /*-----------------------------------------------------------------*/
9520 static void genCast (iCode *ic)
9521 {
9522     operand *result = IC_RESULT(ic);
9523     sym_link *ctype = operandType(IC_LEFT(ic));
9524     sym_link *rtype = operandType(IC_RIGHT(ic));
9525     operand *right = IC_RIGHT(ic);
9526     int size, offset ;
9527
9528     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9529     /* if they are equivalent then do nothing */
9530     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9531         return ;
9532
9533     pic16_aopOp(right,ic,FALSE) ;
9534     pic16_aopOp(result,ic,FALSE);
9535
9536     DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9537
9538     /* if the result is a bit */
9539     if (AOP_TYPE(result) == AOP_CRY) {
9540         /* if the right size is a literal then
9541         we know what the value is */
9542       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9543         if (AOP_TYPE(right) == AOP_LIT) {
9544
9545           pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9546                       pic16_popGet(AOP(result),0));
9547
9548             if (((int) operandLitValue(right))) 
9549               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9550                        AOP(result)->aopu.aop_dir,
9551                        AOP(result)->aopu.aop_dir);
9552             else
9553               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9554                        AOP(result)->aopu.aop_dir,
9555                        AOP(result)->aopu.aop_dir);
9556
9557             goto release;
9558         }
9559
9560         /* the right is also a bit variable */
9561         if (AOP_TYPE(right) == AOP_CRY) {
9562
9563           emitCLRC;
9564           pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9565
9566           pic16_emitcode("clrc","");
9567           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9568                    AOP(right)->aopu.aop_dir,
9569                    AOP(right)->aopu.aop_dir);
9570             pic16_aopPut(AOP(result),"c",0);
9571             goto release ;
9572         }
9573
9574         /* we need to or */
9575         if (AOP_TYPE(right) == AOP_REG) {
9576           pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9577           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9578           pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9579         }
9580         pic16_toBoolean(right);
9581         pic16_aopPut(AOP(result),"a",0);
9582         goto release ;
9583     }
9584
9585     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9586       int offset = 1;
9587       size = AOP_SIZE(result);
9588
9589       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9590
9591       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
9592       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9593       pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
9594
9595       while (size--)
9596         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9597
9598       goto release;
9599     }
9600
9601     /* if they are the same size : or less */
9602     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9603
9604         /* if they are in the same place */
9605       if (pic16_sameRegs(AOP(right),AOP(result)))
9606         goto release;
9607
9608       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9609       if (IS_PTR_CONST(rtype))
9610         DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9611       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9612         DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9613
9614       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9615         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9616         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9617         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9618         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9619         if(AOP_SIZE(result) <2)
9620           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9621
9622       } else {
9623
9624         /* if they in different places then copy */
9625         size = AOP_SIZE(result);
9626         offset = 0 ;
9627         while (size--) {
9628           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9629           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9630
9631           //pic16_aopPut(AOP(result),
9632           // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9633           // offset);
9634
9635           offset++;
9636         }
9637       }
9638       goto release;
9639     }
9640
9641
9642     /* if the result is of type pointer */
9643     if (IS_PTR(ctype)) {
9644
9645         int p_type;
9646         sym_link *type = operandType(right);
9647         sym_link *etype = getSpec(type);
9648       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9649
9650         /* pointer to generic pointer */
9651         if (IS_GENPTR(ctype)) {
9652             char *l = zero;
9653             
9654             if (IS_PTR(type)) 
9655                 p_type = DCL_TYPE(type);
9656             else {
9657                 /* we have to go by the storage class */
9658                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9659
9660 /*              if (SPEC_OCLS(etype)->codesp )  */
9661 /*                  p_type = CPOINTER ;  */
9662 /*              else */
9663 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9664 /*                      p_type = FPOINTER ; */
9665 /*                  else */
9666 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9667 /*                          p_type = PPOINTER; */
9668 /*                      else */
9669 /*                          if (SPEC_OCLS(etype) == idata ) */
9670 /*                              p_type = IPOINTER ; */
9671 /*                          else */
9672 /*                              p_type = POINTER ; */
9673             }
9674                 
9675             /* the first two bytes are known */
9676       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9677             size = GPTRSIZE - 1; 
9678             offset = 0 ;
9679             while (size--) {
9680               if(offset < AOP_SIZE(right)) {
9681       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9682                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9683                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9684                   pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9685                   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9686                 } else { 
9687                   pic16_aopPut(AOP(result),
9688                          pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9689                          offset);
9690                 }
9691               } else 
9692                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9693               offset++;
9694             }
9695             /* the last byte depending on type */
9696             switch (p_type) {
9697             case IPOINTER:
9698             case POINTER:
9699                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9700                 break;
9701             case FPOINTER:
9702               pic16_emitcode(";BUG!? ","%d",__LINE__);
9703                 l = one;
9704                 break;
9705             case CPOINTER:
9706               pic16_emitcode(";BUG!? ","%d",__LINE__);
9707                 l = "#0x02";
9708                 break;                          
9709             case PPOINTER:
9710               pic16_emitcode(";BUG!? ","%d",__LINE__);
9711                 l = "#0x03";
9712                 break;
9713                 
9714             default:
9715                 /* this should never happen */
9716                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9717                        "got unknown pointer type");
9718                 exit(1);
9719             }
9720             //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
9721             goto release ;
9722         }
9723         
9724         /* just copy the pointers */
9725         size = AOP_SIZE(result);
9726         offset = 0 ;
9727         while (size--) {
9728             pic16_aopPut(AOP(result),
9729                    pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9730                    offset);
9731             offset++;
9732         }
9733         goto release ;
9734     }
9735     
9736
9737
9738     /* so we now know that the size of destination is greater
9739     than the size of the source.
9740     Now, if the next iCode is an operator then we might be
9741     able to optimize the operation without performing a cast.
9742     */
9743     if(genMixedOperation(ic))
9744       goto release;
9745
9746     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9747     
9748     /* we move to result for the size of source */
9749     size = AOP_SIZE(right);
9750     offset = 0 ;
9751     while (size--) {
9752       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(right),offset));
9753       pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset));
9754       offset++;
9755     }
9756
9757     /* now depending on the sign of the destination */
9758     size = AOP_SIZE(result) - AOP_SIZE(right);
9759     /* if unsigned or not an integral type */
9760     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9761       while (size--)
9762         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
9763     } else {
9764       /* we need to extend the sign :{ */
9765
9766       if(size == 1) {
9767         /* Save one instruction of casting char to int */
9768         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
9769         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9770         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
9771       } else {
9772         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9773
9774         if(offset)
9775           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9776         else
9777           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9778         
9779         pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
9780
9781         while (size--)
9782           pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
9783       }
9784     }
9785
9786 release:
9787     pic16_freeAsmop(right,NULL,ic,TRUE);
9788     pic16_freeAsmop(result,NULL,ic,TRUE);
9789
9790 }
9791
9792 /*-----------------------------------------------------------------*/
9793 /* genDjnz - generate decrement & jump if not zero instrucion      */
9794 /*-----------------------------------------------------------------*/
9795 static int genDjnz (iCode *ic, iCode *ifx)
9796 {
9797     symbol *lbl, *lbl1;
9798     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9799
9800     if (!ifx)
9801         return 0;
9802     
9803     /* if the if condition has a false label
9804        then we cannot save */
9805     if (IC_FALSE(ifx))
9806         return 0;
9807
9808     /* if the minus is not of the form 
9809        a = a - 1 */
9810     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9811         !IS_OP_LITERAL(IC_RIGHT(ic)))
9812         return 0;
9813
9814     if (operandLitValue(IC_RIGHT(ic)) != 1)
9815         return 0;
9816
9817     /* if the size of this greater than one then no
9818        saving */
9819     if (getSize(operandType(IC_RESULT(ic))) > 1)
9820         return 0;
9821
9822     /* otherwise we can save BIG */
9823     lbl = newiTempLabel(NULL);
9824     lbl1= newiTempLabel(NULL);
9825
9826     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9827     
9828     if (IS_AOP_PREG(IC_RESULT(ic))) {
9829         pic16_emitcode("dec","%s",
9830                  pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9831         pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9832         pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9833     } else {    
9834
9835
9836       pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9837       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9838
9839       pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9840       pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9841
9842     }
9843 /*     pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9844 /*     pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9845 /*     pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9846 /*     pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9847
9848     
9849     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9850     ifx->generated = 1;
9851     return 1;
9852 }
9853
9854 /*-----------------------------------------------------------------*/
9855 /* genReceive - generate code for a receive iCode                  */
9856 /*-----------------------------------------------------------------*/
9857 static void genReceive (iCode *ic)
9858 {    
9859   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9860
9861   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9862       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9863         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9864
9865     int size = getSize(operandType(IC_RESULT(ic)));
9866     int offset =  pic16_fReturnSizePic - size;
9867     while (size--) {
9868       pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9869                                     fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9870       offset++;
9871     }
9872     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9873     size = AOP_SIZE(IC_RESULT(ic));
9874     offset = 0;
9875     while (size--) {
9876       pic16_emitcode ("pop","acc");
9877       pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9878     }
9879         
9880   } else {
9881     _G.accInUse++;
9882     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
9883     _G.accInUse--;
9884     assignResultValue(IC_RESULT(ic));   
9885   }
9886
9887   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9888 }
9889
9890 /*-----------------------------------------------------------------*/
9891 /* genpic16Code - generate code for pic16 based controllers        */
9892 /*-----------------------------------------------------------------*/
9893 /*
9894  * At this point, ralloc.c has gone through the iCode and attempted
9895  * to optimize in a way suitable for a PIC. Now we've got to generate
9896  * PIC instructions that correspond to the iCode.
9897  *
9898  * Once the instructions are generated, we'll pass through both the
9899  * peep hole optimizer and the pCode optimizer.
9900  *-----------------------------------------------------------------*/
9901
9902 void genpic16Code (iCode *lic)
9903 {
9904     iCode *ic;
9905     int cln = 0;
9906
9907     lineHead = lineCurr = NULL;
9908
9909     pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9910     pic16_addpBlock(pb);
9911
9912     /* if debug information required */
9913     if (options.debug && currFunc) { 
9914       if (currFunc) {
9915         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9916         _G.debugLine = 1;
9917         if (IS_STATIC(currFunc->etype)) {
9918           pic16_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9919           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9920         } else {
9921           pic16_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9922           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9923         }
9924         _G.debugLine = 0;
9925       }
9926     }
9927
9928
9929     for (ic = lic ; ic ; ic = ic->next ) {
9930
9931       DEBUGpic16_emitcode(";ic","");
9932         if ( cln != ic->lineno ) {
9933             if ( options.debug ) {
9934                 _G.debugLine = 1;
9935                 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9936                          FileBaseName(ic->filename),ic->lineno,
9937                          ic->level,ic->block);
9938                 _G.debugLine = 0;
9939             }
9940             /*
9941               pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9942               pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9943               printCLine(ic->filename, ic->lineno));
9944             */
9945             pic16_addpCode2pBlock(pb,
9946                             pic16_newpCodeCSource(ic->lineno, 
9947                                             ic->filename, 
9948                                             printCLine(ic->filename, ic->lineno)));
9949
9950             cln = ic->lineno ;
9951         }
9952         /* if the result is marked as
9953            spilt and rematerializable or code for
9954            this has already been generated then
9955            do nothing */
9956         if (resultRemat(ic) || ic->generated ) 
9957             continue ;
9958         
9959         /* depending on the operation */
9960         switch (ic->op) {
9961         case '!' :
9962             genNot(ic);
9963             break;
9964             
9965         case '~' :
9966             genCpl(ic);
9967             break;
9968             
9969         case UNARYMINUS:
9970             genUminus (ic);
9971             break;
9972             
9973         case IPUSH:
9974             genIpush (ic);
9975             break;
9976             
9977         case IPOP:
9978             /* IPOP happens only when trying to restore a 
9979                spilt live range, if there is an ifx statement
9980                following this pop then the if statement might
9981                be using some of the registers being popped which
9982                would destroy the contents of the register so
9983                we need to check for this condition and handle it */
9984             if (ic->next            && 
9985                 ic->next->op == IFX &&
9986                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9987                 genIfx (ic->next,ic);
9988             else
9989                 genIpop (ic);
9990             break; 
9991             
9992         case CALL:
9993             genCall (ic);
9994             break;
9995             
9996         case PCALL:
9997             genPcall (ic);
9998             break;
9999             
10000         case FUNCTION:
10001             genFunction (ic);
10002             break;
10003             
10004         case ENDFUNCTION:
10005             genEndFunction (ic);
10006             break;
10007             
10008         case RETURN:
10009             genRet (ic);
10010             break;
10011             
10012         case LABEL:
10013             genLabel (ic);
10014             break;
10015             
10016         case GOTO:
10017             genGoto (ic);
10018             break;
10019             
10020         case '+' :
10021             pic16_genPlus (ic) ;
10022             break;
10023             
10024         case '-' :
10025             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10026                 pic16_genMinus (ic);
10027             break;
10028             
10029         case '*' :
10030             genMult (ic);
10031             break;
10032             
10033         case '/' :
10034             genDiv (ic) ;
10035             break;
10036             
10037         case '%' :
10038             genMod (ic);
10039             break;
10040             
10041         case '>' :
10042             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10043             break;
10044             
10045         case '<' :
10046             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10047             break;
10048             
10049         case LE_OP:
10050         case GE_OP:
10051         case NE_OP:
10052             
10053             /* note these two are xlated by algebraic equivalence
10054                during parsing SDCC.y */
10055             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10056                    "got '>=' or '<=' shouldn't have come here");
10057             break;      
10058             
10059         case EQ_OP:
10060             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10061             break;          
10062             
10063         case AND_OP:
10064             genAndOp (ic);
10065             break;
10066             
10067         case OR_OP:
10068             genOrOp (ic);
10069             break;
10070             
10071         case '^' :
10072             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10073             break;
10074             
10075         case '|' :
10076                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10077             break;
10078             
10079         case BITWISEAND:
10080             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10081             break;
10082             
10083         case INLINEASM:
10084             genInline (ic);
10085             break;
10086             
10087         case RRC:
10088             genRRC (ic);
10089             break;
10090             
10091         case RLC:
10092             genRLC (ic);
10093             break;
10094             
10095         case GETHBIT:
10096             genGetHbit (ic);
10097             break;
10098             
10099         case LEFT_OP:
10100             genLeftShift (ic);
10101             break;
10102             
10103         case RIGHT_OP:
10104             genRightShift (ic);
10105             break;
10106             
10107         case GET_VALUE_AT_ADDRESS:
10108             genPointerGet(ic);
10109             break;
10110             
10111         case '=' :
10112             if (POINTER_SET(ic))
10113                 genPointerSet(ic);
10114             else
10115                 genAssign(ic);
10116             break;
10117             
10118         case IFX:
10119             genIfx (ic,NULL);
10120             break;
10121             
10122         case ADDRESS_OF:
10123             genAddrOf (ic);
10124             break;
10125             
10126         case JUMPTABLE:
10127             genJumpTab (ic);
10128             break;
10129             
10130         case CAST:
10131             genCast (ic);
10132             break;
10133             
10134         case RECEIVE:
10135             genReceive(ic);
10136             break;
10137             
10138         case SEND:
10139             addSet(&_G.sendSet,ic);
10140             break;
10141
10142         default :
10143             ic = ic;
10144         }
10145     }
10146     
10147
10148     /* now we are ready to call the 
10149        peep hole optimizer */
10150     if (!options.nopeep) {
10151       peepHole (&lineHead);
10152     }
10153     /* now do the actual printing */
10154     printLine (lineHead,codeOutFile);
10155
10156 #ifdef PCODE_DEBUG
10157     DFPRINTF((stderr,"printing pBlock\n\n"));
10158     pic16_printpBlock(stdout,pb);
10159 #endif
10160
10161     return;
10162 }