* doc/sdccman.lyx: removed PIC16 from PIC16 Port Specific Options,
[fw/sdcc] / src / pic16 / gen.c
1 /*-------------------------------------------------------------------------
2  gen.c - source file for code generation for pic16
3
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
9   
10   This program is free software; you can redistribute it and/or modify it
11   under the terms of the GNU General Public License as published by the
12   Free Software Foundation; either version 2, or (at your option) any
13   later version.
14   
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License for more details.
19   
20   You should have received a copy of the GNU General Public License
21   along with this program; if not, write to the Free Software
22   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23   
24   In other words, you are welcome to use, share and improve this program.
25   You are forbidden to forbid anyone else to use, share and improve
26   what you give them.   Help stamp out software-hoarding!
27   
28   Notes:
29   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
30                 Made everything static
31 -------------------------------------------------------------------------*/
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include "SDCCglobl.h"
38 #include "newalloc.h"
39
40 #include "common.h"
41 #include "SDCCpeeph.h"
42 #include "ralloc.h"
43 #include "pcode.h"
44 #include "gen.h"
45 #include "genutils.h"
46 #include "device.h"
47 #include "main.h"
48
49 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
50 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
51 void pic16_genMult8X8_8 (operand *, operand *,operand *);
52 pCode *pic16_AssembleLine(char *line, int peeps);
53 extern void pic16_printpBlock(FILE *of, pBlock *pb);
54 static asmop *newAsmop (short type);
55 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
56 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
57 static void mov2w (asmop *aop, int offset);
58 static int aopIdx (asmop *aop, int offset);
59
60 static int labelOffset=0;
61 extern int pic16_debug_verbose;
62 static int optimized_for_speed = 0;
63 /*
64   hack hack
65
66 */
67
68 /* max_key keeps track of the largest label number used in 
69    a function. This is then used to adjust the label offset
70    for the next function.
71 */
72 static int max_key=0;
73 static int GpsuedoStkPtr=0;
74
75 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
76 unsigned int pic16aopLiteral (value *val, int offset);
77 const char *pic16_AopType(short type);
78 static iCode *ifxForOp ( operand *op, iCode *ic );
79
80 void pic16_pushpCodeOp(pCodeOp *pcop);
81 void pic16_poppCodeOp(pCodeOp *pcop);
82
83
84
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
86
87 /* this is the down and dirty file with all kinds of 
88    kludgy & hacky stuff. This is what it is all about
89    CODE GENERATION for a specific MCU . some of the
90    routines may be reusable, will have to see */
91
92 static char *zero = "#0x00";
93 static char *one  = "#0x01";
94 static char *spname = "sp";
95
96
97 /*
98  * Function return value policy (MSB-->LSB):
99  *  8 bits      -> WREG
100  * 16 bits      -> PRODL:WREG
101  * 24 bits      -> PRODH:PRODL:WREG
102  * 32 bits      -> FSR0L:PRODH:PRODL:WREG
103  * >32 bits     -> on stack, and FSR0 points to the beginning
104  *
105  */
106  
107
108 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
109 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
110 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
111 static char **fReturn = fReturnpic16;
112
113 static char *accUse[] = {"WREG"};
114
115 //static short rbank = -1;
116
117 static struct {
118     short r0Pushed;
119     short r1Pushed;
120     short accInUse;
121     short inLine;
122     short debugLine;
123     short nRegsSaved;
124     set *sendSet;
125 } _G;
126
127 /* Resolved ifx structure. This structure stores information
128    about an iCode ifx that makes it easier to generate code.
129 */
130 typedef struct resolvedIfx {
131   symbol *lbl;     /* pointer to a label */
132   int condition;   /* true or false ifx */
133   int generated;   /* set true when the code associated with the ifx
134                     * is generated */
135 } resolvedIfx;
136
137 extern int pic16_ptrRegReq ;
138 extern int pic16_nRegs;
139 extern FILE *codeOutFile;
140 static void saverbank (int, iCode *,bool);
141
142 static lineNode *lineHead = NULL;
143 static lineNode *lineCurr = NULL;
144
145 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
146 0xE0, 0xC0, 0x80, 0x00};
147 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
148 0x07, 0x03, 0x01, 0x00};
149
150 static  pBlock *pb;
151
152 /*-----------------------------------------------------------------*/
153 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
154 /*                 exponent of 2 is returned, otherwise -1 is      */
155 /*                 returned.                                       */
156 /* note that this is similar to the function `powof2' in SDCCsymt  */
157 /* if(n == 2^y)                                                    */
158 /*   return y;                                                     */
159 /* return -1;                                                      */
160 /*-----------------------------------------------------------------*/
161 static int my_powof2 (unsigned long num)
162 {
163   if(num) {
164     if( (num & (num-1)) == 0) {
165       int nshifts = -1;
166       while(num) {
167         num>>=1;
168         nshifts++;
169       }
170       return nshifts;
171     }
172   }
173
174   return -1;
175 }
176
177 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
178 {
179
180   DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
181                        line_no,
182                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
183                        ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
184                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
185                        ((left)   ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
186                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
187                        ((right)  ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
188                        ((result) ? AOP_SIZE(result) : 0));
189
190 }
191
192 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
193 {
194
195   DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
196                        line_no,
197                        ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
198                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
199                        ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
200                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
201                        ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
202                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
203
204 }
205
206 void pic16_emitpcomment (char *fmt, ...)
207 {
208     va_list ap;
209     char lb[INITIAL_INLINEASM];  
210     char *lbp = lb;
211
212     va_start(ap,fmt);   
213
214     lb[0] = ';';
215     vsprintf(lb+1,fmt,ap);
216
217     while (isspace(*lbp)) lbp++;
218
219     if (lbp && *lbp) 
220         lineCurr = (lineCurr ?
221                     connectLine(lineCurr,newLineNode(lb)) :
222                     (lineHead = newLineNode(lb)));
223     lineCurr->isInline = _G.inLine;
224     lineCurr->isDebug  = _G.debugLine;
225
226     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
227     va_end(ap);
228
229 //      fprintf(stderr, "%s\n", lb);
230 }
231
232 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
233 {
234     va_list ap;
235     char lb[INITIAL_INLINEASM];  
236     char *lbp = lb;
237
238     if(!pic16_debug_verbose)
239       return;
240
241     va_start(ap,fmt);   
242
243     if (inst && *inst) {
244         if (fmt && *fmt)
245             sprintf(lb,"%s\t",inst);
246         else
247             sprintf(lb,"%s",inst);
248         vsprintf(lb+(strlen(lb)),fmt,ap);
249     }  else
250         vsprintf(lb,fmt,ap);
251
252     while (isspace(*lbp)) lbp++;
253
254     if (lbp && *lbp) 
255         lineCurr = (lineCurr ?
256                     connectLine(lineCurr,newLineNode(lb)) :
257                     (lineHead = newLineNode(lb)));
258     lineCurr->isInline = _G.inLine;
259     lineCurr->isDebug  = _G.debugLine;
260
261     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
262     va_end(ap);
263
264 //      fprintf(stderr, "%s\n", lb);
265 }
266
267 void pic16_emitpLabel(int key)
268 {
269   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
270 }
271
272 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
273 {
274
275   if(pcop)
276     pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
277   else
278     DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
279     
280 //    fprintf(stderr, "%s\n", pcop->name);
281 }
282
283 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
284 {
285
286   pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
287
288 }
289
290
291 #if 1
292 #define pic16_emitcode  DEBUGpic16_emitcode
293 #else
294 /*-----------------------------------------------------------------*/
295 /* pic16_emitcode - writes the code into a file : for now it is simple    */
296 /*-----------------------------------------------------------------*/
297 void pic16_emitcode (char *inst,char *fmt, ...)
298 {
299     va_list ap;
300     char lb[INITIAL_INLINEASM];  
301     char *lbp = lb;
302
303     va_start(ap,fmt);   
304
305     if (inst && *inst) {
306         if (fmt && *fmt)
307             sprintf(lb,"%s\t",inst);
308         else
309             sprintf(lb,"%s",inst);
310         vsprintf(lb+(strlen(lb)),fmt,ap);
311     }  else
312         vsprintf(lb,fmt,ap);
313
314     while (isspace(*lbp)) lbp++;
315
316     if (lbp && *lbp) 
317         lineCurr = (lineCurr ?
318                     connectLine(lineCurr,newLineNode(lb)) :
319                     (lineHead = newLineNode(lb)));
320     lineCurr->isInline = _G.inLine;
321     lineCurr->isDebug  = _G.debugLine;
322
323 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
324
325 //    if(pic16_debug_verbose)
326 //      pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
327
328     va_end(ap);
329 }
330 #endif
331
332
333 /*-----------------------------------------------------------------*/
334 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
335 /*-----------------------------------------------------------------*/
336 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
337 {
338     bool r0iu = FALSE , r1iu = FALSE;
339     bool r0ou = FALSE , r1ou = FALSE;
340
341         //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
342
343     /* the logic: if r0 & r1 used in the instruction
344     then we are in trouble otherwise */
345
346     /* first check if r0 & r1 are used by this
347     instruction, in which case we are in trouble */
348     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
349         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
350     {
351         goto endOfWorld;      
352     }
353
354     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
355     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
356
357     /* if no usage of r0 then return it */
358     if (!r0iu && !r0ou) {
359         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
360         (*aopp)->type = AOP_R0;
361         
362         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
363     }
364
365     /* if no usage of r1 then return it */
366     if (!r1iu && !r1ou) {
367         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
368         (*aopp)->type = AOP_R1;
369
370         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
371     }    
372
373     /* now we know they both have usage */
374     /* if r0 not used in this instruction */
375     if (!r0iu) {
376         /* push it if not already pushed */
377         if (!_G.r0Pushed) {
378           //pic16_emitcode ("push","%s",
379           //          pic16_regWithIdx(R0_IDX)->dname);
380             _G.r0Pushed++ ;
381         }
382         
383         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
384         (*aopp)->type = AOP_R0;
385
386         return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
387     }
388
389     /* if r1 not used then */
390
391     if (!r1iu) {
392         /* push it if not already pushed */
393         if (!_G.r1Pushed) {
394           //pic16_emitcode ("push","%s",
395           //          pic16_regWithIdx(R1_IDX)->dname);
396             _G.r1Pushed++ ;
397         }
398         
399         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
400         (*aopp)->type = AOP_R1;
401         return pic16_regWithIdx(R1_IDX);
402     }
403
404 endOfWorld :
405     /* I said end of world but not quite end of world yet */
406     /* if this is a result then we can push it on the stack*/
407     if (result) {
408         (*aopp)->type = AOP_STK;    
409         return NULL;
410     }
411
412     /* other wise this is true end of the world */
413     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
414            "getFreePtr should never reach here");
415     exit(0);
416 }
417
418 /*-----------------------------------------------------------------*/
419 /* newAsmop - creates a new asmOp                                  */
420 /*-----------------------------------------------------------------*/
421 static asmop *newAsmop (short type)
422 {
423     asmop *aop;
424
425     aop = Safe_calloc(1,sizeof(asmop));
426     aop->type = type;
427     return aop;
428 }
429
430 static void genSetDPTR(int n)
431 {
432     if (!n)
433     {
434         pic16_emitcode(";", "Select standard DPTR");
435         pic16_emitcode("mov", "dps, #0x00");
436     }
437     else
438     {
439         pic16_emitcode(";", "Select alternate DPTR");
440         pic16_emitcode("mov", "dps, #0x01");
441     }
442 }
443
444 /*-----------------------------------------------------------------*/
445 /* resolveIfx - converts an iCode ifx into a form more useful for  */
446 /*              generating code                                    */
447 /*-----------------------------------------------------------------*/
448 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
449 {
450   if(!resIfx) 
451     return;
452
453   //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
454
455   resIfx->condition = 1;    /* assume that the ifx is true */
456   resIfx->generated = 0;    /* indicate that the ifx has not been used */
457
458   if(!ifx) {
459     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
460 /*
461     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
462                         __FUNCTION__,__LINE__,resIfx->lbl->key);
463 */
464   } else {
465     if(IC_TRUE(ifx)) {
466       resIfx->lbl = IC_TRUE(ifx);
467     } else {
468       resIfx->lbl = IC_FALSE(ifx);
469       resIfx->condition = 0;
470     }
471 /*
472     if(IC_TRUE(ifx)) 
473       DEBUGpic16_emitcode("; ***","ifx true is non-null");
474     if(IC_FALSE(ifx)) 
475       DEBUGpic16_emitcode("; ***","ifx false is non-null");
476 */
477   }
478
479   //  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
480
481 }
482 #if 0
483 /*-----------------------------------------------------------------*/
484 /* pointerCode - returns the code for a pointer type               */
485 /*-----------------------------------------------------------------*/
486 static int pointerCode (sym_link *etype)
487 {
488
489     return PTR_TYPE(SPEC_OCLS(etype));
490
491 }
492 #endif
493 /*-----------------------------------------------------------------*/
494 /* aopForSym - for a true symbol                                   */
495 /*-----------------------------------------------------------------*/
496 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
497 {
498     asmop *aop;
499     memmap *space= SPEC_OCLS(sym->etype);
500
501     DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
502     /* if already has one */
503     if (sym->aop) {
504             DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
505         return sym->aop;
506     }
507
508     /* assign depending on the storage class */
509     /* if it is on the stack or indirectly addressable */
510     /* space we need to assign either r0 or r1 to it   */    
511     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
512
513         DEBUGpic16_emitcode("; ***", "sum->onStack || sym->iaccess");
514         
515         sym->aop = aop = newAsmop(0);
516         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
517         aop->size = getSize(sym->type);
518
519         /* now assign the address of the variable to 
520         the pointer register */
521         if (aop->type != AOP_STK) {
522
523             if (sym->onStack) {
524                     if ( _G.accInUse )
525                         pic16_emitcode("push","acc");
526
527                     pic16_emitcode("mov","a,_bp");
528                     pic16_emitcode("add","a,#0x%02x",
529                              ((sym->stack < 0) ?
530                               ((char)(sym->stack - _G.nRegsSaved )) :
531                               ((char)sym->stack)) & 0xff);
532                     pic16_emitcode("mov","%s,a",
533                              aop->aopu.aop_ptr->name);
534
535                     if ( _G.accInUse )
536                         pic16_emitcode("pop","acc");
537             } else
538                 pic16_emitcode("mov","%s,#%s",
539                          aop->aopu.aop_ptr->name,
540                          sym->rname);
541             aop->paged = space->paged;
542         } else
543             aop->aopu.aop_stk = sym->stack;
544         return aop;
545     }
546     
547     if (sym->onStack && options.stack10bit)
548     {
549         /* It's on the 10 bit stack, which is located in
550          * far data space.
551          */
552          
553       //DEBUGpic16_emitcode(";","%d",__LINE__);
554
555         if ( _G.accInUse )
556                 pic16_emitcode("push","acc");
557
558         pic16_emitcode("mov","a,_bp");
559         pic16_emitcode("add","a,#0x%02x",
560                  ((sym->stack < 0) ?
561                    ((char)(sym->stack - _G.nRegsSaved )) :
562                    ((char)sym->stack)) & 0xff);
563         
564         genSetDPTR(1);
565         pic16_emitcode ("mov","dpx1,#0x40");
566         pic16_emitcode ("mov","dph1,#0x00");
567         pic16_emitcode ("mov","dpl1, a");
568         genSetDPTR(0);
569         
570         if ( _G.accInUse )
571             pic16_emitcode("pop","acc");
572             
573         sym->aop = aop = newAsmop(AOP_DPTR2);
574         aop->size = getSize(sym->type); 
575         return aop;
576     }
577
578     //DEBUGpic16_emitcode(";","%d",__LINE__);
579     /* if in bit space */
580     if (IN_BITSPACE(space)) {
581         sym->aop = aop = newAsmop (AOP_CRY);
582         aop->aopu.aop_dir = sym->rname ;
583         aop->size = getSize(sym->type);
584         DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
585         return aop;
586     }
587     /* if it is in direct space */
588     if (IN_DIRSPACE(space)) {
589         sym->aop = aop = newAsmop (AOP_DIR);
590         aop->aopu.aop_dir = sym->rname ;
591         aop->size = getSize(sym->type);
592         DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
593         pic16_allocDirReg( IC_LEFT(ic) );
594         return aop;
595     }
596
597     /* special case for a function */
598     if (IS_FUNC(sym->type)) {   
599         sym->aop = aop = newAsmop(AOP_IMMD);    
600         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
601         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
602         strcpy(aop->aopu.aop_immd,sym->rname);
603         aop->size = FPTRSIZE; 
604         DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
605         return aop;
606     }
607
608
609     /* only remaining is far space */
610     /* in which case DPTR gets the address */
611     sym->aop = aop = newAsmop(AOP_PCODE);
612
613 /* change the next if to 1 to revert to good old immediate code */
614         if(IN_CODESPACE(space)) {
615                 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
616                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
617                 PCOI(aop->aopu.pcop)->index = 0;
618         } else {
619                 /* try to allocate via direct register */
620                 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), 0);
621 //              aop->size = getSize( sym->type );
622         }
623
624         DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
625                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
626
627         pic16_allocDirReg (IC_LEFT(ic));
628
629         if(IN_DIRSPACE( space ))
630                 aop->size = PTRSIZE;
631         else if(IN_CODESPACE( space ))
632                 aop->size = FPTRSIZE;
633         else aop->size = AOP_SIZE( IC_LEFT(ic) );
634
635     DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
636
637     /* if it is in code space */
638     if (IN_CODESPACE(space))
639         aop->code = 1;
640
641     return aop;     
642 }
643
644 /*-----------------------------------------------------------------*/
645 /* aopForRemat - rematerialzes an object                           */
646 /*-----------------------------------------------------------------*/
647 static asmop *aopForRemat (operand *op) // x symbol *sym)
648 {
649   symbol *sym = OP_SYMBOL(op);
650   iCode *ic = NULL, *oldic;
651   asmop *aop = newAsmop(AOP_PCODE);
652   int val = 0;
653   int offset = 0;
654   int viaimmd=0;
655
656
657         ic = sym->rematiCode;
658
659         DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
660         
661         if(IS_OP_POINTER(op)) {
662                 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
663         }
664
665         for (;;) {
666                 oldic = ic;
667
668 //              pic16_emitpcomment("ic: %s\n", printILine(ic));
669         
670                 if (ic->op == '+') {
671                         val += (int) operandLitValue(IC_RIGHT(ic));
672                 } else if (ic->op == '-') {
673                         val -= (int) operandLitValue(IC_RIGHT(ic));
674                 } else
675                         break;
676                 
677                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
678         }
679
680         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
681
682         if(!op->isaddr)viaimmd++; else viaimmd=0;
683                 
684 /* set the following if to 1 to revert to good old immediate code */
685         if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
686                 || viaimmd) {
687
688                 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
689
690                 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
691
692 #if 0
693                 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
694 #else
695                 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
696 #endif
697
698                 PCOI(aop->aopu.pcop)->index = val;
699         } else {
700                 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
701
702                 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
703 //              aop->size = AOP_SIZE( IC_LEFT(ic) );
704         }
705
706
707         DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
708                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
709 #if 0
710                 val, IS_PTR_CONST(operandType(op)));
711 #else
712                 val, IS_CODEPTR(operandType(op)));
713 #endif
714
715 //      DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
716
717         pic16_allocDirReg (IC_LEFT(ic));
718
719         if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
720                 aop->code = 1;
721
722   return aop;        
723 }
724
725 static int aopIdx (asmop *aop, int offset)
726 {
727   if(!aop)
728     return -1;
729
730   if(aop->type !=  AOP_REG)
731     return -2;
732         
733   return aop->aopu.aop_reg[offset]->rIdx;
734
735 }
736 /*-----------------------------------------------------------------*/
737 /* regsInCommon - two operands have some registers in common       */
738 /*-----------------------------------------------------------------*/
739 static bool regsInCommon (operand *op1, operand *op2)
740 {
741     symbol *sym1, *sym2;
742     int i;
743
744     /* if they have registers in common */
745     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
746         return FALSE ;
747
748     sym1 = OP_SYMBOL(op1);
749     sym2 = OP_SYMBOL(op2);
750
751     if (sym1->nRegs == 0 || sym2->nRegs == 0)
752         return FALSE ;
753
754     for (i = 0 ; i < sym1->nRegs ; i++) {
755         int j;
756         if (!sym1->regs[i])
757             continue ;
758
759         for (j = 0 ; j < sym2->nRegs ;j++ ) {
760             if (!sym2->regs[j])
761                 continue ;
762
763             if (sym2->regs[j] == sym1->regs[i])
764                 return TRUE ;
765         }
766     }
767
768     return FALSE ;
769 }
770
771 /*-----------------------------------------------------------------*/
772 /* operandsEqu - equivalent                                        */
773 /*-----------------------------------------------------------------*/
774 static bool operandsEqu ( operand *op1, operand *op2)
775 {
776     symbol *sym1, *sym2;
777
778     /* if they not symbols */
779     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
780         return FALSE;
781
782     sym1 = OP_SYMBOL(op1);
783     sym2 = OP_SYMBOL(op2);
784
785     /* if both are itemps & one is spilt
786        and the other is not then false */
787     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
788         sym1->isspilt != sym2->isspilt )
789         return FALSE ;
790
791     /* if they are the same */
792     if (sym1 == sym2)
793         return TRUE ;
794
795     if (strcmp(sym1->rname,sym2->rname) == 0)
796         return TRUE;
797
798
799     /* if left is a tmp & right is not */
800     if (IS_ITEMP(op1)  && 
801         !IS_ITEMP(op2) &&
802         sym1->isspilt  &&
803         (sym1->usl.spillLoc == sym2))
804         return TRUE;
805
806     if (IS_ITEMP(op2)  && 
807         !IS_ITEMP(op1) &&
808         sym2->isspilt  &&
809         sym1->level > 0 &&
810         (sym2->usl.spillLoc == sym1))
811         return TRUE ;
812
813     return FALSE ;
814 }
815
816 /*-----------------------------------------------------------------*/
817 /* pic16_sameRegs - two asmops have the same registers                   */
818 /*-----------------------------------------------------------------*/
819 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
820 {
821     int i;
822
823     if (aop1 == aop2)
824         return TRUE ;
825
826     if (aop1->type != AOP_REG ||
827         aop2->type != AOP_REG )
828         return FALSE ;
829
830     if (aop1->size != aop2->size )
831         return FALSE ;
832
833     for (i = 0 ; i < aop1->size ; i++ )
834         if (aop1->aopu.aop_reg[i] !=
835             aop2->aopu.aop_reg[i] )
836             return FALSE ;
837
838     return TRUE ;
839 }
840
841 /*-----------------------------------------------------------------*/
842 /* pic16_aopOp - allocates an asmop for an operand  :                    */
843 /*-----------------------------------------------------------------*/
844 void pic16_aopOp (operand *op, iCode *ic, bool result)
845 {
846     asmop *aop;
847     symbol *sym;
848     int i;
849
850     if (!op)
851         return ;
852
853 //      DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
854
855     /* if this a literal */
856     if (IS_OP_LITERAL(op)) {
857         op->aop = aop = newAsmop(AOP_LIT);
858         aop->aopu.aop_lit = op->operand.valOperand;
859         aop->size = getSize(operandType(op));
860         return;
861     }
862
863     {
864       sym_link *type = operandType(op);
865 #if 0
866       if(IS_PTR_CONST(type))
867 #else
868       if(IS_CODEPTR(type))
869 #endif
870         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
871     }
872
873     /* if already has a asmop then continue */
874     if (op->aop)
875         return ;
876
877     /* if the underlying symbol has a aop */
878     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
879       DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
880         op->aop = OP_SYMBOL(op)->aop;
881         return;
882     }
883
884     /* if this is a true symbol */
885     if (IS_TRUE_SYMOP(op)) {    
886         DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
887       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
888       return ;
889     }
890
891     /* this is a temporary : this has
892     only four choices :
893     a) register
894     b) spillocation
895     c) rematerialize 
896     d) conditional   
897     e) can be a return use only */
898
899     sym = OP_SYMBOL(op);
900
901         DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
902     /* if the type is a conditional */
903     if (sym->regType == REG_CND) {
904         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
905         aop->size = 0;
906         return;
907     }
908
909     /* if it is spilt then two situations
910     a) is rematerialize 
911     b) has a spill location */
912     if (sym->isspilt || sym->nRegs == 0) {
913
914       DEBUGpic16_emitcode(";","%d",__LINE__);
915         /* rematerialize it NOW */
916         if (sym->remat) {
917
918             sym->aop = op->aop = aop =
919                                       aopForRemat (op);
920             aop->size = getSize(sym->type);
921             //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
922             return;
923         }
924
925 #if 1
926         if (sym->accuse) {
927             int i;
928             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
929             aop->size = getSize(sym->type);
930             for ( i = 0 ; i < 1 ; i++ ) {
931                 aop->aopu.aop_str[i] = accUse[i];
932 //                aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
933             }
934             fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
935             DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
936             return;  
937         }
938 #endif
939
940 #if 1
941         if (sym->ruonly ) {
942           /*
943           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
944           aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
945           //pic16_allocDirReg (IC_LEFT(ic));
946           aop->size = getSize(sym->type);
947           */
948
949           unsigned i;
950
951           aop = op->aop = sym->aop = newAsmop(AOP_STR);
952           aop->size = getSize(sym->type);
953           for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
954             aop->aopu.aop_str[i] = fReturn[i];
955
956           DEBUGpic16_emitcode(";","%d",__LINE__);
957           return;
958         }
959 #endif
960         /* else spill location  */
961         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
962             /* force a new aop if sizes differ */
963             sym->usl.spillLoc->aop = NULL;
964         }
965         DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
966                             __FUNCTION__,__LINE__,
967                             sym->usl.spillLoc->rname,
968                             sym->rname, sym->usl.spillLoc->offset);
969
970         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
971         //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
972         aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, 
973                                           getSize(sym->type), 
974                                           sym->usl.spillLoc->offset);
975         aop->size = getSize(sym->type);
976
977         return;
978     }
979
980     {
981       sym_link *type = operandType(op);
982 #if 0
983       if(IS_PTR_CONST(type)) 
984 #else
985       if(IS_CODEPTR(type)) 
986 #endif
987         DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
988     }
989
990     /* must be in a register */
991     DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
992     sym->aop = op->aop = aop = newAsmop(AOP_REG);
993     aop->size = sym->nRegs;
994     for ( i = 0 ; i < sym->nRegs ;i++)
995         aop->aopu.aop_reg[i] = sym->regs[i];
996 }
997
998 /*-----------------------------------------------------------------*/
999 /* pic16_freeAsmop - free up the asmop given to an operand               */
1000 /*----------------------------------------------------------------*/
1001 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1002 {   
1003     asmop *aop ;
1004
1005     if (!op)
1006         aop = aaop;
1007     else 
1008         aop = op->aop;
1009
1010     if (!aop)
1011         return ;
1012
1013     if (aop->freed)
1014         goto dealloc; 
1015
1016     aop->freed = 1;
1017
1018     /* depending on the asmop type only three cases need work AOP_RO
1019        , AOP_R1 && AOP_STK */
1020 #if 0
1021     switch (aop->type) {
1022         case AOP_R0 :
1023             if (_G.r0Pushed ) {
1024                 if (pop) {
1025                     pic16_emitcode ("pop","ar0");     
1026                     _G.r0Pushed--;
1027                 }
1028             }
1029             bitVectUnSetBit(ic->rUsed,R0_IDX);
1030             break;
1031
1032         case AOP_R1 :
1033             if (_G.r1Pushed ) {
1034                 if (pop) {
1035                     pic16_emitcode ("pop","ar1");
1036                     _G.r1Pushed--;
1037                 }
1038             }
1039             bitVectUnSetBit(ic->rUsed,R1_IDX);          
1040             break;
1041
1042         case AOP_STK :
1043         {
1044             int sz = aop->size;    
1045             int stk = aop->aopu.aop_stk + aop->size;
1046             bitVectUnSetBit(ic->rUsed,R0_IDX);
1047             bitVectUnSetBit(ic->rUsed,R1_IDX);          
1048
1049             getFreePtr(ic,&aop,FALSE);
1050             
1051             if (options.stack10bit)
1052             {
1053                 /* I'm not sure what to do here yet... */
1054                 /* #STUB */
1055                 fprintf(stderr, 
1056                         "*** Warning: probably generating bad code for "
1057                         "10 bit stack mode.\n");
1058             }
1059             
1060             if (stk) {
1061                 pic16_emitcode ("mov","a,_bp");
1062                 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1063                 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1064             } else {
1065                 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1066             }
1067
1068             while (sz--) {
1069                 pic16_emitcode("pop","acc");
1070                 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1071                 if (!sz) break;
1072                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1073             }
1074             op->aop = aop;
1075             pic16_freeAsmop(op,NULL,ic,TRUE);
1076             if (_G.r0Pushed) {
1077                 pic16_emitcode("pop","ar0");
1078                 _G.r0Pushed--;
1079             }
1080
1081             if (_G.r1Pushed) {
1082                 pic16_emitcode("pop","ar1");
1083                 _G.r1Pushed--;
1084             }       
1085         }
1086     }
1087 #endif
1088
1089 dealloc:
1090     /* all other cases just dealloc */
1091     if (op ) {
1092         op->aop = NULL;
1093         if (IS_SYMOP(op)) {
1094             OP_SYMBOL(op)->aop = NULL;    
1095             /* if the symbol has a spill */
1096             if (SPIL_LOC(op))
1097                 SPIL_LOC(op)->aop = NULL;
1098         }
1099     }
1100 }
1101
1102 /*-----------------------------------------------------------------*/
1103 /* pic16_aopGet - for fetching value of the aop                          */
1104 /*-----------------------------------------------------------------*/
1105 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1106 {
1107     char *s = buffer ;
1108     char *rs;
1109
1110     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1111     /* offset is greater than
1112     size then zero */
1113     if (offset > (aop->size - 1) &&
1114         aop->type != AOP_LIT)
1115         return zero;
1116
1117     /* depending on type */
1118     switch (aop->type) {
1119         
1120     case AOP_R0:
1121     case AOP_R1:
1122         DEBUGpic16_emitcode(";","%d",__LINE__);
1123         /* if we need to increment it */       
1124         while (offset > aop->coff) {        
1125             pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1126             aop->coff++;
1127         }
1128         
1129         while (offset < aop->coff) {
1130             pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1131             aop->coff--;
1132         }
1133         
1134         aop->coff = offset ;
1135         if (aop->paged) {
1136             pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1137             return (dname ? "acc" : "a");
1138         }       
1139         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1140         rs = Safe_calloc(1,strlen(s)+1);
1141         strcpy(rs,s);   
1142         return rs;
1143         
1144     case AOP_DPTR:
1145     case AOP_DPTR2:
1146         DEBUGpic16_emitcode(";","%d",__LINE__);
1147     if (aop->type == AOP_DPTR2)
1148     {
1149         genSetDPTR(1);
1150     }
1151     
1152         while (offset > aop->coff) {
1153             pic16_emitcode ("inc","dptr");
1154             aop->coff++;
1155         }
1156         
1157         while (offset < aop->coff) {        
1158             pic16_emitcode("lcall","__decdptr");
1159             aop->coff--;
1160         }
1161         
1162         aop->coff = offset;
1163         if (aop->code) {
1164             pic16_emitcode("clr","a");
1165             pic16_emitcode("movc","a,@a+dptr");
1166         }
1167     else {
1168             pic16_emitcode("movx","a,@dptr");
1169     }
1170             
1171     if (aop->type == AOP_DPTR2)
1172     {
1173         genSetDPTR(0);
1174     }
1175             
1176     return (dname ? "acc" : "a");
1177         
1178         
1179     case AOP_IMMD:
1180         if (bit16) 
1181             sprintf (s,"%s",aop->aopu.aop_immd);
1182         else
1183             if (offset) 
1184                 sprintf(s,"(%s >> %d)",
1185                         aop->aopu.aop_immd,
1186                         offset*8);
1187             else
1188                 sprintf(s,"%s",
1189                         aop->aopu.aop_immd);
1190         DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1191         rs = Safe_calloc(1,strlen(s)+1);
1192         strcpy(rs,s);   
1193         return rs;
1194         
1195     case AOP_DIR:
1196       if (offset) {
1197         sprintf(s,"(%s + %d)",
1198                 aop->aopu.aop_dir,
1199                 offset);
1200         DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1201       } else
1202             sprintf(s,"%s",aop->aopu.aop_dir);
1203         rs = Safe_calloc(1,strlen(s)+1);
1204         strcpy(rs,s);   
1205         return rs;
1206         
1207     case AOP_REG:
1208       //if (dname) 
1209       //    return aop->aopu.aop_reg[offset]->dname;
1210       //else
1211             return aop->aopu.aop_reg[offset]->name;
1212         
1213     case AOP_CRY:
1214       //pic16_emitcode(";","%d",__LINE__);
1215       return aop->aopu.aop_dir;
1216         
1217     case AOP_ACC:
1218         DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1219 //        fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1220 //        assert( 0 );
1221         return aop->aopu.aop_str[offset];       //->"AOP_accumulator_bug";
1222
1223     case AOP_LIT:
1224         sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1225         rs = Safe_calloc(1,strlen(s)+1);
1226         strcpy(rs,s);   
1227         return rs;
1228         
1229     case AOP_STR:
1230         aop->coff = offset ;
1231         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1232             dname)
1233             return "acc";
1234         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1235         
1236         return aop->aopu.aop_str[offset];
1237         
1238     case AOP_PCODE:
1239       {
1240         pCodeOp *pcop = aop->aopu.pcop;
1241         DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1242         if(pcop->name) {
1243           DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1244           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1245           sprintf(s,"%s", pcop->name);
1246         } else
1247           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1248
1249       }
1250       rs = Safe_calloc(1,strlen(s)+1);
1251       strcpy(rs,s);   
1252       return rs;
1253
1254     }
1255
1256     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1257            "aopget got unsupported aop->type");
1258     exit(0);
1259 }
1260
1261
1262 /*-----------------------------------------------------------------*/
1263 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1264 /*-----------------------------------------------------------------*/
1265 pCodeOp *pic16_popGetTempReg(void)
1266 {
1267   pCodeOp *pcop;
1268
1269         pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1270         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1271                 PCOR(pcop)->r->wasUsed=1;
1272                 PCOR(pcop)->r->isFree=0;
1273
1274                 /* push value on stack */
1275                 pic16_pushpCodeOp( pcop );
1276         }
1277
1278   return pcop;
1279 }
1280
1281 /*-----------------------------------------------------------------*/
1282 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
1283 /*-----------------------------------------------------------------*/
1284 void pic16_popReleaseTempReg(pCodeOp *pcop)
1285 {
1286         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1287                 PCOR(pcop)->r->isFree = 1;
1288                 
1289                 pic16_poppCodeOp( pcop );
1290         }
1291 }
1292 /*-----------------------------------------------------------------*/
1293 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL             */
1294 /*-----------------------------------------------------------------*/
1295 pCodeOp *pic16_popGetLabel(unsigned int key)
1296 {
1297
1298   DEBUGpic16_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1299
1300   if(key>max_key)
1301     max_key = key;
1302
1303   return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1304 }
1305
1306 /*-----------------------------------------------------------------*/
1307 /* pic16_popCopyReg - copy a pcode operator                              */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1310 {
1311   pCodeOpReg *pcor;
1312
1313   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1314   pcor->pcop.type = pc->pcop.type;
1315   if(pc->pcop.name) {
1316     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1317       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1318   } else
1319     pcor->pcop.name = NULL;
1320
1321   pcor->r = pc->r;
1322   pcor->rIdx = pc->rIdx;
1323   pcor->r->wasUsed=1;
1324
1325 //  DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1326
1327   return PCOP(pcor);
1328 }
1329
1330 /*-----------------------------------------------------------------*/
1331 /* pic16_popGetLit - asm operator to pcode operator conversion     */
1332 /*-----------------------------------------------------------------*/
1333 pCodeOp *pic16_popGetLit(unsigned int lit)
1334 {
1335   return pic16_newpCodeOpLit(lit);
1336 }
1337
1338 /*-----------------------------------------------------------------*/
1339 /* pic16_popGetLit2 - asm operator to pcode operator conversion    */
1340 /*-----------------------------------------------------------------*/
1341 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1342 {
1343   return pic16_newpCodeOpLit2(lit, arg2);
1344 }
1345
1346
1347 /*-----------------------------------------------------------------*/
1348 /* pic16_popGetImmd - asm operator to pcode immediate conversion   */
1349 /*-----------------------------------------------------------------*/
1350 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1351 {
1352
1353   return pic16_newpCodeOpImmd(name, offset,index, 0);
1354 }
1355
1356
1357 /*-----------------------------------------------------------------*/
1358 /* pic16_popGet - asm operator to pcode operator conversion              */
1359 /*-----------------------------------------------------------------*/
1360 pCodeOp *pic16_popGetWithString(char *str)
1361 {
1362   pCodeOp *pcop;
1363
1364
1365   if(!str) {
1366     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1367     exit (1);
1368   }
1369
1370   pcop = pic16_newpCodeOp(str,PO_STR);
1371
1372   return pcop;
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* pic16_popRegFromString -                                        */
1377 /*-----------------------------------------------------------------*/
1378 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1379 {
1380
1381   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1382   pcop->type = PO_DIR;
1383
1384   DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1385 //  fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1386
1387   if(!str)
1388     str = "BAD_STRING";
1389
1390   pcop->name = Safe_calloc(1,strlen(str)+1);
1391   strcpy(pcop->name,str);
1392
1393   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1394
1395   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1396   if(PCOR(pcop)->r == NULL) {
1397 //      fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1398 //              __FUNCTION__, __LINE__, str, size, offset);
1399     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1400
1401         //fprintf(stderr, "allocating new register -> %s\n", str);
1402
1403 //    DEBUGpic16_emitcode(";","%d  %s   size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1404   } else {
1405 //    DEBUGpic16_emitcode(";","%d  %s   size= %d offset=%d",__LINE__,pcop->name,size,offset);
1406   }
1407   PCOR(pcop)->instance = offset;
1408
1409   return pcop;
1410 }
1411
1412 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1413 {
1414   pCodeOp *pcop;
1415
1416 //      DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1417
1418         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1419         PCOR(pcop)->rIdx = rIdx;
1420         PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1421         PCOR(pcop)->r->isFree = 0;
1422         PCOR(pcop)->r->wasUsed = 1;
1423
1424         pcop->type = PCOR(pcop)->r->pc_type;
1425
1426   return pcop;
1427 }
1428
1429 /*---------------------------------------------------------------------------------*/
1430 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1431 /*                 VR 030601                                                       */
1432 /*---------------------------------------------------------------------------------*/
1433 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1434 {
1435   pCodeOpReg2 *pcop2;
1436   pCodeOp *temp;
1437   
1438         pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1439
1440         /* comment the following check, so errors to throw up */
1441 //      if(!pcop2)return NULL;
1442
1443         temp = pic16_popGet(aop_dst, offset);
1444         pcop2->pcop2 = temp;
1445         
1446   return PCOP(pcop2);
1447 }
1448
1449
1450
1451 /*--------------------------------------------------------------------------------.-*/
1452 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1453 /*                  VR 030601 , adapted by Hans Dorn                                */
1454 /*--------------------------------------------------------------------------------.-*/
1455 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1456 {
1457   pCodeOpReg2 *pcop2;
1458  
1459         pcop2 = (pCodeOpReg2 *)src;
1460         pcop2->pcop2 = dst;
1461         
1462         return PCOP(pcop2);
1463 }
1464
1465
1466
1467 /*---------------------------------------------------------------------------------*/
1468 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with      */
1469 /*                     movff instruction                                           */
1470 /*---------------------------------------------------------------------------------*/
1471 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1472 {
1473   pCodeOpReg2 *pcop2;
1474
1475         if(!noalloc) {
1476                 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1477                 pcop2->pcop2 = pic16_popCopyReg(dst);
1478         } else {
1479                 /* the pCodeOp may be already allocated */
1480                 pcop2 = (pCodeOpReg2 *)(src);
1481                 pcop2->pcop2 = (pCodeOp *)(dst);
1482         }
1483
1484   return PCOP(pcop2);
1485 }
1486
1487
1488 /*-----------------------------------------------------------------*/
1489 /* pic16_popGet - asm operator to pcode operator conversion              */
1490 /*-----------------------------------------------------------------*/
1491 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1492 {
1493   //char *s = buffer ;
1494   char *rs;
1495   pCodeOp *pcop;
1496
1497     //DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1498     /* offset is greater than
1499     size then zero */
1500
1501 //    if (offset > (aop->size - 1) &&
1502 //        aop->type != AOP_LIT)
1503 //      return NULL;  //zero;
1504
1505     /* depending on type */
1506     switch (aop->type) {
1507         
1508     case AOP_R0:
1509     case AOP_R1:
1510     case AOP_DPTR:
1511     case AOP_DPTR2:
1512         DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1513         fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1514         assert( 0 );
1515         return NULL;
1516
1517
1518
1519     case AOP_IMMD:
1520       DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1521       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1522
1523     case AOP_ACC:
1524         fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1525
1526         int rIdx = IDX_WREG;            //aop->aopu.aop_reg[offset]->rIdx;
1527
1528         DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1529         
1530         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1531         PCOR(pcop)->rIdx = rIdx;
1532         PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1533         PCOR(pcop)->r->wasUsed=1;
1534         PCOR(pcop)->r->isFree=0;
1535
1536         PCOR(pcop)->instance = offset;
1537         pcop->type = PCOR(pcop)->r->pc_type;
1538 //      rs = aop->aopu.aop_reg[offset]->name;
1539 //      DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1540         return pcop;
1541
1542
1543         return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1544 //      return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1545
1546 //      assert( 0 );
1547         
1548     case AOP_DIR:
1549       DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1550       return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1551         
1552     case AOP_REG:
1553       {
1554         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1555
1556         DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1557         
1558         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1559         PCOR(pcop)->rIdx = rIdx;
1560         PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1561         PCOR(pcop)->r->wasUsed=1;
1562         PCOR(pcop)->r->isFree=0;
1563
1564         PCOR(pcop)->instance = offset;
1565         pcop->type = PCOR(pcop)->r->pc_type;
1566         rs = aop->aopu.aop_reg[offset]->name;
1567         DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1568         return pcop;
1569       }
1570
1571     case AOP_CRY:
1572         DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1573
1574       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1575       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1576       //if(PCOR(pcop)->r == NULL)
1577       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1578       return pcop;
1579         
1580     case AOP_LIT:
1581         DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1582       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1583
1584     case AOP_STR:
1585       DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1586       return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1587
1588       /*
1589       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1590       PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1591       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1592       pcop->type = PCOR(pcop)->r->pc_type;
1593       pcop->name = PCOR(pcop)->r->name;
1594
1595       return pcop;
1596       */
1597
1598     case AOP_PCODE:
1599       DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1600                           __LINE__, 
1601                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1602       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1603 #if 1
1604         switch( aop->aopu.pcop->type ) {
1605                 case PO_DIR: PCOR(pcop)->instance = offset; break;
1606                 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1607                 default:
1608                         assert( 0 );    /* should never reach here */;
1609         }
1610 #else
1611       PCOI(pcop)->offset = offset;
1612 #endif
1613       return pcop;
1614     }
1615
1616     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1617            "pic16_popGet got unsupported aop->type");
1618     exit(0);
1619 }
1620 /*-----------------------------------------------------------------*/
1621 /* pic16_aopPut - puts a string for a aop                                */
1622 /*-----------------------------------------------------------------*/
1623 void pic16_aopPut (asmop *aop, char *s, int offset)
1624 {
1625     char *d = buffer ;
1626     symbol *lbl ;
1627
1628     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1629
1630     if (aop->size && offset > ( aop->size - 1)) {
1631         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1632                "pic16_aopPut got offset > aop->size");
1633         exit(0);
1634     }
1635
1636     /* will assign value to value */
1637     /* depending on where it is ofcourse */
1638     switch (aop->type) {
1639     case AOP_DIR:
1640       if (offset) {
1641         sprintf(d,"(%s + %d)",
1642                 aop->aopu.aop_dir,offset);
1643         fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1644
1645       } else
1646             sprintf(d,"%s",aop->aopu.aop_dir);
1647         
1648         if (strcmp(d,s)) {
1649           DEBUGpic16_emitcode(";","%d",__LINE__);
1650           if(strcmp(s,"W"))
1651             pic16_emitcode("movf","%s,w",s);
1652           pic16_emitcode("movwf","%s",d);
1653
1654           if(strcmp(s,"W")) {
1655             pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1656             if(offset >= aop->size) {
1657               pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1658               break;
1659             } else
1660               pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1661           }
1662
1663           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1664
1665
1666         }
1667         break;
1668         
1669     case AOP_REG:
1670       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1671         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1672           /*
1673             if (*s == '@'           ||
1674                 strcmp(s,"r0") == 0 ||
1675                 strcmp(s,"r1") == 0 ||
1676                 strcmp(s,"r2") == 0 ||
1677                 strcmp(s,"r3") == 0 ||
1678                 strcmp(s,"r4") == 0 ||
1679                 strcmp(s,"r5") == 0 ||
1680                 strcmp(s,"r6") == 0 || 
1681                 strcmp(s,"r7") == 0 )
1682                 pic16_emitcode("mov","%s,%s  ; %d",
1683                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1684             else
1685           */
1686
1687           if(strcmp(s,"W")==0 )
1688             pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
1689
1690           pic16_emitcode("movwf","%s",
1691                    aop->aopu.aop_reg[offset]->name);
1692
1693           if(strcmp(s,zero)==0) {
1694             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1695
1696           } else if(strcmp(s,"W")==0) {
1697             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1698             pcop->type = PO_GPR_REGISTER;
1699
1700             PCOR(pcop)->rIdx = -1;
1701             PCOR(pcop)->r = NULL;
1702
1703             DEBUGpic16_emitcode(";","%d",__LINE__);
1704             pcop->name = Safe_strdup(s);
1705             pic16_emitpcode(POC_MOVFW,pcop);
1706             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1707           } else if(strcmp(s,one)==0) {
1708             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1709             pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1710           } else {
1711             pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1712           }
1713         }
1714         break;
1715         
1716     case AOP_DPTR:
1717     case AOP_DPTR2:
1718     
1719     if (aop->type == AOP_DPTR2)
1720     {
1721         genSetDPTR(1);
1722     }
1723     
1724         if (aop->code) {
1725             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1726                    "pic16_aopPut writting to code space");
1727             exit(0);
1728         }
1729         
1730         while (offset > aop->coff) {
1731             aop->coff++;
1732             pic16_emitcode ("inc","dptr");
1733         }
1734         
1735         while (offset < aop->coff) {
1736             aop->coff-- ;
1737             pic16_emitcode("lcall","__decdptr");
1738         }
1739         
1740         aop->coff = offset;
1741         
1742         /* if not in accumulater */
1743         MOVA(s);        
1744         
1745         pic16_emitcode ("movx","@dptr,a");
1746         
1747     if (aop->type == AOP_DPTR2)
1748     {
1749         genSetDPTR(0);
1750     }
1751         break;
1752         
1753     case AOP_R0:
1754     case AOP_R1:
1755         while (offset > aop->coff) {
1756             aop->coff++;
1757             pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1758         }
1759         while (offset < aop->coff) {
1760             aop->coff-- ;
1761             pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1762         }
1763         aop->coff = offset;
1764         
1765         if (aop->paged) {
1766             MOVA(s);           
1767             pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1768             
1769         } else
1770             if (*s == '@') {
1771                 MOVA(s);
1772                 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1773             } else
1774                 if (strcmp(s,"r0") == 0 ||
1775                     strcmp(s,"r1") == 0 ||
1776                     strcmp(s,"r2") == 0 ||
1777                     strcmp(s,"r3") == 0 ||
1778                     strcmp(s,"r4") == 0 ||
1779                     strcmp(s,"r5") == 0 ||
1780                     strcmp(s,"r6") == 0 || 
1781                     strcmp(s,"r7") == 0 ) {
1782                     char buffer[10];
1783                     sprintf(buffer,"a%s",s);
1784                     pic16_emitcode("mov","@%s,%s",
1785                              aop->aopu.aop_ptr->name,buffer);
1786                 } else
1787                     pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1788         
1789         break;
1790         
1791     case AOP_STK:
1792         if (strcmp(s,"a") == 0)
1793             pic16_emitcode("push","acc");
1794         else
1795             pic16_emitcode("push","%s",s);
1796         
1797         break;
1798         
1799     case AOP_CRY:
1800         /* if bit variable */
1801         if (!aop->aopu.aop_dir) {
1802             pic16_emitcode("clr","a");
1803             pic16_emitcode("rlc","a");
1804         } else {
1805             if (s == zero) 
1806                 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1807             else
1808                 if (s == one)
1809                     pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1810                 else
1811                     if (!strcmp(s,"c"))
1812                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1813                     else {
1814                         lbl = newiTempLabel(NULL);
1815                         
1816                         if (strcmp(s,"a")) {
1817                             MOVA(s);
1818                         }
1819                         pic16_emitcode("clr","c");
1820                         pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1821                         pic16_emitcode("cpl","c");
1822                         pic16_emitcode("","%05d_DS_:",lbl->key+100);
1823                         pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1824                     }
1825         }
1826         break;
1827         
1828     case AOP_STR:
1829         aop->coff = offset;
1830         if (strcmp(aop->aopu.aop_str[offset],s))
1831             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1832         break;
1833         
1834     case AOP_ACC:
1835         aop->coff = offset;
1836         if (!offset && (strcmp(s,"acc") == 0))
1837             break;
1838         
1839         if (strcmp(aop->aopu.aop_str[offset],s))
1840             pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1841         break;
1842
1843     default :
1844         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1845                "pic16_aopPut got unsupported aop->type");
1846         exit(0);    
1847     }    
1848
1849 }
1850
1851 /*-----------------------------------------------------------------*/
1852 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1853 /*-----------------------------------------------------------------*/
1854 static void mov2w (asmop *aop, int offset)
1855 {
1856
1857   if(!aop)
1858     return;
1859
1860   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1861
1862   if ( aop->type == AOP_PCODE ||
1863        aop->type == AOP_LIT )
1864     pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1865   else
1866     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1867
1868 }
1869
1870
1871 /* push pcop into stack */
1872 void pic16_pushpCodeOp(pCodeOp *pcop)
1873 {
1874         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1875 }
1876
1877 /* pop pcop from stack */
1878 void pic16_poppCodeOp(pCodeOp *pcop)
1879 {
1880         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1881 }
1882
1883
1884 /*-----------------------------------------------------------------*/
1885 /* pushw - pushes wreg to stack                                    */
1886 /*-----------------------------------------------------------------*/
1887 void pushw(void)
1888 {
1889         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1890         pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1891 }
1892
1893                 
1894 /*-----------------------------------------------------------------*/
1895 /* pushaop - pushes aop to stack                                   */
1896 /*-----------------------------------------------------------------*/
1897 void pushaop(asmop *aop, int offset)
1898 {
1899         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1900         pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1901 }
1902
1903 /*-----------------------------------------------------------------*/
1904 /* popaop - pops aop from stack                                    */
1905 /*-----------------------------------------------------------------*/
1906 void popaop(asmop *aop, int offset)
1907 {
1908         DEBUGpic16_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
1909         pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1910 }
1911
1912 void popaopidx(asmop *aop, int offset, int index)
1913 {
1914   int ofs=1;
1915
1916         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1917
1918         if(STACK_MODEL_LARGE)ofs++;
1919
1920         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1921         pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1922 }
1923
1924 /*-----------------------------------------------------------------*/
1925 /* reAdjustPreg - points a register back to where it should        */
1926 /*-----------------------------------------------------------------*/
1927 static void reAdjustPreg (asmop *aop)
1928 {
1929     int size ;
1930
1931     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1932     aop->coff = 0;
1933     if ((size = aop->size) <= 1)
1934         return ;
1935     size-- ;
1936     switch (aop->type) {
1937         case AOP_R0 :
1938         case AOP_R1 :
1939             while (size--)
1940                 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1941             break;          
1942         case AOP_DPTR :
1943         case AOP_DPTR2:
1944             if (aop->type == AOP_DPTR2)
1945             {
1946                 genSetDPTR(1);
1947             } 
1948             while (size--)
1949             {
1950                 pic16_emitcode("lcall","__decdptr");
1951             }
1952                 
1953             if (aop->type == AOP_DPTR2)
1954             {
1955                 genSetDPTR(0);
1956             }                
1957             break;  
1958
1959     }   
1960
1961 }
1962
1963
1964 #if 0
1965 /*-----------------------------------------------------------------*/
1966 /* opIsGptr: returns non-zero if the passed operand is             */   
1967 /* a generic pointer type.                                         */
1968 /*-----------------------------------------------------------------*/ 
1969 static int opIsGptr(operand *op)
1970 {
1971     sym_link *type = operandType(op);
1972     
1973     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1974     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1975     {
1976         return 1;
1977     }
1978     return 0;        
1979 }
1980 #endif
1981
1982 /*-----------------------------------------------------------------*/
1983 /* pic16_getDataSize - get the operand data size                         */
1984 /*-----------------------------------------------------------------*/
1985 int pic16_getDataSize(operand *op)
1986 {
1987     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1988
1989
1990     return AOP_SIZE(op);
1991
1992     // tsd- in the pic port, the genptr size is 1, so this code here
1993     // fails. ( in the 8051 port, the size was 4).
1994 #if 0
1995     int size;
1996     size = AOP_SIZE(op);
1997     if (size == GPTRSIZE)
1998     {
1999         sym_link *type = operandType(op);
2000         if (IS_GENPTR(type))
2001         {
2002             /* generic pointer; arithmetic operations
2003              * should ignore the high byte (pointer type).
2004              */
2005             size--;
2006     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2007         }
2008     }
2009     return size;
2010 #endif
2011 }
2012
2013 /*-----------------------------------------------------------------*/
2014 /* pic16_outAcc - output Acc                                             */
2015 /*-----------------------------------------------------------------*/
2016 void pic16_outAcc(operand *result)
2017 {
2018   int size,offset;
2019   DEBUGpic16_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
2020   DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2021
2022
2023   size = pic16_getDataSize(result);
2024   if(size){
2025     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2026     size--;
2027     offset = 1;
2028     /* unsigned or positive */
2029     while(size--)
2030       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2031   }
2032
2033 }
2034
2035 /*-----------------------------------------------------------------*/
2036 /* pic16_outBitC - output a bit C                                        */
2037 /*-----------------------------------------------------------------*/
2038 void pic16_outBitC(operand *result)
2039 {
2040
2041     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2042     /* if the result is bit */
2043     if (AOP_TYPE(result) == AOP_CRY) 
2044         pic16_aopPut(AOP(result),"c",0);
2045     else {
2046         pic16_emitcode("clr","a  ; %d", __LINE__);
2047         pic16_emitcode("rlc","a");
2048         pic16_outAcc(result);
2049     }
2050 }
2051
2052 /*-----------------------------------------------------------------*/
2053 /* pic16_toBoolean - emit code for orl a,operator(sizeop)                */
2054 /*-----------------------------------------------------------------*/
2055 void pic16_toBoolean(operand *oper)
2056 {
2057     int size = AOP_SIZE(oper) - 1;
2058     int offset = 1;
2059
2060     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2061
2062     if ( AOP_TYPE(oper) != AOP_ACC) {
2063       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2064     }
2065     while (size--) {
2066       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2067     }
2068 }
2069
2070
2071 #if !defined(GEN_Not)
2072 /*-----------------------------------------------------------------*/
2073 /* genNot - generate code for ! operation                          */
2074 /*-----------------------------------------------------------------*/
2075 static void pic16_genNot (iCode *ic)
2076 {
2077   symbol *tlbl;
2078   int size;
2079
2080   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2081   /* assign asmOps to operand & result */
2082   pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2083   pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2084
2085   DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2086   /* if in bit space then a special case */
2087   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2088     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2089       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2090       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2091     } else {
2092       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2093       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2094       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2095     }
2096     goto release;
2097   }
2098
2099   size = AOP_SIZE(IC_LEFT(ic));
2100   if(size == 1) {
2101     pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2102     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2103     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2104     goto release;
2105   }
2106   pic16_toBoolean(IC_LEFT(ic));
2107
2108   tlbl = newiTempLabel(NULL);
2109   pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2110   pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2111   pic16_outBitC(IC_RESULT(ic));
2112
2113  release:    
2114   /* release the aops */
2115   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2116   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2117 }
2118 #endif
2119
2120
2121 #if !defined(GEN_Cpl)
2122 /*-----------------------------------------------------------------*/
2123 /* genCpl - generate code for complement                           */
2124 /*-----------------------------------------------------------------*/
2125 static void pic16_genCpl (iCode *ic)
2126 {
2127     int offset = 0;
2128     int size ;
2129
2130
2131     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2132     /* assign asmOps to operand & result */
2133     pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2134     pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2135
2136     /* if both are in bit space then 
2137     a special case */
2138     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2139         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
2140
2141         pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
2142         pic16_emitcode("cpl","c"); 
2143         pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
2144         goto release; 
2145     } 
2146
2147     size = AOP_SIZE(IC_RESULT(ic));
2148     while (size--) {
2149 /*
2150         char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2151         MOVA(l);       
2152         pic16_emitcode("cpl","a");
2153         pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2154 */
2155         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2156               pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
2157         } else {
2158                 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2159                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2160         }
2161         offset++;
2162
2163     }
2164
2165
2166 release:
2167     /* release the aops */
2168     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2169     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2170 }
2171 #endif
2172
2173 /*-----------------------------------------------------------------*/
2174 /* genUminusFloat - unary minus for floating points                */
2175 /*-----------------------------------------------------------------*/
2176 static void genUminusFloat(operand *op,operand *result)
2177 {
2178     int size ,offset =0 ;
2179     char *l;
2180
2181     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2182     /* for this we just need to flip the 
2183     first it then copy the rest in place */
2184     size = AOP_SIZE(op) - 1;
2185     l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2186
2187     MOVA(l);    
2188
2189     pic16_emitcode("cpl","acc.7");
2190     pic16_aopPut(AOP(result),"a",3);    
2191
2192     while(size--) {
2193         pic16_aopPut(AOP(result),
2194                pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2195                offset);
2196         offset++;
2197     }          
2198 }
2199
2200 /*-----------------------------------------------------------------*/
2201 /* genUminus - unary minus code generation                         */
2202 /*-----------------------------------------------------------------*/
2203 static void genUminus (iCode *ic)
2204 {
2205   int size, i;
2206   sym_link *optype, *rtype;
2207
2208
2209   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2210   /* assign asmops */
2211   pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2212   pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2213
2214   /* if both in bit space then special
2215      case */
2216   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2217       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
2218
2219     pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
2220     pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2221     pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
2222
2223     goto release; 
2224   } 
2225
2226   optype = operandType(IC_LEFT(ic));
2227   rtype = operandType(IC_RESULT(ic));
2228
2229   /* if float then do float stuff */
2230   if (IS_FLOAT(optype)) {
2231     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2232     goto release;
2233   }
2234
2235   /* otherwise subtract from zero by taking the 2's complement */
2236   size = AOP_SIZE(IC_LEFT(ic));
2237
2238   for(i=0; i<size; i++) {
2239     if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2240       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
2241     else {
2242       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2243       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2244     }
2245   }
2246
2247   pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
2248   for(i=1; i<size; i++) {
2249     emitSKPNZ;
2250     pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
2251   }
2252
2253  release:
2254   /* release the aops */
2255   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2256   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2257 }
2258
2259 /*-----------------------------------------------------------------*/
2260 /* saveRegisters - will look for a call and save the registers     */
2261 /*-----------------------------------------------------------------*/
2262 static void saveRegisters(iCode *lic) 
2263 {
2264     int i;
2265     iCode *ic;
2266     bitVect *rsave;
2267     sym_link *dtype;
2268
2269     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2270     /* look for call */
2271     for (ic = lic ; ic ; ic = ic->next) 
2272         if (ic->op == CALL || ic->op == PCALL)
2273             break;
2274
2275     if (!ic) {
2276         fprintf(stderr,"found parameter push with no function call\n");
2277         return ;
2278     }
2279
2280     /* if the registers have been saved already then
2281     do nothing */
2282     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2283         return ;
2284
2285     /* find the registers in use at this time 
2286     and push them away to safety */
2287     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2288                           ic->rUsed);
2289
2290     ic->regsSaved = 1;
2291     if (options.useXstack) {
2292         if (bitVectBitValue(rsave,R0_IDX))
2293             pic16_emitcode("mov","b,r0");
2294         pic16_emitcode("mov","r0,%s",spname);
2295         for (i = 0 ; i < pic16_nRegs ; i++) {
2296             if (bitVectBitValue(rsave,i)) {
2297                 if (i == R0_IDX)
2298                     pic16_emitcode("mov","a,b");
2299                 else
2300                     pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2301                 pic16_emitcode("movx","@r0,a");
2302                 pic16_emitcode("inc","r0");
2303             }
2304         }
2305         pic16_emitcode("mov","%s,r0",spname);
2306         if (bitVectBitValue(rsave,R0_IDX))
2307             pic16_emitcode("mov","r0,b");           
2308     }// else
2309     //for (i = 0 ; i < pic16_nRegs ; i++) {
2310     //    if (bitVectBitValue(rsave,i))
2311     //  pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2312     //}
2313
2314     dtype = operandType(IC_LEFT(ic));
2315     if (currFunc && dtype && 
2316         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2317         IFFUNC_ISISR(currFunc->type) &&
2318         !ic->bankSaved) 
2319
2320         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2321
2322 }
2323 /*-----------------------------------------------------------------*/
2324 /* unsaveRegisters - pop the pushed registers                      */
2325 /*-----------------------------------------------------------------*/
2326 static void unsaveRegisters (iCode *ic)
2327 {
2328     int i;
2329     bitVect *rsave;
2330
2331     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2332     /* find the registers in use at this time 
2333     and push them away to safety */
2334     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2335                           ic->rUsed);
2336     
2337     if (options.useXstack) {
2338         pic16_emitcode("mov","r0,%s",spname);   
2339         for (i =  pic16_nRegs ; i >= 0 ; i--) {
2340             if (bitVectBitValue(rsave,i)) {
2341                 pic16_emitcode("dec","r0");
2342                 pic16_emitcode("movx","a,@r0");
2343                 if (i == R0_IDX)
2344                     pic16_emitcode("mov","b,a");
2345                 else
2346                     pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2347             }       
2348
2349         }
2350         pic16_emitcode("mov","%s,r0",spname);
2351         if (bitVectBitValue(rsave,R0_IDX))
2352             pic16_emitcode("mov","r0,b");
2353     } //else
2354     //for (i =  pic16_nRegs ; i >= 0 ; i--) {
2355     //    if (bitVectBitValue(rsave,i))
2356     //  pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2357     //}
2358
2359 }  
2360
2361
2362 /*-----------------------------------------------------------------*/
2363 /* pushSide -                                                      */
2364 /*-----------------------------------------------------------------*/
2365 static void pushSide(operand * oper, int size)
2366 {
2367 #if 0
2368         int offset = 0;
2369     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2370         while (size--) {
2371                 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2372                 if (AOP_TYPE(oper) != AOP_REG &&
2373                     AOP_TYPE(oper) != AOP_DIR &&
2374                     strcmp(l,"a") ) {
2375                         pic16_emitcode("mov","a,%s",l);
2376                         pic16_emitcode("push","acc");
2377                 } else
2378                         pic16_emitcode("push","%s",l);
2379         }
2380 #endif
2381 }
2382
2383 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2384 {
2385 //              (AOP(left)->aopu.pcop->type == PO_DIR)?
2386
2387         if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2388                 pic16_emitpcode(POC_MOVFW, src);
2389                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2390         } else {
2391                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2392                         src, pic16_popGet(AOP(op), offset)));
2393         }
2394 }
2395
2396
2397 /*-----------------------------------------------------------------*/
2398 /* assignResultValue - assign results to oper, rescall==1 is       */
2399 /*                     called from genCall() or genPCall()         */
2400 /*-----------------------------------------------------------------*/
2401 static void assignResultValue(operand * oper, int rescall)
2402 {
2403   int size = AOP_SIZE(oper);
2404
2405         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2406         DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2407
2408         if(rescall) {
2409                 /* assign result from a call/pcall function() */
2410                 
2411                 /* function results are stored in a special order,
2412                  * see top of file with Function return policy, or manual */
2413
2414                 if(size <= 4) {
2415                         /* 8-bits, result in WREG */
2416                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2417                         
2418                         if(size>1) {
2419                                 /* 16-bits, result in PRODL:WREG */
2420                                 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2421 //                              pic16_emitpcode(POC_MOVFF,
2422 //                                      pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1)));
2423                         }
2424                         
2425                         if(size>2) {
2426                                 /* 24-bits, result in PRODH:PRODL:WREG */
2427                                 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodl));
2428
2429 //                              pic16_emitpcode(POC_MOVFF,
2430 //                                      pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2)));
2431                         }
2432                         
2433                         if(size>3) {
2434                                 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2435                                 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_prodl));
2436
2437 //                              pic16_emitpcode(POC_MOVFF,
2438 //                                      pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3)));
2439                         }
2440                 } else {
2441                         /* >32-bits, result on stack, and FSR0 points to beginning.
2442                          * Fix stack when done */
2443                          
2444                         while (size--) {
2445 //                              DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2446 //                              DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2447                 
2448                                 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2449                                 GpsuedoStkPtr++;
2450                         }
2451                         
2452                         /* fix stack */
2453                         pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2454                         pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2455                         if(STACK_MODEL_LARGE) {
2456                                 emitSKPNC;
2457                                 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2458                         }
2459                 }                       
2460         } else {
2461                 if(!GpsuedoStkPtr) {
2462 //                      DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2463                         /* The last byte in the assignment is in W */
2464                         size--;
2465                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2466                         GpsuedoStkPtr++;
2467                 }
2468
2469                 while (size--) {
2470 //                      DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2471 //                      DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2472                 
2473                         popaopidx(AOP(oper), size, GpsuedoStkPtr);
2474                         GpsuedoStkPtr++;
2475
2476 #if 0
2477 #if STACK_SUPPORT
2478                 if(!USE_STACK)
2479                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2480 #else
2481                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2482 #endif
2483 #endif
2484
2485                 }
2486         }
2487                 
2488 }
2489
2490
2491 /*-----------------------------------------------------------------*/
2492 /* genIpush - genrate code for pushing this gets a little complex  */
2493 /*-----------------------------------------------------------------*/
2494 static void genIpush (iCode *ic)
2495 {
2496
2497   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2498 #if 0
2499     int size, offset = 0 ;
2500     char *l;
2501
2502
2503     /* if this is not a parm push : ie. it is spill push 
2504     and spill push is always done on the local stack */
2505     if (!ic->parmPush) {
2506
2507         /* and the item is spilt then do nothing */
2508         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2509             return ;
2510
2511         pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2512         size = AOP_SIZE(IC_LEFT(ic));
2513         /* push it on the stack */
2514         while(size--) {
2515             l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2516             if (*l == '#') {
2517                 MOVA(l);
2518                 l = "acc";
2519             }
2520             pic16_emitcode("push","%s",l);
2521         }
2522         return ;        
2523     }
2524
2525     /* this is a paramter push: in this case we call
2526     the routine to find the call and save those
2527     registers that need to be saved */   
2528     saveRegisters(ic);
2529
2530     /* then do the push */
2531     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2532
2533
2534         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2535     size = AOP_SIZE(IC_LEFT(ic));
2536
2537     while (size--) {
2538         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2539         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2540             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2541             strcmp(l,"a") ) {
2542             pic16_emitcode("mov","a,%s",l);
2543             pic16_emitcode("push","acc");
2544         } else
2545             pic16_emitcode("push","%s",l);
2546     }       
2547
2548     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2549 #endif
2550 }
2551
2552 /*-----------------------------------------------------------------*/
2553 /* genIpop - recover the registers: can happen only for spilling   */
2554 /*-----------------------------------------------------------------*/
2555 static void genIpop (iCode *ic)
2556 {
2557   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2558 #if 0
2559     int size,offset ;
2560
2561
2562     /* if the temp was not pushed then */
2563     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2564         return ;
2565
2566     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2567     size = AOP_SIZE(IC_LEFT(ic));
2568     offset = (size-1);
2569     while (size--) 
2570         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2571                                    FALSE,TRUE));
2572
2573     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2574 #endif
2575 }
2576
2577 /*-----------------------------------------------------------------*/
2578 /* unsaverbank - restores the resgister bank from stack            */
2579 /*-----------------------------------------------------------------*/
2580 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2581 {
2582   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2583 #if 0
2584     int i;
2585     asmop *aop ;
2586     regs *r = NULL;
2587
2588     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2589     if (popPsw) {
2590         if (options.useXstack) {
2591             aop = newAsmop(0);
2592             r = getFreePtr(ic,&aop,FALSE);
2593             
2594             
2595             pic16_emitcode("mov","%s,_spx",r->name);
2596             pic16_emitcode("movx","a,@%s",r->name);
2597             pic16_emitcode("mov","psw,a");
2598             pic16_emitcode("dec","%s",r->name);
2599             
2600         }else
2601             pic16_emitcode ("pop","psw");
2602     }
2603
2604     for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2605         if (options.useXstack) {       
2606             pic16_emitcode("movx","a,@%s",r->name);
2607             //pic16_emitcode("mov","(%s+%d),a",
2608             //       regspic16[i].base,8*bank+regspic16[i].offset);
2609             pic16_emitcode("dec","%s",r->name);
2610
2611         } else 
2612           pic16_emitcode("pop",""); //"(%s+%d)",
2613         //regspic16[i].base,8*bank); //+regspic16[i].offset);
2614     }
2615
2616     if (options.useXstack) {
2617
2618         pic16_emitcode("mov","_spx,%s",r->name);
2619         pic16_freeAsmop(NULL,aop,ic,TRUE);
2620
2621     }
2622 #endif 
2623 }
2624
2625 /*-----------------------------------------------------------------*/
2626 /* saverbank - saves an entire register bank on the stack          */
2627 /*-----------------------------------------------------------------*/
2628 static void saverbank (int bank, iCode *ic, bool pushPsw)
2629 {
2630   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2631 #if 0
2632     int i;
2633     asmop *aop ;
2634     regs *r = NULL;
2635
2636     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2637     if (options.useXstack) {
2638
2639         aop = newAsmop(0);
2640         r = getFreePtr(ic,&aop,FALSE);  
2641         pic16_emitcode("mov","%s,_spx",r->name);
2642
2643     }
2644
2645     for (i = 0 ; i < pic16_nRegs ;i++) {
2646         if (options.useXstack) {
2647             pic16_emitcode("inc","%s",r->name);
2648             //pic16_emitcode("mov","a,(%s+%d)",
2649             //         regspic16[i].base,8*bank+regspic16[i].offset);
2650             pic16_emitcode("movx","@%s,a",r->name);           
2651         } else 
2652           pic16_emitcode("push","");// "(%s+%d)",
2653                      //regspic16[i].base,8*bank+regspic16[i].offset);
2654     }
2655     
2656     if (pushPsw) {
2657         if (options.useXstack) {
2658             pic16_emitcode("mov","a,psw");
2659             pic16_emitcode("movx","@%s,a",r->name);     
2660             pic16_emitcode("inc","%s",r->name);
2661             pic16_emitcode("mov","_spx,%s",r->name);       
2662             pic16_freeAsmop (NULL,aop,ic,TRUE);
2663             
2664         } else
2665             pic16_emitcode("push","psw");
2666         
2667         pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2668     }
2669     ic->bankSaved = 1;
2670 #endif
2671 }
2672
2673
2674
2675 /*-----------------------------------------------------------------*/
2676 /* genCall - generates a call statement                            */
2677 /*-----------------------------------------------------------------*/
2678 static void genCall (iCode *ic)
2679 {
2680   sym_link *dtype;   
2681   int stackParms=0;
2682   
2683         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2684
2685         /* if caller saves & we have not saved then */
2686         if (!ic->regsSaved)
2687                 saveRegisters(ic);
2688
2689         /* if we are calling a function that is not using
2690          * the same register bank then we need to save the
2691          * destination registers on the stack */
2692         dtype = operandType(IC_LEFT(ic));
2693         if (currFunc && dtype && 
2694                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2695                 IFFUNC_ISISR(currFunc->type) &&
2696                 !ic->bankSaved) 
2697
2698                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2699
2700         /* if send set is not empty the assign */
2701         if (_G.sendSet) {
2702           iCode *sic;
2703
2704                 /* For the Pic port, there is no data stack.
2705                  * So parameters passed to functions are stored
2706                  * in registers. (The pCode optimizer will get
2707                  * rid of most of these :). */
2708
2709           int psuedoStkPtr=-1; 
2710           int firstTimeThruLoop = 1;
2711
2712                 _G.sendSet = reverseSet(_G.sendSet);
2713
2714                 /* First figure how many parameters are getting passed */
2715                 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2716                         pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2717                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2718                         pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2719                 }
2720
2721                 stackParms = psuedoStkPtr;
2722
2723                 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2724                   int size, offset = 0;
2725
2726                         pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2727                         size = AOP_SIZE(IC_LEFT(sic));
2728
2729                         while (size--) {
2730                                 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2731                                         pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2732                                 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2733
2734                                 if(!firstTimeThruLoop) {
2735                                         /* If this is not the first time we've been through the loop
2736                                          * then we need to save the parameter in a temporary
2737                                          * register. The last byte of the last parameter is
2738                                          * passed in W. */
2739
2740                                         pushw();
2741                                         --psuedoStkPtr;         // sanity check
2742                                 }
2743                         
2744                                 firstTimeThruLoop=0;
2745
2746                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2747                                 offset++;
2748                         }
2749                         pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2750                 }
2751                 _G.sendSet = NULL;
2752         }
2753
2754         /* make the call */
2755         pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2756                         OP_SYMBOL(IC_LEFT(ic))->rname :
2757                         OP_SYMBOL(IC_LEFT(ic))->name));
2758
2759         GpsuedoStkPtr=0;
2760         /* if we need assign a result value */
2761         if ((IS_ITEMP(IC_RESULT(ic)) && 
2762                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2763                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2764                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2765
2766                 _G.accInUse++;
2767                 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2768                 _G.accInUse--;
2769
2770                 assignResultValue(IC_RESULT(ic), 1);
2771
2772                 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2773                          pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2774                 
2775                 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2776         }
2777
2778         if(stackParms>0) {
2779                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2780                 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2781                 if(STACK_MODEL_LARGE) {
2782                         emitSKPNC;
2783                         pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2784                 }
2785         }
2786
2787         /* adjust the stack for parameters if required */
2788 //      fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2789
2790         if (ic->parmBytes) {
2791           int i;
2792
2793                 if (ic->parmBytes > 3) {
2794                         pic16_emitcode("mov","a,%s",spname);
2795                         pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2796                         pic16_emitcode("mov","%s,a",spname);
2797                 } else 
2798                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2799                                 pic16_emitcode("dec","%s",spname);
2800         }
2801
2802         /* if register bank was saved then pop them */
2803         if (ic->bankSaved)
2804                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2805
2806         /* if we hade saved some registers then unsave them */
2807         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2808                 unsaveRegisters (ic);
2809 }
2810
2811 /*-----------------------------------------------------------------*/
2812 /* genPcall - generates a call by pointer statement                */
2813 /*-----------------------------------------------------------------*/
2814 static void genPcall (iCode *ic)
2815 {
2816     sym_link *dtype;
2817     symbol *rlbl = newiTempLabel(NULL);
2818
2819
2820     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2821     /* if caller saves & we have not saved then */
2822     if (!ic->regsSaved)
2823         saveRegisters(ic);
2824
2825     /* if we are calling a function that is not using
2826     the same register bank then we need to save the
2827     destination registers on the stack */
2828     dtype = operandType(IC_LEFT(ic));
2829     if (currFunc && dtype && 
2830         IFFUNC_ISISR(currFunc->type) &&
2831         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2832         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2833
2834
2835     /* push the return address on to the stack */
2836     pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2837     pic16_emitcode("push","acc");    
2838     pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2839     pic16_emitcode("push","acc");
2840     
2841     if (options.model == MODEL_FLAT24)
2842     {
2843         pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2844         pic16_emitcode("push","acc");    
2845     }
2846
2847     /* now push the calling address */
2848     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2849
2850     pushSide(IC_LEFT(ic), FPTRSIZE);
2851
2852     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2853
2854     /* if send set is not empty the assign */
2855     if (_G.sendSet) {
2856         iCode *sic ;
2857
2858         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2859              sic = setNextItem(_G.sendSet)) {
2860             int size, offset = 0;
2861             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2862             size = AOP_SIZE(IC_LEFT(sic));
2863             while (size--) {
2864                 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2865                                 FALSE,FALSE);
2866                 if (strcmp(l,fReturn[offset]))
2867                     pic16_emitcode("mov","%s,%s",
2868                              fReturn[offset],
2869                              l);
2870                 offset++;
2871             }
2872             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2873         }
2874         _G.sendSet = NULL;
2875     }
2876
2877     pic16_emitcode("ret","");
2878     pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2879
2880
2881     /* if we need assign a result value */
2882     if ((IS_ITEMP(IC_RESULT(ic)) &&
2883          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2884           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2885         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2886
2887         _G.accInUse++;
2888         pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2889         _G.accInUse--;
2890         
2891         assignResultValue(IC_RESULT(ic), 1);
2892
2893         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2894     }
2895
2896     /* adjust the stack for parameters if 
2897     required */
2898     if (ic->parmBytes) {
2899         int i;
2900         if (ic->parmBytes > 3) {
2901             pic16_emitcode("mov","a,%s",spname);
2902             pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2903             pic16_emitcode("mov","%s,a",spname);
2904         } else 
2905             for ( i = 0 ; i <  ic->parmBytes ;i++)
2906                 pic16_emitcode("dec","%s",spname);
2907
2908     }
2909
2910     /* if register bank was saved then unsave them */
2911     if (currFunc && dtype && 
2912         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2913         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2914
2915     /* if we hade saved some registers then
2916     unsave them */
2917     if (ic->regsSaved)
2918         unsaveRegisters (ic);
2919
2920 }
2921
2922 /*-----------------------------------------------------------------*/
2923 /* resultRemat - result  is rematerializable                       */
2924 /*-----------------------------------------------------------------*/
2925 static int resultRemat (iCode *ic)
2926 {
2927   //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2928   if (SKIP_IC(ic) || ic->op == IFX)
2929     return 0;
2930
2931   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2932     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2933     if (sym->remat && !POINTER_SET(ic)) 
2934       return 1;
2935   }
2936
2937   return 0;
2938 }
2939
2940 #if defined(__BORLANDC__) || defined(_MSC_VER)
2941 #define STRCASECMP stricmp
2942 #else
2943 #define STRCASECMP strcasecmp
2944 #endif
2945
2946 #if 0
2947 /*-----------------------------------------------------------------*/
2948 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2949 /*-----------------------------------------------------------------*/
2950 static bool inExcludeList(char *s)
2951 {
2952   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2953     int i =0;
2954     
2955     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2956     if (options.excludeRegs[i] &&
2957     STRCASECMP(options.excludeRegs[i],"none") == 0)
2958         return FALSE ;
2959
2960     for ( i = 0 ; options.excludeRegs[i]; i++) {
2961         if (options.excludeRegs[i] &&
2962         STRCASECMP(s,options.excludeRegs[i]) == 0)
2963             return TRUE;
2964     }
2965     return FALSE ;
2966 }
2967 #endif
2968
2969 /*-----------------------------------------------------------------*/
2970 /* genFunction - generated code for function entry                 */
2971 /*-----------------------------------------------------------------*/
2972 static void genFunction (iCode *ic)
2973 {
2974   symbol *sym;
2975   sym_link *ftype;
2976
2977         DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2978
2979         labelOffset += (max_key+4);
2980         max_key=0;
2981         GpsuedoStkPtr=0;
2982         _G.nRegsSaved = 0;
2983
2984         ftype = operandType(IC_LEFT(ic));
2985
2986         if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) {
2987                 /* create an absolute section at the interrupt vector:
2988                  * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */
2989           int ivec;
2990           symbol *asym;
2991           char asymname[128];
2992           
2993                 {
2994                   int i;
2995
2996                         sym = OP_SYMBOL( IC_LEFT(ic));
2997                         for(i=1;i<=2;i++)
2998                                 if(STRCASECMP(interrupts[i]->name, sym->name))break;
2999                         
3000                         if(i>2) {
3001                                 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3002                                         __FILE__, __LINE__, sym->name);
3003                                 exit(-1);
3004                         }
3005                         ivec = i;
3006                 }
3007                 sprintf(asymname, "ivec_%s", sym->name);
3008                 asym = newSymbol(asymname, 0);
3009                 pic16_emitcode(";","-----------------------------------------");
3010                 pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name);
3011                 pic16_emitcode(";","-----------------------------------------");
3012                 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name));
3013                 pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname ));
3014                 
3015                 pic16_pBlockConvert2Absolute(pb);
3016         }
3017
3018
3019         /* create the function header */
3020         pic16_emitcode(";","-----------------------------------------");
3021         pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
3022         pic16_emitcode(";","-----------------------------------------");
3023
3024         pic16_emitcode("","%s:",sym->rname);
3025         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3026
3027         {
3028           absSym *ab;
3029
3030                 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3031                         if(strcmp(ab->name, sym->name)) {
3032                                 pic16_pBlockConvert2Absolute(pb);
3033                                 break;
3034                         }
3035                 
3036         }
3037
3038
3039         if(IFFUNC_ISNAKED(ftype)) {
3040                 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3041                 return;
3042         }
3043         
3044         /* if critical function then turn interrupts off */
3045         if (IFFUNC_ISCRITICAL(ftype))
3046                 pic16_emitcode("clr","ea");
3047
3048         /* if this is an interrupt service routine then
3049          * save acc, b, dpl, dph  */
3050         if (IFFUNC_ISISR(sym->type)) {
3051           int i;
3052                 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH */
3053                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3054                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3055                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3056                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3057                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3058                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3059                 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3060
3061
3062 #if 0
3063                 /* VR -- this is the old code which clears STATUS register for
3064                  * the ISR routine. Why? */
3065                 pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
3066                 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
3067                 pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
3068                 pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
3069 #endif
3070
3071                 pic16_pBlockConvert2ISR(pb);
3072
3073 #if 0
3074                 if (!inExcludeList("acc"))          
3075                         pic16_emitcode ("push","acc");  
3076                 if (!inExcludeList("b"))
3077                         pic16_emitcode ("push","b");
3078                 if (!inExcludeList("dpl"))
3079                         pic16_emitcode ("push","dpl");
3080                 if (!inExcludeList("dph"))
3081                         pic16_emitcode ("push","dph");
3082 #endif
3083
3084                 /* if any registers used */
3085                 if (sym->regsUsed) {
3086                         /* save the registers used */
3087                         DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3088                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3089                                 if (bitVectBitValue(sym->regsUsed,i)) {
3090 //                                      fprintf(stderr, "%s:%d function %s uses register %s\n",
3091 //                                                      __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3092 //                                                      pic16_regWithIdx(i)->name);
3093
3094                                         pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3095                                         _G.nRegsSaved++;
3096                                 }
3097                         }
3098                 }
3099         } else {
3100                 /* emit code to setup stack frame if user enabled,
3101                  * and function is not main() */
3102          
3103 //              fprintf(stderr, "function name: %s\n", sym->name);
3104                 if(strcmp(sym->name, "main")) {
3105                         if(!options.ommitFramePtr || sym->regsUsed) {
3106                         /* setup the stack frame */
3107                                 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3108                                 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3109                                 if(STACK_MODEL_LARGE)
3110                                         pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3111                         }
3112                 }
3113
3114                 /* if callee-save to be used for this function
3115                 * then save the registers being used in this function */
3116                 if (IFFUNC_CALLEESAVES(sym->type)) {
3117                   int i;
3118             
3119 //                      fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
3120                         
3121                         /* if any registers used */
3122                         if (sym->regsUsed) {
3123                                 /* save the registers used */
3124                                 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3125                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3126                                         if (bitVectBitValue(sym->regsUsed,i)) {
3127 //                                              fprintf(stderr, "%s:%d function %s uses register %s\n",
3128 //                                                              __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3129 //                                                              pic16_regWithIdx(i)->name);
3130
3131                                                 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3132 //                                              pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3133 //                                                      PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3134 //                                                      &pic16_pc_postdec1, 0));
3135                                                 _G.nRegsSaved++;
3136                                         }
3137                                 }
3138                         }
3139                 }
3140         }
3141
3142
3143         
3144 #if 0
3145         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3146
3147                 if (options.useXstack) {
3148                         pic16_emitcode("mov","r0,%s",spname);
3149                         pic16_emitcode("mov","a,_bp");
3150                         pic16_emitcode("movx","@r0,a");
3151                         pic16_emitcode("inc","%s",spname);
3152                 } else {
3153                         /* set up the stack */
3154                         pic16_emitcode ("push","_bp");     /* save the callers stack  */
3155                 }
3156                 pic16_emitcode ("mov","_bp,%s",spname);
3157         }
3158 #endif
3159         DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3160
3161         /* adjust the stack for the function */
3162         if (sym->stack) {
3163           int i = sym->stack;
3164
3165                 if (i > 127 ) 
3166                         werror(W_STACK_OVERFLOW,sym->name);
3167
3168                 if (i > 3 && sym->recvSize < 4) {              
3169                         pic16_emitcode ("mov","a,sp");
3170                         pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3171                         pic16_emitcode ("mov","sp,a");
3172                 } else
3173                         while(i--)
3174                                 pic16_emitcode("inc","sp");
3175         }
3176
3177         if (sym->xstack) {
3178                 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3179
3180                 pic16_emitcode ("mov","a,_spx");
3181                 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3182                 pic16_emitcode ("mov","_spx,a");
3183         }
3184     
3185 }
3186
3187 /*-----------------------------------------------------------------*/
3188 /* genEndFunction - generates epilogue for functions               */
3189 /*-----------------------------------------------------------------*/
3190 static void genEndFunction (iCode *ic)
3191 {
3192     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3193
3194     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3195
3196     if(IFFUNC_ISNAKED(sym->type)) {
3197         DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3198         return;
3199     }
3200
3201 #if 0
3202     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3203     {
3204         pic16_emitcode ("mov","%s,_bp",spname);
3205     }
3206 #endif
3207
3208     /* if use external stack but some variables were
3209     added to the local stack then decrement the
3210     local stack */
3211     if (options.useXstack && sym->stack) {      
3212         pic16_emitcode("mov","a,sp");
3213         pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3214         pic16_emitcode("mov","sp,a");
3215     }
3216
3217
3218 #if 0
3219     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3220         if (options.useXstack) {
3221             pic16_emitcode("mov","r0,%s",spname);
3222             pic16_emitcode("movx","a,@r0");
3223             pic16_emitcode("mov","_bp,a");
3224             pic16_emitcode("dec","%s",spname);
3225         }
3226         else
3227         {
3228             pic16_emitcode ("pop","_bp");
3229         }
3230     }
3231 #endif
3232
3233     /* restore the register bank  */    
3234     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3235         pic16_emitcode ("pop","psw");
3236
3237         if (IFFUNC_ISISR(sym->type)) {
3238
3239                 /* now we need to restore the registers */
3240                 
3241                 /* if any registers used */
3242                 if (sym->regsUsed) {
3243                   int i;
3244
3245                         /* restore registers used */
3246                         DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3247                         for ( i = sym->regsUsed->size; i >= 0; i--) {
3248                                 if (bitVectBitValue(sym->regsUsed,i)) {
3249 //                                      fprintf(stderr, "%s:%d function %s uses register %s\n",
3250 //                                                      __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3251 //                                                      pic16_regWithIdx(i)->name);
3252         
3253                                         pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3254                                                         &pic16_pc_preinc1,
3255                                                         PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3256                                 }
3257                         }
3258                 }
3259         
3260                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3261                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3262                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3263                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3264                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3265                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3266                 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3267         
3268
3269                 /* if debug then send end of function */
3270 /*      if (options.debug && currFunc)  */
3271                 if (currFunc) {
3272                         _G.debugLine = 1;
3273                         pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3274                                         FileBaseName(ic->filename),currFunc->lastLine,
3275                                         ic->level,ic->block); 
3276                         if (IS_STATIC(currFunc->etype))     
3277                                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
3278                         else
3279                                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3280                         _G.debugLine = 0;
3281                 }
3282         
3283 #if 0
3284                 pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
3285                 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3286                 pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
3287                 pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
3288                 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3289 #endif
3290
3291                 pic16_emitpcodeNULLop(POC_RETFIE);
3292         }
3293         else {
3294                 if (IFFUNC_ISCRITICAL(sym->type))
3295                         pic16_emitcode("setb","ea");
3296         
3297         /* if any registers used */
3298         if (sym->regsUsed) {
3299           int i;
3300                 /* save the registers used */
3301                 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3302                 for ( i = sym->regsUsed->size; i >= 0; i--) {
3303                         if (bitVectBitValue(sym->regsUsed,i)) {
3304 //                              fprintf(stderr, "%s:%d function %s uses register %s\n",
3305 //                                              __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3306 //                                              pic16_regWithIdx(i)->name);
3307         
3308                                 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3309                                         &pic16_pc_preinc1,
3310                                         PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3311                         }
3312                 }
3313         }
3314         
3315
3316         /* if debug then send end of function */
3317         if (currFunc) {
3318             _G.debugLine = 1;
3319             pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3320                      FileBaseName(ic->filename),currFunc->lastLine,
3321                      ic->level,ic->block); 
3322             if (IS_STATIC(currFunc->etype))         
3323                 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
3324             else
3325                 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3326             _G.debugLine = 0;
3327         }
3328
3329         /* insert code to restore stack frame, if user enabled it
3330          * and function is not main() */
3331          
3332         if(strcmp(sym->name, "main")) {
3333                 if(!options.ommitFramePtr || sym->regsUsed) {
3334                         /* restore stack frame */
3335                         if(STACK_MODEL_LARGE)
3336                                 pic16_emitpcode(POC_MOVFF,
3337                                         pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3338                         pic16_emitpcode(POC_MOVFF,
3339                                         pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3340                 }
3341         }
3342
3343         pic16_emitcode ("return","");
3344         pic16_emitpcodeNULLop(POC_RETURN);
3345
3346         /* Mark the end of a function */
3347         pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3348     }
3349
3350 }
3351
3352
3353 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3354 {
3355 //              (AOP(left)->aopu.pcop->type == PO_DIR)?
3356
3357         if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3358                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3359                 pic16_emitpcode(POC_MOVWF, dest);
3360         } else {
3361                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3362                         pic16_popGet(AOP(op), offset), dest));
3363         }
3364 }
3365
3366 /*-----------------------------------------------------------------*/
3367 /* genRet - generate code for return statement                     */
3368 /*-----------------------------------------------------------------*/
3369 static void genRet (iCode *ic)
3370 {
3371   int size;
3372   operand *left;
3373
3374         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3375         /* if we have no return value then
3376          * just generate the "ret" */
3377         
3378         if (!IC_LEFT(ic)) 
3379                 goto jumpret;       
3380     
3381         /* we have something to return then
3382          * move the return value into place */
3383         pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3384         size = AOP_SIZE(IC_LEFT(ic));
3385
3386         if(size <= 4) {
3387                 if(size>3) {
3388                         pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3389 //                      pic16_emitpcode(POC_MOVFF,
3390 //                              pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3391                 }
3392                 if(size>2) {
3393                         pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3394 //                      pic16_emitpcode(POC_MOVFF,
3395 //                              pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3396                 }
3397                 if(size>1) {
3398                         pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3399 //                      pic16_emitpcode(POC_MOVFF,
3400 //                              pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3401                 }
3402
3403                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0));
3404
3405 //              pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg));
3406 //              pic16_emitpcode(POC_MOVFF,
3407 //                      pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3408
3409         } else {
3410                 /* >32-bits, setup stack and FSR0 */
3411                 while (size--) {
3412 //                      DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3413 //                      DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3414
3415                         pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3416
3417 //                      popaopidx(AOP(oper), size, GpseudoStkPtr);
3418                         GpsuedoStkPtr++;
3419                 }
3420                         
3421                 /* setup FSR0 */
3422                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3423                         pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3424
3425                 if(STACK_MODEL_LARGE) {
3426                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3427                                 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3428                 } else {
3429                         pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3430                 }
3431         }
3432                                 
3433 #if 0
3434         /* old code, left here for reference -- VR */    
3435         while (size--) {
3436           char *l ;
3437
3438                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3439                         /* #NOCHANGE */
3440                         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3441                         pic16_emitpcomment("push %s",l);
3442                         pushed++;
3443                 } else {
3444                         DEBUGpic16_emitcode(";", "%d", __LINE__);
3445                         l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3446                         DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);       
3447                         
3448                         if (strcmp(fReturn[offset],l)) {
3449                                 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3450                                         || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3451                                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3452                                 } else {
3453                                         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3454                                 }
3455                                 
3456                                 if(size) {
3457                                         pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3458                                 }
3459                                 offset++;
3460                         }
3461                 }
3462         }    
3463
3464         if (pushed) {
3465                 while(pushed) {
3466                         pushed--;
3467                         if (strcmp(fReturn[pushed],"a"))
3468                                 pic16_emitcode("pop",fReturn[pushed]);
3469                         else
3470                                 pic16_emitcode("pop","acc");
3471                 }
3472         }
3473 #endif
3474
3475
3476         pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3477     
3478 jumpret:
3479         /* generate a jump to the return label
3480          * if the next is not the return statement */
3481         if (!(ic->next && ic->next->op == LABEL
3482                 && IC_LABEL(ic->next) == returnLabel)) {
3483         
3484                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3485                 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3486         }
3487 }
3488
3489 /*-----------------------------------------------------------------*/
3490 /* genLabel - generates a label                                    */
3491 /*-----------------------------------------------------------------*/
3492 static void genLabel (iCode *ic)
3493 {
3494     /* special case never generate */
3495     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3496     if (IC_LABEL(ic) == entryLabel)
3497         return ;
3498
3499     pic16_emitpLabel(IC_LABEL(ic)->key);
3500     pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3501 }
3502
3503 /*-----------------------------------------------------------------*/
3504 /* genGoto - generates a goto                                      */
3505 /*-----------------------------------------------------------------*/
3506 //tsd
3507 static void genGoto (iCode *ic)
3508 {
3509   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3510   pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3511 }
3512
3513
3514 /*-----------------------------------------------------------------*/
3515 /* genMultbits :- multiplication of bits                           */
3516 /*-----------------------------------------------------------------*/
3517 static void genMultbits (operand *left, 
3518                          operand *right, 
3519                          operand *result)
3520 {
3521   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3522
3523   if(!pic16_sameRegs(AOP(result),AOP(right)))
3524     pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),0));
3525
3526   pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3527   pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3528   pic16_emitpcode(POC_BCF,  pic16_popGet(AOP(result),0));
3529
3530 }
3531
3532
3533 /*-----------------------------------------------------------------*/
3534 /* genMultOneByte : 8 bit multiplication & division                */
3535 /*-----------------------------------------------------------------*/
3536 static void genMultOneByte (operand *left,
3537                             operand *right,
3538                             operand *result)
3539 {
3540   sym_link *opetype = operandType(result);
3541
3542   // symbol *lbl ;
3543   int size,offset;
3544
3545   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3546   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3547   DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3548
3549   /* (if two literals, the value is computed before) */
3550   /* if one literal, literal on the right */
3551   if (AOP_TYPE(left) == AOP_LIT){
3552     operand *t = right;
3553     right = left;
3554     left = t;
3555   }
3556
3557   size = AOP_SIZE(result);
3558   if(size == 1) {
3559
3560     if (AOP_TYPE(right) == AOP_LIT){
3561       pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
3562                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3563                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3564                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3565     } else {
3566       pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
3567                      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3568                      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3569                      pic16_aopGet(AOP(result),0,FALSE,FALSE));
3570     }
3571     pic16_genMult8X8_8 (left, right,result);
3572   } else {  // (size > 1)
3573
3574     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3575                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
3576                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
3577                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
3578
3579     if (SPEC_USIGN(opetype)){
3580       pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3581       pic16_genUMult8X8_16 (left, right, result, NULL);
3582
3583       if (size > 2) {
3584         /* for filling the MSBs */
3585         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),2));
3586         pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),3));
3587       }
3588     }
3589     else{
3590       pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3591
3592       pic16_emitcode("mov","a,b");
3593
3594       /* adjust the MSB if left or right neg */
3595
3596       /* if one literal */
3597       if (AOP_TYPE(right) == AOP_LIT){
3598         pic16_emitcode("multiply ","right is a lit");
3599         /* AND literal negative */
3600         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3601           /* adjust MSB (c==0 after mul) */
3602           pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3603         }
3604       }
3605       else{
3606         pic16_genSMult8X8_16 (left, right, result, NULL);
3607       }
3608
3609       if(size > 2){
3610         pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3611         /* get the sign */
3612         pic16_emitcode("rlc","a");
3613         pic16_emitcode("subb","a,acc");
3614       }
3615     }
3616
3617     size -= 2;   
3618     offset = 2;
3619     if (size > 0)
3620       while (size--)
3621         pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3622     //pic16_aopPut(AOP(result),"a",offset++);
3623   }
3624 }
3625
3626 /*-----------------------------------------------------------------*/
3627 /* genMult - generates code for multiplication                     */
3628 /*-----------------------------------------------------------------*/
3629 static void genMult (iCode *ic)
3630 {
3631     operand *left = IC_LEFT(ic);
3632     operand *right = IC_RIGHT(ic);
3633     operand *result= IC_RESULT(ic);   
3634
3635     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3636     /* assign the amsops */
3637     pic16_aopOp (left,ic,FALSE);
3638     pic16_aopOp (right,ic,FALSE);
3639     pic16_aopOp (result,ic,TRUE);
3640
3641   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3642
3643     /* special cases first */
3644     /* both are bits */
3645     if (AOP_TYPE(left) == AOP_CRY &&
3646         AOP_TYPE(right)== AOP_CRY) {
3647         genMultbits(left,right,result);
3648         goto release ;
3649     }
3650
3651     /* if both are of size == 1 */
3652     if (AOP_SIZE(left) == 1 &&
3653         AOP_SIZE(right) == 1 ) {
3654         genMultOneByte(left,right,result);
3655         goto release ;
3656     }
3657
3658     pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3659
3660     /* should have been converted to function call */
3661         assert(0) ;
3662
3663 release :
3664     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3665     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3666     pic16_freeAsmop(result,NULL,ic,TRUE); 
3667 }
3668
3669 /*-----------------------------------------------------------------*/
3670 /* genDivbits :- division of bits                                  */
3671 /*-----------------------------------------------------------------*/
3672 static void genDivbits (operand *left, 
3673                         operand *right, 
3674                         operand *result)
3675 {
3676
3677     char *l;
3678
3679     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3680     /* the result must be bit */    
3681     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3682     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3683
3684     MOVA(l);    
3685
3686     pic16_emitcode("div","ab");
3687     pic16_emitcode("rrc","a");
3688     pic16_aopPut(AOP(result),"c",0);
3689 }
3690
3691 /*-----------------------------------------------------------------*/
3692 /* genDivOneByte : 8 bit division                                  */
3693 /*-----------------------------------------------------------------*/
3694 static void genDivOneByte (operand *left,
3695                            operand *right,
3696                            operand *result)
3697 {
3698     sym_link *opetype = operandType(result);
3699     char *l ;
3700     symbol *lbl ;
3701     int size,offset;
3702
3703     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3704     size = AOP_SIZE(result) - 1;
3705     offset = 1;
3706     /* signed or unsigned */
3707     if (SPEC_USIGN(opetype)) {
3708         /* unsigned is easy */
3709         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3710         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3711         MOVA(l);        
3712         pic16_emitcode("div","ab");
3713         pic16_aopPut(AOP(result),"a",0);
3714         while (size--)
3715             pic16_aopPut(AOP(result),zero,offset++);
3716         return ;
3717     }
3718
3719     /* signed is a little bit more difficult */
3720
3721     /* save the signs of the operands */
3722     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3723     MOVA(l);    
3724     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3725     pic16_emitcode("push","acc"); /* save it on the stack */
3726
3727     /* now sign adjust for both left & right */
3728     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3729     MOVA(l);       
3730     lbl = newiTempLabel(NULL);
3731     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3732     pic16_emitcode("cpl","a");   
3733     pic16_emitcode("inc","a");
3734     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3735     pic16_emitcode("mov","b,a");
3736
3737     /* sign adjust left side */
3738     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3739     MOVA(l);
3740
3741     lbl = newiTempLabel(NULL);
3742     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3743     pic16_emitcode("cpl","a");
3744     pic16_emitcode("inc","a");
3745     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3746
3747     /* now the division */
3748     pic16_emitcode("div","ab");
3749     /* we are interested in the lower order
3750     only */
3751     pic16_emitcode("mov","b,a");
3752     lbl = newiTempLabel(NULL);
3753     pic16_emitcode("pop","acc");   
3754     /* if there was an over flow we don't 
3755     adjust the sign of the result */
3756     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3757     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3758     CLRC;
3759     pic16_emitcode("clr","a");
3760     pic16_emitcode("subb","a,b");
3761     pic16_emitcode("mov","b,a");
3762     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3763
3764     /* now we are done */
3765     pic16_aopPut(AOP(result),"b",0);
3766     if(size > 0){
3767         pic16_emitcode("mov","c,b.7");
3768         pic16_emitcode("subb","a,acc");   
3769     }
3770     while (size--)
3771         pic16_aopPut(AOP(result),"a",offset++);
3772
3773 }
3774
3775 /*-----------------------------------------------------------------*/
3776 /* genDiv - generates code for division                            */
3777 /*-----------------------------------------------------------------*/
3778 static void genDiv (iCode *ic)
3779 {
3780     operand *left = IC_LEFT(ic);
3781     operand *right = IC_RIGHT(ic);
3782     operand *result= IC_RESULT(ic);   
3783
3784     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3785     /* assign the amsops */
3786     pic16_aopOp (left,ic,FALSE);
3787     pic16_aopOp (right,ic,FALSE);
3788     pic16_aopOp (result,ic,TRUE);
3789
3790     /* special cases first */
3791     /* both are bits */
3792     if (AOP_TYPE(left) == AOP_CRY &&
3793         AOP_TYPE(right)== AOP_CRY) {
3794         genDivbits(left,right,result);
3795         goto release ;
3796     }
3797
3798     /* if both are of size == 1 */
3799     if (AOP_SIZE(left) == 1 &&
3800         AOP_SIZE(right) == 1 ) {
3801         genDivOneByte(left,right,result);
3802         goto release ;
3803     }
3804
3805     /* should have been converted to function call */
3806     assert(0);
3807 release :
3808     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3809     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3810     pic16_freeAsmop(result,NULL,ic,TRUE); 
3811 }
3812
3813 /*-----------------------------------------------------------------*/
3814 /* genModbits :- modulus of bits                                   */
3815 /*-----------------------------------------------------------------*/
3816 static void genModbits (operand *left, 
3817                         operand *right, 
3818                         operand *result)
3819 {
3820
3821     char *l;
3822
3823     /* the result must be bit */    
3824     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3825     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3826
3827     MOVA(l);       
3828
3829     pic16_emitcode("div","ab");
3830     pic16_emitcode("mov","a,b");
3831     pic16_emitcode("rrc","a");
3832     pic16_aopPut(AOP(result),"c",0);
3833 }
3834
3835 /*-----------------------------------------------------------------*/
3836 /* genModOneByte : 8 bit modulus                                   */
3837 /*-----------------------------------------------------------------*/
3838 static void genModOneByte (operand *left,
3839                            operand *right,
3840                            operand *result)
3841 {
3842     sym_link *opetype = operandType(result);
3843     char *l ;
3844     symbol *lbl ;
3845
3846     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3847     /* signed or unsigned */
3848     if (SPEC_USIGN(opetype)) {
3849         /* unsigned is easy */
3850         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3851         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3852         MOVA(l);    
3853         pic16_emitcode("div","ab");
3854         pic16_aopPut(AOP(result),"b",0);
3855         return ;
3856     }
3857
3858     /* signed is a little bit more difficult */
3859
3860     /* save the signs of the operands */
3861     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3862     MOVA(l);
3863
3864     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3865     pic16_emitcode("push","acc"); /* save it on the stack */
3866
3867     /* now sign adjust for both left & right */
3868     l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
3869     MOVA(l);
3870
3871     lbl = newiTempLabel(NULL);
3872     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3873     pic16_emitcode("cpl","a");   
3874     pic16_emitcode("inc","a");
3875     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3876     pic16_emitcode("mov","b,a"); 
3877
3878     /* sign adjust left side */
3879     l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
3880     MOVA(l);
3881
3882     lbl = newiTempLabel(NULL);
3883     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3884     pic16_emitcode("cpl","a");   
3885     pic16_emitcode("inc","a");
3886     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3887
3888     /* now the multiplication */
3889     pic16_emitcode("div","ab");
3890     /* we are interested in the lower order
3891     only */
3892     lbl = newiTempLabel(NULL);
3893     pic16_emitcode("pop","acc");   
3894     /* if there was an over flow we don't 
3895     adjust the sign of the result */
3896     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3897     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3898     CLRC ;
3899     pic16_emitcode("clr","a");
3900     pic16_emitcode("subb","a,b");
3901     pic16_emitcode("mov","b,a");
3902     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3903
3904     /* now we are done */
3905     pic16_aopPut(AOP(result),"b",0);
3906
3907 }
3908
3909 /*-----------------------------------------------------------------*/
3910 /* genMod - generates code for division                            */
3911 /*-----------------------------------------------------------------*/
3912 static void genMod (iCode *ic)
3913 {
3914     operand *left = IC_LEFT(ic);
3915     operand *right = IC_RIGHT(ic);
3916     operand *result= IC_RESULT(ic);  
3917
3918     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3919     /* assign the amsops */
3920     pic16_aopOp (left,ic,FALSE);
3921     pic16_aopOp (right,ic,FALSE);
3922     pic16_aopOp (result,ic,TRUE);
3923
3924     /* special cases first */
3925     /* both are bits */
3926     if (AOP_TYPE(left) == AOP_CRY &&
3927         AOP_TYPE(right)== AOP_CRY) {
3928         genModbits(left,right,result);
3929         goto release ;
3930     }
3931
3932     /* if both are of size == 1 */
3933     if (AOP_SIZE(left) == 1 &&
3934         AOP_SIZE(right) == 1 ) {
3935         genModOneByte(left,right,result);
3936         goto release ;
3937     }
3938
3939     /* should have been converted to function call */
3940     assert(0);
3941
3942 release :
3943     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3944     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3945     pic16_freeAsmop(result,NULL,ic,TRUE); 
3946 }
3947
3948 /*-----------------------------------------------------------------*/
3949 /* genIfxJump :- will create a jump depending on the ifx           */
3950 /*-----------------------------------------------------------------*/
3951 /*
3952   note: May need to add parameter to indicate when a variable is in bit space.
3953 */
3954 static void genIfxJump (iCode *ic, char *jval)
3955 {
3956
3957     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3958     /* if true label then we jump if condition
3959     supplied is true */
3960     if ( IC_TRUE(ic) ) {
3961
3962         if(strcmp(jval,"a") == 0)
3963           emitSKPZ;
3964         else if (strcmp(jval,"c") == 0)
3965           emitSKPC;
3966         else {
3967           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3968           pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1));
3969         }
3970
3971         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3972         pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3973
3974     }
3975     else {
3976         /* false label is present */
3977         if(strcmp(jval,"a") == 0)
3978           emitSKPNZ;
3979         else if (strcmp(jval,"c") == 0)
3980           emitSKPNC;
3981         else {
3982           DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3983           pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1));
3984         }
3985
3986         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3987         pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3988
3989     }
3990
3991
3992     /* mark the icode as generated */
3993     ic->generated = 1;
3994 }
3995
3996 /*-----------------------------------------------------------------*/
3997 /* genSkip                                                         */
3998 /*-----------------------------------------------------------------*/
3999 static void genSkip(iCode *ifx,int status_bit)
4000 {
4001   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4002   if(!ifx)
4003     return;
4004
4005   if ( IC_TRUE(ifx) ) {
4006     switch(status_bit) {
4007     case 'z':
4008       emitSKPNZ;
4009       break;
4010
4011     case 'c':
4012       emitSKPNC;
4013       break;
4014
4015     case 'd':
4016       emitSKPDC;
4017       break;
4018
4019     }
4020
4021     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4022     // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4023
4024   } else {
4025
4026     switch(status_bit) {
4027
4028     case 'z':
4029       emitSKPZ;
4030       break;
4031
4032     case 'c':
4033       emitSKPC;
4034       break;
4035
4036     case 'd':
4037       emitSKPDC;
4038       break;
4039     }
4040     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4041     // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4042
4043   }
4044
4045 }
4046
4047 /*-----------------------------------------------------------------*/
4048 /* genSkipc                                                        */
4049 /*-----------------------------------------------------------------*/
4050 static void genSkipc(resolvedIfx *rifx)
4051 {
4052   if(!rifx)
4053     return;
4054
4055   if(rifx->condition)
4056     emitSKPC;
4057   else
4058     emitSKPNC;
4059
4060   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4061   rifx->generated = 1;
4062 }
4063
4064 /*-----------------------------------------------------------------*/
4065 /* genSkipz2                                                       */
4066 /*-----------------------------------------------------------------*/
4067 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4068 {
4069   if(!rifx)
4070     return;
4071
4072   if( (rifx->condition ^ invert_condition) & 1)
4073     emitSKPZ;
4074   else
4075     emitSKPNZ;
4076
4077   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4078   rifx->generated = 1;
4079 }
4080
4081 #if 0
4082 /*-----------------------------------------------------------------*/
4083 /* genSkipz                                                        */
4084 /*-----------------------------------------------------------------*/
4085 static void genSkipz(iCode *ifx, int condition)
4086 {
4087   if(!ifx)
4088     return;
4089
4090   if(condition)
4091     emitSKPNZ;
4092   else
4093     emitSKPZ;
4094
4095   if ( IC_TRUE(ifx) )
4096     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4097   else
4098     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4099
4100   if ( IC_TRUE(ifx) )
4101     pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4102   else
4103     pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4104
4105 }
4106 #endif
4107
4108 /*-----------------------------------------------------------------*/
4109 /* genSkipCond                                                     */
4110 /*-----------------------------------------------------------------*/
4111 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4112 {
4113   if(!rifx)
4114     return;
4115
4116   if(rifx->condition)
4117     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4118   else
4119     pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4120
4121
4122   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4123   rifx->generated = 1;
4124 }
4125
4126 #if 0
4127 /*-----------------------------------------------------------------*/
4128 /* genChkZeroes :- greater or less than comparison                 */
4129 /*     For each byte in a literal that is zero, inclusive or the   */
4130 /*     the corresponding byte in the operand with W                */
4131 /*     returns true if any of the bytes are zero                   */
4132 /*-----------------------------------------------------------------*/
4133 static int genChkZeroes(operand *op, int lit,  int size)
4134 {
4135
4136   int i;
4137   int flag =1;
4138
4139   while(size--) {
4140     i = (lit >> (size*8)) & 0xff;
4141
4142     if(i==0) {
4143       if(flag) 
4144         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4145       else
4146         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4147       flag = 0;
4148     }
4149   }
4150
4151   return (flag==0);
4152 }
4153 #endif
4154
4155 /*-----------------------------------------------------------------*/
4156 /* genCmp :- greater or less than comparison                       */
4157 /*-----------------------------------------------------------------*/
4158 static void genCmp (operand *left,operand *right,
4159                     operand *result, iCode *ifx, int sign)
4160 {
4161   int size; //, offset = 0 ;
4162   unsigned long lit = 0L,i = 0;
4163   resolvedIfx rFalseIfx;
4164   //  resolvedIfx rTrueIfx;
4165   symbol *truelbl;
4166   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4167 /*
4168   if(ifx) {
4169     DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4170     DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4171   }
4172 */
4173
4174   resolveIfx(&rFalseIfx,ifx);
4175   truelbl  = newiTempLabel(NULL);
4176   size = max(AOP_SIZE(left),AOP_SIZE(right));
4177
4178   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4179
4180 #define _swapp
4181
4182   /* if literal is on the right then swap with left */
4183   if ((AOP_TYPE(right) == AOP_LIT)) {
4184     operand *tmp = right ;
4185     unsigned long mask = (0x100 << (8*(size-1))) - 1;
4186     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4187 #ifdef _swapp
4188
4189     lit = (lit - 1) & mask;
4190     right = left;
4191     left = tmp;
4192     rFalseIfx.condition ^= 1;
4193 #endif
4194
4195   } else if ((AOP_TYPE(left) == AOP_LIT)) {
4196     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4197   }
4198
4199
4200   //if(IC_TRUE(ifx) == NULL)
4201   /* if left & right are bit variables */
4202   if (AOP_TYPE(left) == AOP_CRY &&
4203       AOP_TYPE(right) == AOP_CRY ) {
4204     pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4205     pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4206   } else {
4207     /* subtract right from left if at the
4208        end the carry flag is set then we know that
4209        left is greater than right */
4210
4211     //    {
4212
4213     symbol *lbl  = newiTempLabel(NULL);
4214
4215 #ifndef _swapp
4216     if(AOP_TYPE(right) == AOP_LIT) {
4217
4218       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4219
4220       DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4221
4222       /* special cases */
4223
4224       if(lit == 0) {
4225
4226         if(sign != 0) 
4227           genSkipCond(&rFalseIfx,left,size-1,7);
4228         else 
4229           /* no need to compare to 0...*/
4230           /* NOTE: this is a de-generate compare that most certainly 
4231            *       creates some dead code. */
4232           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4233
4234         if(ifx) ifx->generated = 1;
4235         return;
4236
4237       }
4238       size--;
4239
4240       if(size == 0) {
4241         //i = (lit >> (size*8)) & 0xff;
4242         DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4243         
4244         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4245
4246         i = ((0-lit) & 0xff);
4247         if(sign) {
4248           if( i == 0x81) { 
4249             /* lit is 0x7f, all signed chars are less than
4250              * this except for 0x7f itself */
4251             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4252             genSkipz2(&rFalseIfx,0);
4253           } else {
4254             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4255             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4256             genSkipc(&rFalseIfx);
4257           }
4258
4259         } else {
4260           if(lit == 1) {
4261             genSkipz2(&rFalseIfx,1);
4262           } else {
4263             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4264             genSkipc(&rFalseIfx);
4265           }
4266         }
4267
4268         if(ifx) ifx->generated = 1;
4269         return;
4270       }
4271
4272       /* chars are out of the way. now do ints and longs */
4273
4274
4275       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4276         
4277       /* special cases */
4278
4279       if(sign) {
4280
4281         if(lit == 0) {
4282           genSkipCond(&rFalseIfx,left,size,7);
4283           if(ifx) ifx->generated = 1;
4284           return;
4285         }
4286
4287         if(lit <0x100) {
4288           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4289
4290           //rFalseIfx.condition ^= 1;
4291           //genSkipCond(&rFalseIfx,left,size,7);
4292           //rFalseIfx.condition ^= 1;
4293
4294           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4295           if(rFalseIfx.condition)
4296             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4297           else
4298             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4299
4300           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4301           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4302           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4303
4304           while(size > 1)
4305             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4306
4307           if(rFalseIfx.condition) {
4308             emitSKPZ;
4309             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4310
4311           } else {
4312             emitSKPNZ;
4313           }
4314
4315           genSkipc(&rFalseIfx);
4316           pic16_emitpLabel(truelbl->key);
4317           if(ifx) ifx->generated = 1;
4318           return;
4319
4320         }
4321
4322         if(size == 1) {
4323
4324           if( (lit & 0xff) == 0) {
4325             /* lower byte is zero */
4326             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4327             i = ((lit >> 8) & 0xff) ^0x80;
4328             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4329             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4330             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4331             genSkipc(&rFalseIfx);
4332
4333
4334             if(ifx) ifx->generated = 1;
4335             return;
4336
4337           }
4338         } else {
4339           /* Special cases for signed longs */
4340           if( (lit & 0xffffff) == 0) {
4341             /* lower byte is zero */
4342             DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4343             i = ((lit >> 8*3) & 0xff) ^0x80;
4344             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4345             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4346             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4347             genSkipc(&rFalseIfx);
4348
4349
4350             if(ifx) ifx->generated = 1;
4351             return;
4352
4353           }
4354
4355         }
4356
4357
4358         if(lit & (0x80 << (size*8))) {
4359           /* lit is negative */
4360           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4361
4362           //genSkipCond(&rFalseIfx,left,size,7);
4363
4364           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4365
4366           if(rFalseIfx.condition)
4367             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4368           else
4369             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4370
4371
4372         } else {
4373           /* lit is positive */
4374           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4375           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4376           if(rFalseIfx.condition)
4377             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4378           else
4379             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4380
4381         }
4382
4383         /*
4384           This works, but is only good for ints.
4385           It also requires a "known zero" register.
4386           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4387           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4388           pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
4389           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4390           pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4391           genSkipc(&rFalseIfx);
4392
4393           pic16_emitpLabel(truelbl->key);
4394           if(ifx) ifx->generated = 1;
4395           return;
4396         **/
4397           
4398         /* There are no more special cases, so perform a general compare */
4399   
4400         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4401         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4402
4403         while(size--) {
4404
4405           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4406           emitSKPNZ;
4407           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4408         }
4409         //rFalseIfx.condition ^= 1;
4410         genSkipc(&rFalseIfx);
4411
4412         pic16_emitpLabel(truelbl->key);
4413
4414         if(ifx) ifx->generated = 1;
4415         return;
4416
4417
4418       }
4419
4420
4421       /* sign is out of the way. So now do an unsigned compare */
4422       DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4423
4424
4425       /* General case - compare to an unsigned literal on the right.*/
4426
4427       i = (lit >> (size*8)) & 0xff;
4428       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4429       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4430       while(size--) {
4431         i = (lit >> (size*8)) & 0xff;
4432
4433         if(i) {
4434           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4435           emitSKPNZ;
4436           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4437         } else {
4438           /* this byte of the lit is zero, 
4439            *if it's not the last then OR in the variable */
4440           if(size)
4441             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4442         }
4443       }
4444
4445
4446       pic16_emitpLabel(lbl->key);
4447       //if(emitFinalCheck)
4448       genSkipc(&rFalseIfx);
4449       if(sign)
4450         pic16_emitpLabel(truelbl->key);
4451
4452       if(ifx) ifx->generated = 1;
4453       return;
4454
4455
4456     }
4457 #endif  // _swapp
4458
4459     if(AOP_TYPE(left) == AOP_LIT) {
4460       //symbol *lbl = newiTempLabel(NULL);
4461
4462       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4463
4464
4465       DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4466
4467       /* Special cases */
4468       if((lit == 0) && (sign == 0)){
4469
4470         size--;
4471         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4472         while(size) 
4473           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4474
4475         genSkipz2(&rFalseIfx,0);
4476         if(ifx) ifx->generated = 1;
4477         return;
4478       }
4479
4480       if(size==1) {
4481         /* Special cases */
4482         lit &= 0xff;
4483         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4484           /* degenerate compare can never be true */
4485           if(rFalseIfx.condition == 0)
4486             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4487
4488           if(ifx) ifx->generated = 1;
4489           return;
4490         }
4491
4492         if(sign) {
4493           /* signed comparisons to a literal byte */
4494
4495           int lp1 = (lit+1) & 0xff;
4496
4497           DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4498           switch (lp1) {
4499           case 0:
4500             rFalseIfx.condition ^= 1;
4501             genSkipCond(&rFalseIfx,right,0,7);
4502             break;
4503           case 0x7f:
4504             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4505             pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4506             genSkipz2(&rFalseIfx,1);
4507             break;
4508           default:
4509             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4510             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4511             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4512             rFalseIfx.condition ^= 1;
4513             genSkipc(&rFalseIfx);
4514             break;
4515           }
4516         } else {
4517           /* unsigned comparisons to a literal byte */
4518
4519           switch(lit & 0xff ) {
4520           case 0:
4521             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4522             genSkipz2(&rFalseIfx,0);
4523             break;
4524           case 0x7f:
4525             rFalseIfx.condition ^= 1;
4526             genSkipCond(&rFalseIfx,right,0,7);
4527             break;
4528
4529           default:
4530             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4531             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4532             DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4533             rFalseIfx.condition ^= 1;
4534             if (AOP_TYPE(result) == AOP_CRY)
4535               genSkipc(&rFalseIfx);
4536             else {
4537               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4538               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4539             }         
4540             break;
4541           }
4542         }
4543
4544         if(ifx) ifx->generated = 1;
4545         //goto check_carry;
4546         return;
4547
4548       } else {
4549
4550         /* Size is greater than 1 */
4551
4552         if(sign) {
4553           int lp1 = lit+1;
4554
4555           size--;
4556
4557           if(lp1 == 0) {
4558             /* this means lit = 0xffffffff, or -1 */
4559
4560
4561             DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4562             rFalseIfx.condition ^= 1;
4563             genSkipCond(&rFalseIfx,right,size,7);
4564             if(ifx) ifx->generated = 1;
4565             return;
4566           }
4567
4568           if(lit == 0) {
4569             int s = size;
4570
4571             if(rFalseIfx.condition) {
4572               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4573               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4574             }
4575
4576             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4577             while(size--)
4578               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4579
4580
4581             emitSKPZ;
4582             if(rFalseIfx.condition) {
4583               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4584               pic16_emitpLabel(truelbl->key);
4585             }else {
4586               rFalseIfx.condition ^= 1;
4587               genSkipCond(&rFalseIfx,right,s,7);
4588             }
4589
4590             if(ifx) ifx->generated = 1;
4591             return;
4592           }
4593
4594           if((size == 1) &&  (0 == (lp1&0xff))) {
4595             /* lower byte of signed word is zero */
4596             DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4597             i = ((lp1 >> 8) & 0xff) ^0x80;
4598             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4599             pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4600             pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4601             rFalseIfx.condition ^= 1;
4602             genSkipc(&rFalseIfx);
4603
4604
4605             if(ifx) ifx->generated = 1;
4606             return;
4607           }
4608
4609           if(lit & (0x80 << (size*8))) {
4610             /* Lit is less than zero */
4611             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4612             //rFalseIfx.condition ^= 1;
4613             //genSkipCond(&rFalseIfx,left,size,7);
4614             //rFalseIfx.condition ^= 1;
4615             pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4616             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4617
4618             if(rFalseIfx.condition)
4619               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4620             else
4621               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4622
4623
4624           } else {
4625             /* Lit is greater than or equal to zero */
4626             DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4627             //rFalseIfx.condition ^= 1;
4628             //genSkipCond(&rFalseIfx,right,size,7);
4629             //rFalseIfx.condition ^= 1;
4630
4631             //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4632             //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4633
4634             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4635             if(rFalseIfx.condition)
4636               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4637             else
4638               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4639
4640           }
4641
4642
4643           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4644           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4645
4646           while(size--) {
4647
4648             pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4649             emitSKPNZ;
4650             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4651           }
4652           rFalseIfx.condition ^= 1;
4653           //rFalseIfx.condition = 1;
4654           genSkipc(&rFalseIfx);
4655
4656           pic16_emitpLabel(truelbl->key);
4657
4658           if(ifx) ifx->generated = 1;
4659           return;
4660           // end of if (sign)
4661         } else {
4662
4663           /* compare word or long to an unsigned literal on the right.*/
4664
4665
4666           size--;
4667           if(lit < 0xff) {
4668             DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4669             switch (lit) {
4670             case 0:
4671               break; /* handled above */
4672 /*
4673             case 0xff:
4674               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4675               while(size--)
4676                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4677               genSkipz2(&rFalseIfx,0);
4678               break;
4679 */
4680             default:
4681               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4682               while(--size)
4683                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4684
4685               emitSKPZ;
4686               if(rFalseIfx.condition)
4687                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
4688               else
4689                 pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
4690
4691
4692               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4693               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4694
4695               rFalseIfx.condition ^= 1;
4696               genSkipc(&rFalseIfx);
4697             }
4698
4699             pic16_emitpLabel(truelbl->key);
4700
4701             if(ifx) ifx->generated = 1;
4702             return;
4703           }
4704
4705
4706           lit++;
4707           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4708           i = (lit >> (size*8)) & 0xff;
4709
4710           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4711           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4712
4713           while(size--) {
4714             i = (lit >> (size*8)) & 0xff;
4715
4716             if(i) {
4717               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4718               emitSKPNZ;
4719               pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4720             } else {
4721               /* this byte of the lit is zero, 
4722                *if it's not the last then OR in the variable */
4723               if(size)
4724                 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4725             }
4726           }
4727
4728
4729           pic16_emitpLabel(lbl->key);
4730
4731           rFalseIfx.condition ^= 1;
4732           genSkipc(&rFalseIfx);
4733         }
4734
4735         if(sign)
4736           pic16_emitpLabel(truelbl->key);
4737         if(ifx) ifx->generated = 1;
4738         return;
4739       }
4740     }
4741     /* Compare two variables */
4742
4743     DEBUGpic16_emitcode(";sign","%d",sign);
4744
4745     size--;
4746     if(sign) {
4747       /* Sigh. thus sucks... */
4748       if(size) {
4749         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4750         pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4751         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4752         pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4753         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4754         pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4755       } else {
4756         /* Signed char comparison */
4757         /* Special thanks to Nikolai Golovchenko for this snippet */
4758         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4759         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4760         pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
4761         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4762         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4763         pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4764
4765         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4766         genSkipc(&rFalseIfx);
4767           
4768         if(ifx) ifx->generated = 1;
4769         return;
4770       }
4771
4772     } else {
4773
4774       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4775       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4776     }
4777
4778
4779     /* The rest of the bytes of a multi-byte compare */
4780     while (size) {
4781
4782       emitSKPZ;
4783       pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
4784       size--;
4785
4786       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4787       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4788
4789
4790     }
4791
4792     pic16_emitpLabel(lbl->key);
4793
4794     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4795     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4796         (AOP_TYPE(result) == AOP_REG)) {
4797       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4798       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4799     } else {
4800       genSkipc(&rFalseIfx);
4801     }         
4802     //genSkipc(&rFalseIfx);
4803     if(ifx) ifx->generated = 1;
4804
4805     return;
4806
4807   }
4808
4809   // check_carry:
4810   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4811     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4812     pic16_outBitC(result);
4813   } else {
4814     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4815     /* if the result is used in the next
4816        ifx conditional branch then generate
4817        code a little differently */
4818     if (ifx )
4819       genIfxJump (ifx,"c");
4820     else
4821       pic16_outBitC(result);
4822     /* leave the result in acc */
4823   }
4824
4825 }
4826
4827 /*-----------------------------------------------------------------*/
4828 /* genCmpGt :- greater than comparison                             */
4829 /*-----------------------------------------------------------------*/
4830 static void genCmpGt (iCode *ic, iCode *ifx)
4831 {
4832     operand *left, *right, *result;
4833     sym_link *letype , *retype;
4834     int sign ;
4835
4836     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4837     left = IC_LEFT(ic);
4838     right= IC_RIGHT(ic);
4839     result = IC_RESULT(ic);
4840
4841     letype = getSpec(operandType(left));
4842     retype =getSpec(operandType(right));
4843     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4844     /* assign the amsops */
4845     pic16_aopOp (left,ic,FALSE);
4846     pic16_aopOp (right,ic,FALSE);
4847     pic16_aopOp (result,ic,TRUE);
4848
4849     genCmp(right, left, result, ifx, sign);
4850
4851     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4852     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4853     pic16_freeAsmop(result,NULL,ic,TRUE); 
4854 }
4855
4856 /*-----------------------------------------------------------------*/
4857 /* genCmpLt - less than comparisons                                */
4858 /*-----------------------------------------------------------------*/
4859 static void genCmpLt (iCode *ic, iCode *ifx)
4860 {
4861     operand *left, *right, *result;
4862     sym_link *letype , *retype;
4863     int sign ;
4864
4865     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4866     left = IC_LEFT(ic);
4867     right= IC_RIGHT(ic);
4868     result = IC_RESULT(ic);
4869
4870     letype = getSpec(operandType(left));
4871     retype =getSpec(operandType(right));
4872     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4873
4874     /* assign the amsops */
4875     pic16_aopOp (left,ic,FALSE);
4876     pic16_aopOp (right,ic,FALSE);
4877     pic16_aopOp (result,ic,TRUE);
4878
4879     genCmp(left, right, result, ifx, sign);
4880
4881     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4882     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4883     pic16_freeAsmop(result,NULL,ic,TRUE); 
4884 }
4885
4886 /*-----------------------------------------------------------------*/
4887 /* genc16bit2lit - compare a 16 bit value to a literal             */
4888 /*-----------------------------------------------------------------*/
4889 static void genc16bit2lit(operand *op, int lit, int offset)
4890 {
4891   int i;
4892
4893   DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4894   if( (lit&0xff) == 0) 
4895     i=1;
4896   else
4897     i=0;
4898
4899   switch( BYTEofLONG(lit,i)) { 
4900   case 0:
4901     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4902     break;
4903   case 1:
4904     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4905     break;
4906   case 0xff:
4907     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4908     break;
4909   default:
4910     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4911     pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4912   }
4913
4914   i ^= 1;
4915
4916   switch( BYTEofLONG(lit,i)) { 
4917   case 0:
4918     pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4919     break;
4920   case 1:
4921     emitSKPNZ;
4922     pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4923     break;
4924   case 0xff:
4925     emitSKPNZ;
4926     pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4927     break;
4928   default:
4929     pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4930     emitSKPNZ;
4931     pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4932
4933   }
4934
4935 }
4936
4937 /*-----------------------------------------------------------------*/
4938 /* gencjneshort - compare and jump if not equal                    */
4939 /*-----------------------------------------------------------------*/
4940 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4941 {
4942   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4943   int offset = 0;
4944   int res_offset = 0;  /* the result may be a different size then left or right */
4945   int res_size = AOP_SIZE(result);
4946   resolvedIfx rIfx;
4947   symbol *lbl;
4948
4949   unsigned long lit = 0L;
4950   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4951   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4952   if(result)
4953     DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4954   resolveIfx(&rIfx,ifx);
4955   lbl =  newiTempLabel(NULL);
4956
4957
4958   /* if the left side is a literal or 
4959      if the right is in a pointer register and left 
4960      is not */
4961   if ((AOP_TYPE(left) == AOP_LIT) || 
4962       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4963     operand *t = right;
4964     right = left;
4965     left = t;
4966   }
4967   if(AOP_TYPE(right) == AOP_LIT)
4968     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4969
4970   /* if the right side is a literal then anything goes */
4971   if (AOP_TYPE(right) == AOP_LIT &&
4972       AOP_TYPE(left) != AOP_DIR ) {
4973     switch(size) {
4974     case 2:
4975       genc16bit2lit(left, lit, 0);
4976       emitSKPNZ;
4977       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4978       break;
4979     default:
4980       while (size--) {
4981         if(lit & 0xff) {
4982           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4983           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4984         } else {
4985           pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4986         }
4987
4988         emitSKPNZ;
4989         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4990         offset++;
4991         if(res_offset < res_size-1)
4992           res_offset++;
4993         lit >>= 8;
4994       }
4995       break;
4996     }
4997   }
4998
4999   /* if the right side is in a register or in direct space or
5000      if the left is a pointer register & right is not */    
5001   else if (AOP_TYPE(right) == AOP_REG ||
5002            AOP_TYPE(right) == AOP_DIR || 
5003            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5004            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5005     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5006     int lbl_key = lbl->key;
5007
5008     if(result) {
5009       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5010       //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5011     }else {
5012       DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
5013       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
5014               __FUNCTION__,__LINE__);
5015       return;
5016     }
5017
5018 /*     switch(size) { */
5019 /*     case 2: */
5020 /*       genc16bit2lit(left, lit, 0); */
5021 /*       emitSKPNZ; */
5022 /*       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5023 /*       break; */
5024 /*     default: */
5025     while (size--) {
5026       int emit_skip=1;
5027       if((AOP_TYPE(left) == AOP_DIR) && 
5028          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5029
5030         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5031         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5032
5033       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5034             
5035         switch (lit & 0xff) {
5036         case 0:
5037           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5038           break;
5039         case 1:
5040           pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5041           pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5042           //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5043           emit_skip=0;
5044           break;
5045         case 0xff:
5046           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5047           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5048           //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5049           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5050           emit_skip=0;
5051           break;
5052         default:
5053           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5054           pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5055         }
5056         lit >>= 8;
5057
5058       } else {
5059         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5060       }
5061       if(emit_skip) {
5062         if(AOP_TYPE(result) == AOP_CRY) {
5063           pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
5064           if(rIfx.condition)
5065             emitSKPNZ;
5066           else
5067             emitSKPZ;
5068           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5069         } else {
5070           /* fix me. probably need to check result size too */
5071           //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5072           if(rIfx.condition)
5073             emitSKPZ;
5074           else
5075             emitSKPNZ;
5076           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5077           //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5078         }
5079         if(ifx)
5080           ifx->generated=1;
5081       }
5082       emit_skip++;
5083       offset++;
5084       if(res_offset < res_size-1)
5085         res_offset++;
5086     }
5087 /*       break; */
5088 /*     } */
5089   } else if(AOP_TYPE(right) == AOP_REG &&
5090             AOP_TYPE(left) != AOP_DIR){
5091
5092     while(size--) {
5093       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5094       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5095       pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
5096       if(rIfx.condition)
5097         emitSKPNZ;
5098       else
5099         emitSKPZ;
5100       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5101       offset++;
5102       if(res_offset < res_size-1)
5103         res_offset++;
5104     }
5105       
5106   }else{
5107     /* right is a pointer reg need both a & b */
5108     while(size--) {
5109       char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5110       if(strcmp(l,"b"))
5111         pic16_emitcode("mov","b,%s",l);
5112       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5113       pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
5114       offset++;
5115     }
5116   }
5117
5118   pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5119   if(!rIfx.condition)
5120     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5121
5122   pic16_emitpLabel(lbl->key);
5123
5124   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5125
5126   if(ifx)
5127     ifx->generated = 1;
5128 }
5129
5130 #if 0
5131 /*-----------------------------------------------------------------*/
5132 /* gencjne - compare and jump if not equal                         */
5133 /*-----------------------------------------------------------------*/
5134 static void gencjne(operand *left, operand *right, iCode *ifx)
5135 {
5136     symbol *tlbl  = newiTempLabel(NULL);
5137
5138     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5139     gencjneshort(left, right, lbl);
5140
5141     pic16_emitcode("mov","a,%s",one);
5142     pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5143     pic16_emitcode("","%05d_DS_:",lbl->key+100);
5144     pic16_emitcode("clr","a");
5145     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5146
5147     pic16_emitpLabel(lbl->key);
5148     pic16_emitpLabel(tlbl->key);
5149
5150 }
5151 #endif
5152
5153 /*-----------------------------------------------------------------*/
5154 /* genCmpEq - generates code for equal to                          */
5155 /*-----------------------------------------------------------------*/
5156 static void genCmpEq (iCode *ic, iCode *ifx)
5157 {
5158     operand *left, *right, *result;
5159     unsigned long lit = 0L;
5160     int size,offset=0;
5161     symbol *falselbl  = newiTempLabel(NULL);
5162
5163
5164     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5165
5166     if(ifx)
5167       DEBUGpic16_emitcode ("; ifx is non-null","");
5168     else
5169       DEBUGpic16_emitcode ("; ifx is null","");
5170
5171     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5172     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5173     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5174
5175     size = max(AOP_SIZE(left),AOP_SIZE(right));
5176
5177     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5178
5179     /* if literal, literal on the right or 
5180     if the right is in a pointer register and left 
5181     is not */
5182     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
5183         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5184       operand *tmp = right ;
5185       right = left;
5186       left = tmp;
5187     }
5188
5189
5190     if(ifx && !AOP_SIZE(result)){
5191         symbol *tlbl;
5192         DEBUGpic16_emitcode ("; ***","%s  %d CASE 1",__FUNCTION__,__LINE__);
5193         /* if they are both bit variables */
5194         if (AOP_TYPE(left) == AOP_CRY &&
5195             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5196                 DEBUGpic16_emitcode ("; ***","%s  %d CASE 11",__FUNCTION__,__LINE__);
5197             if(AOP_TYPE(right) == AOP_LIT){
5198                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5199                 if(lit == 0L){
5200                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5201                     pic16_emitcode("cpl","c");
5202                 } else if(lit == 1L) {
5203                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5204                 } else {
5205                     pic16_emitcode("clr","c");
5206                 }
5207                 /* AOP_TYPE(right) == AOP_CRY */
5208             } else {
5209                 symbol *lbl = newiTempLabel(NULL);
5210                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211                 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5212                 pic16_emitcode("cpl","c");
5213                 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5214             }
5215             /* if true label then we jump if condition
5216             supplied is true */
5217             tlbl = newiTempLabel(NULL);
5218             if ( IC_TRUE(ifx) ) {
5219                 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5220                 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5221             } else {
5222                 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5223                 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5224             }
5225             pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5226
5227                 {
5228                 /* left and right are both bit variables, result is carry */
5229                         resolvedIfx rIfx;
5230               
5231                         resolveIfx(&rIfx,ifx);
5232
5233                         pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5234                         pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5235                         pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5236                         pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5237                         genSkipz2(&rIfx,0);
5238                 }
5239         } else {
5240
5241                         DEBUGpic16_emitcode ("; ***","%s  %d CASE 12",__FUNCTION__,__LINE__);
5242
5243                         /* They're not both bit variables. Is the right a literal? */
5244                         if(AOP_TYPE(right) == AOP_LIT) {
5245                         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5246             
5247                         switch(size) {
5248
5249                                 case 1:
5250                                         switch(lit & 0xff) {
5251                                                 case 1:
5252                                                                 if ( IC_TRUE(ifx) ) {
5253                                                                         pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5254                                                                         emitSKPNZ;
5255                                                                         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5256                                                                 } else {
5257                                                                         pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5258                                                                         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5259                                                                 }
5260                                                                 break;
5261                                                 case 0xff:
5262                                                                 if ( IC_TRUE(ifx) ) {
5263                                                                         pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5264                                                                         emitSKPNZ;
5265                                                                         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5266                                                                 } else {
5267                                                                         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5268                                                                         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5269                                                                 }
5270                                                                 break;
5271                                                 default:
5272                                                                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5273                                                                 if(lit)
5274                                                                         pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5275                                                                 genSkip(ifx,'z');
5276                                         } // switch lit
5277
5278
5279                                         /* end of size == 1 */
5280                                         break;
5281               
5282                                 case 2:
5283                                         genc16bit2lit(left,lit,offset);
5284                                         genSkip(ifx,'z');
5285                                         break;
5286                                         /* end of size == 2 */
5287
5288                                 default:
5289                                         /* size is 4 */
5290                                         if(lit==0) {
5291                                                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5292                                                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5293                                                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5294                                                 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5295                                                 genSkip(ifx,'z');
5296                                         } else {
5297                                                 /* search for patterns that can be optimized */
5298
5299                                                 genc16bit2lit(left,lit,0);
5300                                                 lit >>= 16;
5301                                                 if(lit) {
5302                                                                 if(IC_TRUE(ifx))
5303                                                                 emitSKPZ; // if hi word unequal
5304                                                                 else
5305                                                                 emitSKPNZ; // if hi word equal
5306                                                                 // fail early
5307                                                         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5308                                                         genc16bit2lit(left,lit,2);
5309                                                         genSkip(ifx,'z');
5310                                                 } else {
5311                                                         pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5312                                                         pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5313                                                         genSkip(ifx,'z');
5314                                                 }
5315                                         }
5316                                                 pic16_emitpLabel(falselbl->key);
5317                                                 break;
5318
5319                         } // switch size
5320           
5321                         ifx->generated = 1;
5322                         goto release ;
5323             
5324
5325           } else if(AOP_TYPE(right) == AOP_CRY ) {
5326             /* we know the left is not a bit, but that the right is */
5327             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5328             pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5329                       pic16_popGet(AOP(right),offset));
5330             pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5331
5332             /* if the two are equal, then W will be 0 and the Z bit is set
5333              * we could test Z now, or go ahead and check the high order bytes if
5334              * the variable we're comparing is larger than a byte. */
5335
5336             while(--size)
5337               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5338
5339             if ( IC_TRUE(ifx) ) {
5340               emitSKPNZ;
5341               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5342               // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5343             } else {
5344               emitSKPZ;
5345               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5346               // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5347             }
5348
5349           } else {
5350             /* They're both variables that are larger than bits */
5351             int s = size;
5352
5353             tlbl = newiTempLabel(NULL);
5354
5355             while(size--) {
5356               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5357               pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5358
5359               if ( IC_TRUE(ifx) ) {
5360                 if(size) {
5361                   emitSKPZ;
5362                 
5363                         DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5364
5365                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5366                   pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5367                 } else {
5368                   emitSKPNZ;
5369
5370                         DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5371
5372
5373                   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5374                   pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5375                 }
5376               } else {
5377                 emitSKPZ;
5378
5379                         DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5380
5381                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5382                 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5383               }
5384               offset++;
5385             }
5386             if(s>1 && IC_TRUE(ifx)) {
5387               pic16_emitpLabel(tlbl->key);
5388               pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
5389             }
5390           }
5391         }
5392         /* mark the icode as generated */
5393         ifx->generated = 1;
5394         goto release ;
5395     }
5396
5397     /* if they are both bit variables */
5398     if (AOP_TYPE(left) == AOP_CRY &&
5399         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5400         DEBUGpic16_emitcode ("; ***","%s  %d CASE 2",__FUNCTION__,__LINE__);
5401         if(AOP_TYPE(right) == AOP_LIT){
5402             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5403             if(lit == 0L){
5404                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5405                 pic16_emitcode("cpl","c");
5406             } else if(lit == 1L) {
5407                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5408             } else {
5409                 pic16_emitcode("clr","c");
5410             }
5411             /* AOP_TYPE(right) == AOP_CRY */
5412         } else {
5413             symbol *lbl = newiTempLabel(NULL);
5414             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5415             pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5416             pic16_emitcode("cpl","c");
5417             pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5418         }
5419         /* c = 1 if egal */
5420         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5421             pic16_outBitC(result);
5422             goto release ;
5423         }
5424         if (ifx) {
5425             genIfxJump (ifx,"c");
5426             goto release ;
5427         }
5428         /* if the result is used in an arithmetic operation
5429         then put the result in place */
5430         pic16_outBitC(result);
5431     } else {
5432       
5433       DEBUGpic16_emitcode ("; ***","%s  %d CASE 3",__FUNCTION__,__LINE__);
5434       gencjne(left,right,result,ifx);
5435 /*
5436       if(ifx) 
5437         gencjne(left,right,newiTempLabel(NULL));
5438       else {
5439         if(IC_TRUE(ifx)->key)
5440           gencjne(left,right,IC_TRUE(ifx)->key);
5441         else
5442           gencjne(left,right,IC_FALSE(ifx)->key);
5443         ifx->generated = 1;
5444         goto release ;
5445       }
5446       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5447         pic16_aopPut(AOP(result),"a",0);
5448         goto release ;
5449       }
5450
5451       if (ifx) {
5452         genIfxJump (ifx,"a");
5453         goto release ;
5454       }
5455 */
5456       /* if the result is used in an arithmetic operation
5457          then put the result in place */
5458 /*
5459       if (AOP_TYPE(result) != AOP_CRY) 
5460         pic16_outAcc(result);
5461 */
5462       /* leave the result in acc */
5463     }
5464
5465 release:
5466     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5467     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5468     pic16_freeAsmop(result,NULL,ic,TRUE);
5469 }
5470
5471 /*-----------------------------------------------------------------*/
5472 /* ifxForOp - returns the icode containing the ifx for operand     */
5473 /*-----------------------------------------------------------------*/
5474 static iCode *ifxForOp ( operand *op, iCode *ic )
5475 {
5476     /* if true symbol then needs to be assigned */
5477     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5478     if (IS_TRUE_SYMOP(op))
5479         return NULL ;
5480
5481     /* if this has register type condition and
5482     the next instruction is ifx with the same operand
5483     and live to of the operand is upto the ifx only then */
5484     if (ic->next &&
5485         ic->next->op == IFX &&
5486         IC_COND(ic->next)->key == op->key &&
5487         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5488         return ic->next;
5489
5490     if (ic->next &&
5491         ic->next->op == IFX &&
5492         IC_COND(ic->next)->key == op->key) {
5493       DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5494       return ic->next;
5495     }
5496
5497     DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5498     if (ic->next &&
5499         ic->next->op == IFX)
5500       DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5501
5502     if (ic->next &&
5503         ic->next->op == IFX &&
5504         IC_COND(ic->next)->key == op->key) {
5505       DEBUGpic16_emitcode ("; "," key is okay");
5506       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5507                            OP_SYMBOL(op)->liveTo,
5508                            ic->next->seq);
5509     }
5510
5511
5512     return NULL;
5513 }
5514 /*-----------------------------------------------------------------*/
5515 /* genAndOp - for && operation                                     */
5516 /*-----------------------------------------------------------------*/
5517 static void genAndOp (iCode *ic)
5518 {
5519     operand *left,*right, *result;
5520 /*     symbol *tlbl; */
5521
5522     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5523     /* note here that && operations that are in an
5524     if statement are taken away by backPatchLabels
5525     only those used in arthmetic operations remain */
5526     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5527     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5528     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5529
5530     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5531
5532     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5533     pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5534     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5535
5536     /* if both are bit variables */
5537 /*     if (AOP_TYPE(left) == AOP_CRY && */
5538 /*         AOP_TYPE(right) == AOP_CRY ) { */
5539 /*         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5540 /*         pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5541 /*         pic16_outBitC(result); */
5542 /*     } else { */
5543 /*         tlbl = newiTempLabel(NULL); */
5544 /*         pic16_toBoolean(left);     */
5545 /*         pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5546 /*         pic16_toBoolean(right); */
5547 /*         pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5548 /*         pic16_outBitAcc(result); */
5549 /*     } */
5550
5551     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5552     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5553     pic16_freeAsmop(result,NULL,ic,TRUE);
5554 }
5555
5556
5557 /*-----------------------------------------------------------------*/
5558 /* genOrOp - for || operation                                      */
5559 /*-----------------------------------------------------------------*/
5560 /*
5561   tsd pic port -
5562   modified this code, but it doesn't appear to ever get called
5563 */
5564
5565 static void genOrOp (iCode *ic)
5566 {
5567     operand *left,*right, *result;
5568     symbol *tlbl;
5569
5570     /* note here that || operations that are in an
5571     if statement are taken away by backPatchLabels
5572     only those used in arthmetic operations remain */
5573     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5574     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5575     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5576     pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5577
5578     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5579
5580     /* if both are bit variables */
5581     if (AOP_TYPE(left) == AOP_CRY &&
5582         AOP_TYPE(right) == AOP_CRY ) {
5583       pic16_emitcode("clrc","");
5584       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5585                AOP(left)->aopu.aop_dir,
5586                AOP(left)->aopu.aop_dir);
5587       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5588                AOP(right)->aopu.aop_dir,
5589                AOP(right)->aopu.aop_dir);
5590       pic16_emitcode("setc","");
5591
5592     } else {
5593         tlbl = newiTempLabel(NULL);
5594         pic16_toBoolean(left);
5595         emitSKPZ;
5596         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5597         pic16_toBoolean(right);
5598         pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5599
5600         pic16_outBitAcc(result);
5601     }
5602
5603     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5604     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5605     pic16_freeAsmop(result,NULL,ic,TRUE);            
5606 }
5607
5608 /*-----------------------------------------------------------------*/
5609 /* isLiteralBit - test if lit == 2^n                               */
5610 /*-----------------------------------------------------------------*/
5611 static int isLiteralBit(unsigned long lit)
5612 {
5613     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5614     0x100L,0x200L,0x400L,0x800L,
5615     0x1000L,0x2000L,0x4000L,0x8000L,
5616     0x10000L,0x20000L,0x40000L,0x80000L,
5617     0x100000L,0x200000L,0x400000L,0x800000L,
5618     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5619     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5620     int idx;
5621     
5622     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5623     for(idx = 0; idx < 32; idx++)
5624         if(lit == pw[idx])
5625             return idx+1;
5626     return 0;
5627 }
5628
5629 /*-----------------------------------------------------------------*/
5630 /* continueIfTrue -                                                */
5631 /*-----------------------------------------------------------------*/
5632 static void continueIfTrue (iCode *ic)
5633 {
5634     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5635     if(IC_TRUE(ic))
5636         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5637     ic->generated = 1;
5638 }
5639
5640 /*-----------------------------------------------------------------*/
5641 /* jmpIfTrue -                                                     */
5642 /*-----------------------------------------------------------------*/
5643 static void jumpIfTrue (iCode *ic)
5644 {
5645     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5646     if(!IC_TRUE(ic))
5647         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5648     ic->generated = 1;
5649 }
5650
5651 /*-----------------------------------------------------------------*/
5652 /* jmpTrueOrFalse -                                                */
5653 /*-----------------------------------------------------------------*/
5654 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5655 {
5656     // ugly but optimized by peephole
5657     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5658     if(IC_TRUE(ic)){
5659         symbol *nlbl = newiTempLabel(NULL);
5660         pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5661         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5662         pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5663         pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5664     }
5665     else{
5666         pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5667         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5668     }
5669     ic->generated = 1;
5670 }
5671
5672 /*-----------------------------------------------------------------*/
5673 /* genAnd  - code for and                                          */
5674 /*-----------------------------------------------------------------*/
5675 static void genAnd (iCode *ic, iCode *ifx)
5676 {
5677   operand *left, *right, *result;
5678   int size, offset=0;  
5679   unsigned long lit = 0L;
5680   int bytelit = 0;
5681   resolvedIfx rIfx;
5682
5683
5684   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5685   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5686   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5687   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5688
5689   resolveIfx(&rIfx,ifx);
5690
5691   /* if left is a literal & right is not then exchange them */
5692   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5693       AOP_NEEDSACC(left)) {
5694     operand *tmp = right ;
5695     right = left;
5696     left = tmp;
5697   }
5698
5699   /* if result = right then exchange them */
5700   if(pic16_sameRegs(AOP(result),AOP(right))){
5701     operand *tmp = right ;
5702     right = left;
5703     left = tmp;
5704   }
5705
5706   /* if right is bit then exchange them */
5707   if (AOP_TYPE(right) == AOP_CRY &&
5708       AOP_TYPE(left) != AOP_CRY){
5709     operand *tmp = right ;
5710     right = left;
5711     left = tmp;
5712   }
5713   if(AOP_TYPE(right) == AOP_LIT)
5714     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5715
5716   size = AOP_SIZE(result);
5717
5718   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5719
5720   // if(bit & yy)
5721   // result = bit & yy;
5722   if (AOP_TYPE(left) == AOP_CRY){
5723     // c = bit & literal;
5724     if(AOP_TYPE(right) == AOP_LIT){
5725       if(lit & 1) {
5726         if(size && pic16_sameRegs(AOP(result),AOP(left)))
5727           // no change
5728           goto release;
5729         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5730       } else {
5731         // bit(result) = 0;
5732         if(size && (AOP_TYPE(result) == AOP_CRY)){
5733           pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5734           goto release;
5735         }
5736         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5737           jumpIfTrue(ifx);
5738           goto release;
5739         }
5740         pic16_emitcode("clr","c");
5741       }
5742     } else {
5743       if (AOP_TYPE(right) == AOP_CRY){
5744         // c = bit & bit;
5745         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5746         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5747       } else {
5748         // c = bit & val;
5749         MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5750         // c = lsb
5751         pic16_emitcode("rrc","a");
5752         pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5753       }
5754     }
5755     // bit = c
5756     // val = c
5757     if(size)
5758       pic16_outBitC(result);
5759     // if(bit & ...)
5760     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5761       genIfxJump(ifx, "c");           
5762     goto release ;
5763   }
5764
5765   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5766   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5767   if((AOP_TYPE(right) == AOP_LIT) &&
5768      (AOP_TYPE(result) == AOP_CRY) &&
5769      (AOP_TYPE(left) != AOP_CRY)){
5770     int posbit = isLiteralBit(lit);
5771     /* left &  2^n */
5772     if(posbit){
5773       posbit--;
5774       //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5775       // bit = left & 2^n
5776       if(size)
5777         pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5778       // if(left &  2^n)
5779       else{
5780         if(ifx){
5781 /*
5782           if(IC_TRUE(ifx)) {
5783             pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5784             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5785           } else {
5786             pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5787             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5788           }
5789 */
5790           pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5791                     pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5792           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5793           
5794           ifx->generated = 1;
5795         }
5796         goto release;
5797       }
5798     } else {
5799       symbol *tlbl = newiTempLabel(NULL);
5800       int sizel = AOP_SIZE(left);
5801       if(size)
5802         pic16_emitcode("setb","c");
5803       while(sizel--){
5804         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5805           MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5806           // byte ==  2^n ?
5807           if((posbit = isLiteralBit(bytelit)) != 0)
5808             pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5809           else{
5810             if(bytelit != 0x0FFL)
5811               pic16_emitcode("anl","a,%s",
5812                              pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5813             pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5814           }
5815         }
5816         offset++;
5817       }
5818       // bit = left & literal
5819       if(size){
5820         pic16_emitcode("clr","c");
5821         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5822       }
5823       // if(left & literal)
5824       else{
5825         if(ifx)
5826           jmpTrueOrFalse(ifx, tlbl);
5827         goto release ;
5828       }
5829     }
5830     pic16_outBitC(result);
5831     goto release ;
5832   }
5833
5834   /* if left is same as result */
5835   if(pic16_sameRegs(AOP(result),AOP(left))){
5836     int know_W = -1;
5837     for(;size--; offset++,lit>>=8) {
5838       if(AOP_TYPE(right) == AOP_LIT){
5839         switch(lit & 0xff) {
5840         case 0x00:
5841           /*  and'ing with 0 has clears the result */
5842 //        pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5843           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5844           break;
5845         case 0xff:
5846           /* and'ing with 0xff is a nop when the result and left are the same */
5847           break;
5848
5849         default:
5850           {
5851             int p = my_powof2( (~lit) & 0xff );
5852             if(p>=0) {
5853               /* only one bit is set in the literal, so use a bcf instruction */
5854 //            pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5855               pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5856
5857             } else {
5858               pic16_emitcode("movlw","0x%x", (lit & 0xff));
5859               pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5860               if(know_W != (lit&0xff))
5861                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5862               know_W = lit &0xff;
5863               pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5864             }
5865           }    
5866         }
5867       } else {
5868         if (AOP_TYPE(left) == AOP_ACC) {
5869           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5870         } else {                    
5871           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5872           pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5873
5874         }
5875       }
5876     }
5877
5878   } else {
5879     // left & result in different registers
5880     if(AOP_TYPE(result) == AOP_CRY){
5881       // result = bit
5882       // if(size), result in bit
5883       // if(!size && ifx), conditional oper: if(left & right)
5884       symbol *tlbl = newiTempLabel(NULL);
5885       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5886       if(size)
5887         pic16_emitcode("setb","c");
5888       while(sizer--){
5889         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5890         pic16_emitcode("anl","a,%s",
5891                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5892         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5893         offset++;
5894       }
5895       if(size){
5896         CLRC;
5897         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5898         pic16_outBitC(result);
5899       } else if(ifx)
5900         jmpTrueOrFalse(ifx, tlbl);
5901     } else {
5902       for(;(size--);offset++) {
5903         // normal case
5904         // result = left & right
5905         if(AOP_TYPE(right) == AOP_LIT){
5906           int t = (lit >> (offset*8)) & 0x0FFL;
5907           switch(t) { 
5908           case 0x00:
5909             pic16_emitcode("clrf","%s",
5910                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5911             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5912             break;
5913           case 0xff:
5914             pic16_emitcode("movf","%s,w",
5915                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5916             pic16_emitcode("movwf","%s",
5917                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5918             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5919             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5920             break;
5921           default:
5922             pic16_emitcode("movlw","0x%x",t);
5923             pic16_emitcode("andwf","%s,w",
5924                            pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5925             pic16_emitcode("movwf","%s",
5926                            pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5927               
5928             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5929             pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5930             pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5931           }
5932           continue;
5933         }
5934
5935         if (AOP_TYPE(left) == AOP_ACC) {
5936           pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5937           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5938         } else {
5939           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5940           pic16_emitcode("andwf","%s,w",
5941                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5942           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5943           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5944         }
5945         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5946         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5947       }
5948     }
5949   }
5950
5951   release :
5952     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5953   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5954   pic16_freeAsmop(result,NULL,ic,TRUE);     
5955 }
5956
5957 /*-----------------------------------------------------------------*/
5958 /* genOr  - code for or                                            */
5959 /*-----------------------------------------------------------------*/
5960 static void genOr (iCode *ic, iCode *ifx)
5961 {
5962     operand *left, *right, *result;
5963     int size, offset=0;
5964     unsigned long lit = 0L;
5965
5966     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5967
5968     pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5969     pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5970     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5971
5972     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5973
5974     /* if left is a literal & right is not then exchange them */
5975     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5976         AOP_NEEDSACC(left)) {
5977         operand *tmp = right ;
5978         right = left;
5979         left = tmp;
5980     }
5981
5982     /* if result = right then exchange them */
5983     if(pic16_sameRegs(AOP(result),AOP(right))){
5984         operand *tmp = right ;
5985         right = left;
5986         left = tmp;
5987     }
5988
5989     /* if right is bit then exchange them */
5990     if (AOP_TYPE(right) == AOP_CRY &&
5991         AOP_TYPE(left) != AOP_CRY){
5992         operand *tmp = right ;
5993         right = left;
5994         left = tmp;
5995     }
5996
5997     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5998
5999     if(AOP_TYPE(right) == AOP_LIT)
6000         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6001
6002     size = AOP_SIZE(result);
6003
6004     // if(bit | yy)
6005     // xx = bit | yy;
6006     if (AOP_TYPE(left) == AOP_CRY){
6007         if(AOP_TYPE(right) == AOP_LIT){
6008             // c = bit & literal;
6009             if(lit){
6010                 // lit != 0 => result = 1
6011                 if(AOP_TYPE(result) == AOP_CRY){
6012                   if(size)
6013                     pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6014                   //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6015                   //     AOP(result)->aopu.aop_dir,
6016                   //     AOP(result)->aopu.aop_dir);
6017                     else if(ifx)
6018                         continueIfTrue(ifx);
6019                     goto release;
6020                 }
6021             } else {
6022                 // lit == 0 => result = left
6023                 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6024                     goto release;
6025                 pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6026             }
6027         } else {
6028             if (AOP_TYPE(right) == AOP_CRY){
6029               if(pic16_sameRegs(AOP(result),AOP(left))){
6030                 // c = bit | bit;
6031                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
6032                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6033                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
6034
6035                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6036                          AOP(result)->aopu.aop_dir,
6037                          AOP(result)->aopu.aop_dir);
6038                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6039                          AOP(right)->aopu.aop_dir,
6040                          AOP(right)->aopu.aop_dir);
6041                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6042                          AOP(result)->aopu.aop_dir,
6043                          AOP(result)->aopu.aop_dir);
6044               } else {
6045                 if( AOP_TYPE(result) == AOP_ACC) {
6046                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6047                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6048                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6049                   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6050
6051                 } else {
6052
6053                   pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
6054                   pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6055                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6056                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
6057
6058                   pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6059                                  AOP(result)->aopu.aop_dir,
6060                                  AOP(result)->aopu.aop_dir);
6061                   pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6062                                  AOP(right)->aopu.aop_dir,
6063                                  AOP(right)->aopu.aop_dir);
6064                   pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6065                                  AOP(left)->aopu.aop_dir,
6066                                  AOP(left)->aopu.aop_dir);
6067                   pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6068                                  AOP(result)->aopu.aop_dir,
6069                                  AOP(result)->aopu.aop_dir);
6070                 }
6071               }
6072             } else {
6073                 // c = bit | val;
6074                 symbol *tlbl = newiTempLabel(NULL);
6075                 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6076
6077
6078                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
6079                 if( AOP_TYPE(right) == AOP_ACC) {
6080                   pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6081                   emitSKPNZ;
6082                   pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6083                   pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
6084                 }
6085
6086
6087
6088                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6089                     pic16_emitcode(";XXX setb","c");
6090                 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6091                          AOP(left)->aopu.aop_dir,tlbl->key+100);
6092                 pic16_toBoolean(right);
6093                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6094                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6095                     jmpTrueOrFalse(ifx, tlbl);
6096                     goto release;
6097                 } else {
6098                     CLRC;
6099                     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6100                 }
6101             }
6102         }
6103         // bit = c
6104         // val = c
6105         if(size)
6106             pic16_outBitC(result);
6107         // if(bit | ...)
6108         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6109             genIfxJump(ifx, "c");           
6110         goto release ;
6111     }
6112
6113     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
6114     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
6115     if((AOP_TYPE(right) == AOP_LIT) &&
6116        (AOP_TYPE(result) == AOP_CRY) &&
6117        (AOP_TYPE(left) != AOP_CRY)){
6118         if(lit){
6119           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6120             // result = 1
6121             if(size)
6122                 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6123             else 
6124                 continueIfTrue(ifx);
6125             goto release;
6126         } else {
6127           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6128             // lit = 0, result = boolean(left)
6129             if(size)
6130                 pic16_emitcode(";XXX setb","c");
6131             pic16_toBoolean(right);
6132             if(size){
6133                 symbol *tlbl = newiTempLabel(NULL);
6134                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6135                 CLRC;
6136                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6137             } else {
6138                 genIfxJump (ifx,"a");
6139                 goto release;
6140             }
6141         }
6142         pic16_outBitC(result);
6143         goto release ;
6144     }
6145
6146     /* if left is same as result */
6147     if(pic16_sameRegs(AOP(result),AOP(left))){
6148       int know_W = -1;
6149       for(;size--; offset++,lit>>=8) {
6150         if(AOP_TYPE(right) == AOP_LIT){
6151           if((lit & 0xff) == 0)
6152             /*  or'ing with 0 has no effect */
6153             continue;
6154           else {
6155             int p = my_powof2(lit & 0xff);
6156             if(p>=0) {
6157               /* only one bit is set in the literal, so use a bsf instruction */
6158               pic16_emitpcode(POC_BSF,
6159                         pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6160             } else {
6161               if(know_W != (lit & 0xff))
6162                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6163               know_W = lit & 0xff;
6164               pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6165             }
6166                     
6167           }
6168         } else {
6169           if (AOP_TYPE(left) == AOP_ACC) {
6170             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
6171             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6172           } else {                  
6173             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
6174             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
6175
6176             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6177             pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6178
6179           }
6180         }
6181       }
6182     } else {
6183         // left & result in different registers
6184         if(AOP_TYPE(result) == AOP_CRY){
6185             // result = bit
6186             // if(size), result in bit
6187             // if(!size && ifx), conditional oper: if(left | right)
6188             symbol *tlbl = newiTempLabel(NULL);
6189             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6190             pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6191
6192
6193             if(size)
6194                 pic16_emitcode(";XXX setb","c");
6195             while(sizer--){
6196                 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6197                 pic16_emitcode(";XXX orl","a,%s",
6198                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6199                 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6200                 offset++;
6201             }
6202             if(size){
6203                 CLRC;
6204                 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6205                 pic16_outBitC(result);
6206             } else if(ifx)
6207                 jmpTrueOrFalse(ifx, tlbl);
6208         } else for(;(size--);offset++){
6209           // normal case
6210           // result = left & right
6211           if(AOP_TYPE(right) == AOP_LIT){
6212             int t = (lit >> (offset*8)) & 0x0FFL;
6213             switch(t) { 
6214             case 0x00:
6215               pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
6216               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
6217
6218               pic16_emitcode("movf","%s,w",
6219                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6220               pic16_emitcode("movwf","%s",
6221                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6222               break;
6223             default:
6224               pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
6225               pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
6226               pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
6227
6228               pic16_emitcode("movlw","0x%x",t);
6229               pic16_emitcode("iorwf","%s,w",
6230                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6231               pic16_emitcode("movwf","%s",
6232                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6233               
6234             }
6235             continue;
6236           }
6237
6238           // faster than result <- left, anl result,right
6239           // and better if result is SFR
6240           if (AOP_TYPE(left) == AOP_ACC) {
6241             pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
6242             pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6243           } else {
6244             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
6245             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
6246
6247             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6248             pic16_emitcode("iorwf","%s,w",
6249                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6250           }
6251           pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
6252           pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6253         }
6254     }
6255
6256 release :
6257     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6258     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6259     pic16_freeAsmop(result,NULL,ic,TRUE);     
6260 }
6261
6262 /*-----------------------------------------------------------------*/
6263 /* genXor - code for xclusive or                                   */
6264 /*-----------------------------------------------------------------*/
6265 static void genXor (iCode *ic, iCode *ifx)
6266 {
6267   operand *left, *right, *result;
6268   int size, offset=0;
6269   unsigned long lit = 0L;
6270
6271   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6272
6273   pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6274   pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6275   pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6276
6277   /* if left is a literal & right is not ||
6278      if left needs acc & right does not */
6279   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6280       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6281     operand *tmp = right ;
6282     right = left;
6283     left = tmp;
6284   }
6285
6286   /* if result = right then exchange them */
6287   if(pic16_sameRegs(AOP(result),AOP(right))){
6288     operand *tmp = right ;
6289     right = left;
6290     left = tmp;
6291   }
6292
6293   /* if right is bit then exchange them */
6294   if (AOP_TYPE(right) == AOP_CRY &&
6295       AOP_TYPE(left) != AOP_CRY){
6296     operand *tmp = right ;
6297     right = left;
6298     left = tmp;
6299   }
6300   if(AOP_TYPE(right) == AOP_LIT)
6301     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6302
6303   size = AOP_SIZE(result);
6304
6305   // if(bit ^ yy)
6306   // xx = bit ^ yy;
6307   if (AOP_TYPE(left) == AOP_CRY){
6308     if(AOP_TYPE(right) == AOP_LIT){
6309       // c = bit & literal;
6310       if(lit>>1){
6311         // lit>>1  != 0 => result = 1
6312         if(AOP_TYPE(result) == AOP_CRY){
6313           if(size)
6314             {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
6315             pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6316           else if(ifx)
6317             continueIfTrue(ifx);
6318           goto release;
6319         }
6320         pic16_emitcode("setb","c");
6321       } else{
6322         // lit == (0 or 1)
6323         if(lit == 0){
6324           // lit == 0, result = left
6325           if(size && pic16_sameRegs(AOP(result),AOP(left)))
6326             goto release;
6327           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6328         } else{
6329           // lit == 1, result = not(left)
6330           if(size && pic16_sameRegs(AOP(result),AOP(left))){
6331             pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
6332             pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
6333             pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6334             goto release;
6335           } else {
6336             pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6337             pic16_emitcode("cpl","c");
6338           }
6339         }
6340       }
6341
6342     } else {
6343       // right != literal
6344       symbol *tlbl = newiTempLabel(NULL);
6345       if (AOP_TYPE(right) == AOP_CRY){
6346         // c = bit ^ bit;
6347         pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6348       }
6349       else{
6350         int sizer = AOP_SIZE(right);
6351         // c = bit ^ val
6352         // if val>>1 != 0, result = 1
6353         pic16_emitcode("setb","c");
6354         while(sizer){
6355           MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6356           if(sizer == 1)
6357             // test the msb of the lsb
6358             pic16_emitcode("anl","a,#0xfe");
6359           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6360           sizer--;
6361         }
6362         // val = (0,1)
6363         pic16_emitcode("rrc","a");
6364       }
6365       pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6366       pic16_emitcode("cpl","c");
6367       pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6368     }
6369     // bit = c
6370     // val = c
6371     if(size)
6372       pic16_outBitC(result);
6373     // if(bit | ...)
6374     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6375       genIfxJump(ifx, "c");           
6376     goto release ;
6377   }
6378
6379   if(pic16_sameRegs(AOP(result),AOP(left))){
6380     /* if left is same as result */
6381     for(;size--; offset++) {
6382       if(AOP_TYPE(right) == AOP_LIT){
6383         int t  = (lit >> (offset*8)) & 0x0FFL;
6384         if(t == 0x00L)
6385           continue;
6386         else
6387           if (IS_AOP_PREG(left)) {
6388             MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6389             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6390             pic16_aopPut(AOP(result),"a",offset);
6391           } else {
6392             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6393             pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6394             pic16_emitcode("xrl","%s,%s",
6395                            pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6396                            pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6397           }
6398       } else {
6399         if (AOP_TYPE(left) == AOP_ACC)
6400           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6401         else {
6402           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6403           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6404 /*
6405           if (IS_AOP_PREG(left)) {
6406             pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6407             pic16_aopPut(AOP(result),"a",offset);
6408           } else
6409             pic16_emitcode("xrl","%s,a",
6410                            pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6411 */
6412         }
6413       }
6414     }
6415   } else {
6416     // left & result in different registers
6417     if(AOP_TYPE(result) == AOP_CRY){
6418       // result = bit
6419       // if(size), result in bit
6420       // if(!size && ifx), conditional oper: if(left ^ right)
6421       symbol *tlbl = newiTempLabel(NULL);
6422       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6423       if(size)
6424         pic16_emitcode("setb","c");
6425       while(sizer--){
6426         if((AOP_TYPE(right) == AOP_LIT) &&
6427            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6428           MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6429         } else {
6430           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6431           pic16_emitcode("xrl","a,%s",
6432                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6433         }
6434         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6435         offset++;
6436       }
6437       if(size){
6438         CLRC;
6439         pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6440         pic16_outBitC(result);
6441       } else if(ifx)
6442         jmpTrueOrFalse(ifx, tlbl);
6443     } else for(;(size--);offset++){
6444       // normal case
6445       // result = left & right
6446       if(AOP_TYPE(right) == AOP_LIT){
6447         int t = (lit >> (offset*8)) & 0x0FFL;
6448         switch(t) { 
6449         case 0x00:
6450           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6451           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6452           pic16_emitcode("movf","%s,w",
6453                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6454           pic16_emitcode("movwf","%s",
6455                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6456           break;
6457         case 0xff:
6458           pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6459           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6460           pic16_emitcode("comf","%s,w",
6461                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6462           pic16_emitcode("movwf","%s",
6463                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6464           break;
6465         default:
6466           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6467           pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6468           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6469           pic16_emitcode("movlw","0x%x",t);
6470           pic16_emitcode("xorwf","%s,w",
6471                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6472           pic16_emitcode("movwf","%s",
6473                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6474
6475         }
6476         continue;
6477       }
6478
6479       // faster than result <- left, anl result,right
6480       // and better if result is SFR
6481       if (AOP_TYPE(left) == AOP_ACC) {
6482         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6483         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6484       } else {
6485         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6486         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6487         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6488         pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6489       }
6490       if ( AOP_TYPE(result) != AOP_ACC){
6491         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6492         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6493       }
6494     }
6495   }
6496
6497   release :
6498     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6499   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6500   pic16_freeAsmop(result,NULL,ic,TRUE);     
6501 }
6502
6503 /*-----------------------------------------------------------------*/
6504 /* genInline - write the inline code out                           */
6505 /*-----------------------------------------------------------------*/
6506 static void genInline (iCode *ic)
6507 {
6508   char *buffer, *bp, *bp1;
6509     
6510         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6511
6512         _G.inLine += (!options.asmpeep);
6513
6514         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6515         strcpy(buffer,IC_INLINE(ic));
6516
6517 //      fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
6518
6519         /* emit each line as a code */
6520         while (*bp) {
6521                 if (*bp == '\n') {
6522                         *bp++ = '\0';
6523
6524                         if(*bp1)
6525 #if 0
6526                                 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6527 #else
6528                                 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6529 #endif
6530                         bp1 = bp;
6531                 } else {
6532                         if (*bp == ':') {
6533                                 bp++;
6534                                 *bp = '\0';
6535                                 bp++;
6536                                 pic16_emitcode(bp1,"");
6537                                 bp1 = bp;
6538                         } else
6539                                 bp++;
6540                 }
6541         }
6542
6543         if ((bp1 != bp) && *bp1)
6544 #if 0
6545                 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6546 #else
6547                 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6548 #endif
6549
6550
6551     Safe_free(buffer);
6552
6553     _G.inLine -= (!options.asmpeep);
6554 }
6555
6556 /*-----------------------------------------------------------------*/
6557 /* genRRC - rotate right with carry                                */
6558 /*-----------------------------------------------------------------*/
6559 static void genRRC (iCode *ic)
6560 {
6561   operand *left , *result ;
6562   int size, offset = 0, same;
6563
6564   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6565
6566   /* rotate right with carry */
6567   left = IC_LEFT(ic);
6568   result=IC_RESULT(ic);
6569   pic16_aopOp (left,ic,FALSE);
6570   pic16_aopOp (result,ic,FALSE);
6571
6572   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6573
6574   same = pic16_sameRegs(AOP(result),AOP(left));
6575
6576   size = AOP_SIZE(result);    
6577
6578   DEBUGpic16_emitcode ("; ***","%s  %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6579
6580   /* get the lsb and put it into the carry */
6581   pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6582
6583   offset = 0 ;
6584
6585   while(size--) {
6586
6587     if(same) {
6588       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6589     } else {
6590       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6591       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6592     }
6593
6594     offset++;
6595   }
6596
6597   pic16_freeAsmop(left,NULL,ic,TRUE);
6598   pic16_freeAsmop(result,NULL,ic,TRUE);
6599 }
6600
6601 /*-----------------------------------------------------------------*/
6602 /* genRLC - generate code for rotate left with carry               */
6603 /*-----------------------------------------------------------------*/
6604 static void genRLC (iCode *ic)
6605 {    
6606   operand *left , *result ;
6607   int size, offset = 0;
6608   int same;
6609
6610   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6611   /* rotate right with carry */
6612   left = IC_LEFT(ic);
6613   result=IC_RESULT(ic);
6614   pic16_aopOp (left,ic,FALSE);
6615   pic16_aopOp (result,ic,FALSE);
6616
6617   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6618
6619   same = pic16_sameRegs(AOP(result),AOP(left));
6620
6621   /* move it to the result */
6622   size = AOP_SIZE(result);    
6623
6624   /* get the msb and put it into the carry */
6625   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6626
6627   offset = 0 ;
6628
6629   while(size--) {
6630
6631     if(same) {
6632       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6633     } else {
6634       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6635       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6636     }
6637
6638     offset++;
6639   }
6640
6641
6642   pic16_freeAsmop(left,NULL,ic,TRUE);
6643   pic16_freeAsmop(result,NULL,ic,TRUE);
6644 }
6645
6646
6647 /* gpasm can get the highest order bit with HIGH/UPPER
6648  * so the following probably is not needed -- VR */
6649  
6650 /*-----------------------------------------------------------------*/
6651 /* genGetHbit - generates code get highest order bit               */
6652 /*-----------------------------------------------------------------*/
6653 static void genGetHbit (iCode *ic)
6654 {
6655     operand *left, *result;
6656     left = IC_LEFT(ic);
6657     result=IC_RESULT(ic);
6658     pic16_aopOp (left,ic,FALSE);
6659     pic16_aopOp (result,ic,FALSE);
6660
6661     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6662     /* get the highest order byte into a */
6663     MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6664     if(AOP_TYPE(result) == AOP_CRY){
6665         pic16_emitcode("rlc","a");
6666         pic16_outBitC(result);
6667     }
6668     else{
6669         pic16_emitcode("rl","a");
6670         pic16_emitcode("anl","a,#0x01");
6671         pic16_outAcc(result);
6672     }
6673
6674
6675     pic16_freeAsmop(left,NULL,ic,TRUE);
6676     pic16_freeAsmop(result,NULL,ic,TRUE);
6677 }
6678
6679 #if 0
6680 /*-----------------------------------------------------------------*/
6681 /* AccRol - rotate left accumulator by known count                 */
6682 /*-----------------------------------------------------------------*/
6683 static void AccRol (int shCount)
6684 {
6685     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6686     shCount &= 0x0007;              // shCount : 0..7
6687     switch(shCount){
6688         case 0 :
6689             break;
6690         case 1 :
6691             pic16_emitcode("rl","a");
6692             break;
6693         case 2 :
6694             pic16_emitcode("rl","a");
6695             pic16_emitcode("rl","a");
6696             break;
6697         case 3 :
6698             pic16_emitcode("swap","a");
6699             pic16_emitcode("rr","a");
6700             break;
6701         case 4 :
6702             pic16_emitcode("swap","a");
6703             break;
6704         case 5 :
6705             pic16_emitcode("swap","a");
6706             pic16_emitcode("rl","a");
6707             break;
6708         case 6 :
6709             pic16_emitcode("rr","a");
6710             pic16_emitcode("rr","a");
6711             break;
6712         case 7 :
6713             pic16_emitcode("rr","a");
6714             break;
6715     }
6716 }
6717 #endif
6718
6719 /*-----------------------------------------------------------------*/
6720 /* AccLsh - left shift accumulator by known count                  */
6721 /*-----------------------------------------------------------------*/
6722 static void AccLsh (int shCount)
6723 {
6724         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6725         switch(shCount){
6726                 case 0 :
6727                         return;
6728                         break;
6729                 case 1 :
6730                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6731                         break;
6732                 case 2 :
6733                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6734                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6735                         break;
6736                 case 3 :
6737                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6738                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6739                         break;
6740                 case 4 :
6741                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6742                         break;
6743                 case 5 :
6744                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6745                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6746                         break;
6747                 case 6 :
6748                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6749                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6750                         break;
6751                 case 7 :
6752                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6753                         break;
6754         }
6755
6756         pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6757 }
6758
6759 /*-----------------------------------------------------------------*/
6760 /* AccRsh - right shift accumulator by known count                 */
6761 /*-----------------------------------------------------------------*/
6762 static void AccRsh (int shCount, int andmask)
6763 {
6764         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6765         switch(shCount){
6766                 case 0 :
6767                         return; break;
6768                 case 1 :
6769                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6770 //                      andmask = 0;    /* no need */
6771                         break;
6772                 case 2 :
6773                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6774                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6775 //                      andmask = 0;    /* no need */
6776                         break;
6777                 case 3 :
6778                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6779                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6780                         break;
6781                 case 4 :
6782                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6783                         break;
6784                 case 5 :
6785                         pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6786                         pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6787                         break;
6788                 case 6 :
6789                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6790                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6791                         break;
6792                 case 7 :
6793                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6794                         break;
6795         }
6796         
6797         if(andmask)
6798                 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6799         else
6800                 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
6801 }
6802
6803 #if 0
6804 /*-----------------------------------------------------------------*/
6805 /* AccSRsh - signed right shift accumulator by known count                 */
6806 /*-----------------------------------------------------------------*/
6807 static void AccSRsh (int shCount)
6808 {
6809     symbol *tlbl ;
6810     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6811     if(shCount != 0){
6812         if(shCount == 1){
6813             pic16_emitcode("mov","c,acc.7");
6814             pic16_emitcode("rrc","a");
6815         } else if(shCount == 2){
6816             pic16_emitcode("mov","c,acc.7");
6817             pic16_emitcode("rrc","a");
6818             pic16_emitcode("mov","c,acc.7");
6819             pic16_emitcode("rrc","a");
6820         } else {
6821             tlbl = newiTempLabel(NULL);
6822             /* rotate right accumulator */
6823             AccRol(8 - shCount);
6824             /* and kill the higher order bits */
6825             pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6826             pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6827             pic16_emitcode("orl","a,#0x%02x",
6828                      (unsigned char)~SRMask[shCount]);
6829             pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6830         }
6831     }
6832 }
6833 #endif
6834 /*-----------------------------------------------------------------*/
6835 /* shiftR1Left2Result - shift right one byte from left to result   */
6836 /*-----------------------------------------------------------------*/
6837 static void shiftR1Left2ResultSigned (operand *left, int offl,
6838                                 operand *result, int offr,
6839                                 int shCount)
6840 {
6841   int same;
6842
6843   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6844
6845   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6846
6847   switch(shCount) {
6848   case 1:
6849     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6850     if(same) 
6851       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6852     else {
6853       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6854       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6855     }
6856
6857     break;
6858   case 2:
6859
6860     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6861     if(same) 
6862       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6863     else {
6864       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6865       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6866     }
6867     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6868     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
6869
6870     break;
6871
6872   case 3:
6873     if(same)
6874       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6875     else {
6876       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6877       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6878     }
6879
6880     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6881     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6882     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6883
6884     pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6885     pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6886
6887     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6888     break;
6889
6890   case 4:
6891     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6892     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
6893     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6894     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
6895     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6896     break;
6897   case 5:
6898     if(same) {
6899       pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
6900     } else {
6901       pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
6902       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6903     }
6904     pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
6905     pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
6906     pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6907     pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
6908     pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
6909     break;
6910
6911   case 6:
6912     if(same) {
6913       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6914       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6915       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6916       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6917       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6918       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6919     } else {
6920       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6921       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6922       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6923       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6924       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6925     }
6926     break;
6927
6928   case 7:
6929     if(same) {
6930       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6931       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6932       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6933       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6934     } else {
6935       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
6936       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6937       pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
6938     }
6939
6940   default:
6941     break;
6942   }
6943 }
6944
6945 /*-----------------------------------------------------------------*/
6946 /* shiftR1Left2Result - shift right one byte from left to result   */
6947 /*-----------------------------------------------------------------*/
6948 static void shiftR1Left2Result (operand *left, int offl,
6949                                 operand *result, int offr,
6950                                 int shCount, int sign)
6951 {
6952   int same;
6953
6954   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6955
6956   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6957
6958   /* Copy the msb into the carry if signed. */
6959   if(sign) {
6960     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6961     return;
6962   }
6963
6964
6965
6966   switch(shCount) {
6967   case 1:
6968     emitCLRC;
6969     if(same) 
6970       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6971     else {
6972       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6973       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6974     }
6975     break;
6976   case 2:
6977     emitCLRC;
6978     if(same) {
6979       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6980     } else {
6981       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6982       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6983     }
6984     emitCLRC;
6985     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6986
6987     break;
6988   case 3:
6989     if(same)
6990       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6991     else {
6992       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6993       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6994     }
6995
6996     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6997     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
6998     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6999     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7000     break;
7001       
7002   case 4:
7003     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7004     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7005     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7006     break;
7007
7008   case 5:
7009     pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7010     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7011     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7012     emitCLRC;
7013     pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7014
7015     break;
7016   case 6:
7017
7018     pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl));
7019     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7020     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7021     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
7022     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
7023     break;
7024
7025   case 7:
7026
7027     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7028     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7029     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7030
7031     break;
7032
7033   default:
7034     break;
7035   }
7036 }
7037
7038 /*-----------------------------------------------------------------*/
7039 /* shiftL1Left2Result - shift left one byte from left to result    */
7040 /*-----------------------------------------------------------------*/
7041 static void shiftL1Left2Result (operand *left, int offl,
7042                                 operand *result, int offr, int shCount)
7043 {
7044   int same;
7045
7046   //    char *l;
7047   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7048
7049   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7050   DEBUGpic16_emitcode ("; ***","same =  %d",same);
7051     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7052     //    MOVA(l);
7053     /* shift left accumulator */
7054     //AccLsh(shCount); // don't comment out just yet...
7055   //    pic16_aopPut(AOP(result),"a",offr);
7056
7057   switch(shCount) {
7058   case 1:
7059     /* Shift left 1 bit position */
7060     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7061     if(same) {
7062       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7063     } else {
7064       pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7065       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7066     }
7067     break;
7068   case 2:
7069     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7070     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7071     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7072     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7073     break;
7074   case 3:
7075     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7076     pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7077     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7078     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7079     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7080     break;
7081   case 4:
7082     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7083     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7084     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7085     break;
7086   case 5:
7087     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7088     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7089     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7090     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7091     break;
7092   case 6:
7093     pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7094     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7095     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7096     pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7097     pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7098     break;
7099   case 7:
7100     pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7101     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7102     pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7103     break;
7104
7105   default:
7106     DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7107   }
7108
7109 }
7110
7111 /*-----------------------------------------------------------------*/
7112 /* movLeft2Result - move byte from left to result                  */
7113 /*-----------------------------------------------------------------*/
7114 static void movLeft2Result (operand *left, int offl,
7115                             operand *result, int offr)
7116 {
7117   char *l;
7118   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7119   if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7120     l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7121
7122     if (*l == '@' && (IS_AOP_PREG(result))) {
7123       pic16_emitcode("mov","a,%s",l);
7124       pic16_aopPut(AOP(result),"a",offr);
7125     } else {
7126       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7127       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7128     }
7129   }
7130 }
7131
7132 /*-----------------------------------------------------------------*/
7133 /* shiftL2Left2Result - shift left two bytes from left to result   */
7134 /*-----------------------------------------------------------------*/
7135 static void shiftL2Left2Result (operand *left, int offl,
7136                                 operand *result, int offr, int shCount)
7137 {
7138   int same = pic16_sameRegs(AOP(result), AOP(left));
7139   int i;
7140
7141   DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7142
7143   if (same && (offl != offr)) { // shift bytes
7144     if (offr > offl) {
7145        for(i=1;i>-1;i--) {
7146          pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7147          pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7148        }
7149     } else { // just treat as different later on
7150                 same = 0;
7151     }
7152   }
7153
7154   if(same) {
7155     switch(shCount) {
7156     case 0:
7157       break;
7158     case 1:
7159     case 2:
7160     case 3:
7161
7162       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7163       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7164       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
7165
7166       while(--shCount) {
7167                 emitCLRC;
7168                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7169                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7170       }
7171
7172       break;
7173     case 4:
7174     case 5:
7175       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7176       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7177       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7178       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7179       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7180       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7181       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7182       if(shCount >=5) {
7183                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7184                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7185       }
7186       break;
7187     case 6:
7188       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
7189       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7190       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
7191       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7192       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7193       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7194       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7195       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7196       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7197       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7198       break;
7199     case 7:
7200       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7201       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7202       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7203       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7204       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7205     }
7206
7207   } else {
7208     switch(shCount) {
7209     case 0:
7210       break;
7211     case 1:
7212     case 2:
7213     case 3:
7214       /* note, use a mov/add for the shift since the mov has a
7215          chance of getting optimized out */
7216       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7217       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7218       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7219       pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),offl+MSB16));
7220       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7221
7222       while(--shCount) {
7223                 emitCLRC;
7224                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7225                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7226       }
7227       break;
7228
7229     case 4:
7230     case 5:
7231       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7232       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7233       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7234       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7235       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7236       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7237       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7238       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7239
7240
7241       if(shCount == 5) {
7242                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7243                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7244       }
7245       break;
7246     case 6:
7247       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7248       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7249       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7250       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
7251
7252       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
7253       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7254       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7255       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7256       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7257       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7258       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7259       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7260       break;
7261     case 7:
7262       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7263       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7264       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7265       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7266       pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
7267     }
7268   }
7269
7270 }
7271 /*-----------------------------------------------------------------*/
7272 /* shiftR2Left2Result - shift right two bytes from left to result  */
7273 /*-----------------------------------------------------------------*/
7274 static void shiftR2Left2Result (operand *left, int offl,
7275                                 operand *result, int offr,
7276                                 int shCount, int sign)
7277 {
7278   int same = pic16_sameRegs(AOP(result), AOP(left));
7279   int i;
7280   DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7281
7282   if (same && (offl != offr)) { // shift right bytes
7283     if (offr < offl) {
7284        for(i=0;i<2;i++) {
7285          pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7286          pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7287        }
7288     } else { // just treat as different later on
7289                 same = 0;
7290     }
7291   }
7292
7293   switch(shCount) {
7294   case 0:
7295     break;
7296   case 1:
7297   case 2:
7298   case 3:
7299     if(sign)
7300       pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7301     else
7302       emitCLRC;
7303
7304     if(same) {
7305       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7306       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7307     } else {
7308       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7309       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7310       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7311       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7312     }
7313
7314     while(--shCount) {
7315       if(sign)
7316                 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7317       else
7318                 emitCLRC;
7319       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7320       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7321     }
7322     break;
7323   case 4:
7324   case 5:
7325     if(same) {
7326
7327       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7328       pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7329       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7330
7331       pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7332       pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7333       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7334       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7335     } else {
7336       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7337       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7338       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7339
7340       pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7341       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7342       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7343       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7344       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7345     }
7346
7347     if(shCount >=5) {
7348       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7349       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7350     }
7351
7352     if(sign) {
7353       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7354       pic16_emitpcode(POC_BTFSC, 
7355                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7356       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7357     }
7358
7359     break;
7360
7361   case 6:
7362     if(same) {
7363
7364       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7365       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
7366
7367       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7368       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
7369       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7370       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7371       if(sign) {
7372         pic16_emitpcode(POC_BTFSC, 
7373                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7374         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7375       }
7376       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7377       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7378       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7379       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7380     } else {
7381       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7382       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7383       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7384       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7385       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
7386       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7387       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7388       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7389       if(sign) {
7390         pic16_emitpcode(POC_BTFSC, 
7391                   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7392         pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7393       }
7394       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7395       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
7396
7397         
7398     }
7399
7400     break;
7401   case 7:
7402     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7403     pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7404     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7405     pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7406     if(sign) {
7407       emitSKPNC;
7408       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7409     } else 
7410       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
7411   }
7412 }
7413
7414
7415 /*-----------------------------------------------------------------*/
7416 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7417 /*-----------------------------------------------------------------*/
7418 static void shiftLLeftOrResult (operand *left, int offl,
7419                                 operand *result, int offr, int shCount)
7420 {
7421     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7422
7423     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7424     /* shift left accumulator */
7425     AccLsh(shCount);
7426     /* or with result */
7427     /* back to result */
7428     pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7429 }
7430
7431 /*-----------------------------------------------------------------*/
7432 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7433 /*-----------------------------------------------------------------*/
7434 static void shiftRLeftOrResult (operand *left, int offl,
7435                                 operand *result, int offr, int shCount)
7436 {
7437     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7438     
7439     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7440     /* shift right accumulator */
7441     AccRsh(shCount, 1);
7442     /* or with result */
7443     /* back to result */
7444     pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7445 }
7446
7447 /*-----------------------------------------------------------------*/
7448 /* genlshOne - left shift a one byte quantity by known count       */
7449 /*-----------------------------------------------------------------*/
7450 static void genlshOne (operand *result, operand *left, int shCount)
7451 {       
7452     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7453     shiftL1Left2Result(left, LSB, result, LSB, shCount);
7454 }
7455
7456 /*-----------------------------------------------------------------*/
7457 /* genlshTwo - left shift two bytes by known amount != 0           */
7458 /*-----------------------------------------------------------------*/
7459 static void genlshTwo (operand *result,operand *left, int shCount)
7460 {
7461     int size;
7462     
7463     DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7464     size = pic16_getDataSize(result);
7465
7466     /* if shCount >= 8 */
7467     if (shCount >= 8) {
7468         shCount -= 8 ;
7469
7470         if (size > 1){
7471             if (shCount)
7472                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7473             else 
7474                 movLeft2Result(left, LSB, result, MSB16);
7475         }
7476         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7477     }
7478
7479     /*  1 <= shCount <= 7 */
7480     else {  
7481         if(size == 1)
7482             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
7483         else 
7484             shiftL2Left2Result(left, LSB, result, LSB, shCount);
7485     }
7486 }
7487
7488 /*-----------------------------------------------------------------*/
7489 /* shiftLLong - shift left one long from left to result            */
7490 /* offr = LSB or MSB16                                             */
7491 /*-----------------------------------------------------------------*/
7492 static void shiftLLong (operand *left, operand *result, int offr )
7493 {
7494     int size = AOP_SIZE(result);
7495     int same = pic16_sameRegs(AOP(left),AOP(result));
7496         int i;
7497
7498     DEBUGpic16_emitcode ("; ***","%s  %d  offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7499
7500         if (same && (offr == MSB16)) { //shift one byte
7501                 for(i=size-1;i>=MSB16;i--) {
7502                         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7503                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7504                 }
7505         } else {
7506                 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7507         }
7508         
7509     if (size >= LSB+offr ){
7510                 if (same) {
7511                         pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7512                 } else {
7513                         pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7514                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7515                 }
7516          }
7517
7518     if(size >= MSB16+offr){
7519                 if (same) {
7520                         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7521                 } else {
7522                         pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7523                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7524                 }
7525     }
7526
7527     if(size >= MSB24+offr){
7528                 if (same) {
7529                         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7530                 } else {
7531                         pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7532                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7533                 }
7534     }
7535
7536     if(size > MSB32+offr){
7537                 if (same) {
7538                         pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7539                 } else {
7540                         pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7541                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7542                 }
7543     }
7544     if(offr != LSB)
7545                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7546
7547 }
7548
7549 /*-----------------------------------------------------------------*/
7550 /* genlshFour - shift four byte by a known amount != 0             */
7551 /*-----------------------------------------------------------------*/
7552 static void genlshFour (operand *result, operand *left, int shCount)
7553 {
7554     int size;
7555
7556     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7557     size = AOP_SIZE(result);
7558
7559     /* if shifting more that 3 bytes */
7560     if (shCount >= 24 ) {
7561         shCount -= 24;
7562         if (shCount)
7563             /* lowest order of left goes to the highest
7564             order of the destination */
7565             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7566         else
7567             movLeft2Result(left, LSB, result, MSB32);
7568
7569                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7570                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7571                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7572
7573         return;
7574     }
7575
7576     /* more than two bytes */
7577     else if ( shCount >= 16 ) {
7578         /* lower order two bytes goes to higher order two bytes */
7579         shCount -= 16;
7580         /* if some more remaining */
7581         if (shCount)
7582             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7583         else {
7584             movLeft2Result(left, MSB16, result, MSB32);
7585             movLeft2Result(left, LSB, result, MSB24);
7586         }
7587                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7588                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7589         return;
7590     }    
7591
7592     /* if more than 1 byte */
7593     else if ( shCount >= 8 ) {
7594         /* lower order three bytes goes to higher order  three bytes */
7595         shCount -= 8;
7596         if(size == 2){
7597             if(shCount)
7598                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7599             else
7600                 movLeft2Result(left, LSB, result, MSB16);
7601         }
7602         else{   /* size = 4 */
7603             if(shCount == 0){
7604                 movLeft2Result(left, MSB24, result, MSB32);
7605                 movLeft2Result(left, MSB16, result, MSB24);
7606                 movLeft2Result(left, LSB, result, MSB16);
7607                                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7608             }
7609             else if(shCount == 1)
7610                 shiftLLong(left, result, MSB16);
7611             else{
7612                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7613                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7614                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7615                                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7616             }
7617         }
7618     }
7619
7620     /* 1 <= shCount <= 7 */
7621     else if(shCount <= 3)
7622     { 
7623         shiftLLong(left, result, LSB);
7624         while(--shCount >= 1)
7625             shiftLLong(result, result, LSB);
7626     }
7627     /* 3 <= shCount <= 7, optimize */
7628     else{
7629         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7630         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7631         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7632     }
7633 }
7634
7635 /*-----------------------------------------------------------------*/
7636 /* genLeftShiftLiteral - left shifting by known count              */
7637 /*-----------------------------------------------------------------*/
7638 static void genLeftShiftLiteral (operand *left,
7639                                  operand *right,
7640                                  operand *result,
7641                                  iCode *ic)
7642 {    
7643     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7644     int size;
7645
7646     DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7647     pic16_freeAsmop(right,NULL,ic,TRUE);
7648
7649     pic16_aopOp(left,ic,FALSE);
7650     pic16_aopOp(result,ic,FALSE);
7651
7652     size = getSize(operandType(result));
7653
7654 #if VIEW_SIZE
7655     pic16_emitcode("; shift left ","result %d, left %d",size,
7656              AOP_SIZE(left));
7657 #endif
7658
7659     /* I suppose that the left size >= result size */
7660     if(shCount == 0){
7661         while(size--){
7662             movLeft2Result(left, size, result, size);
7663         }
7664     }
7665
7666     else if(shCount >= (size * 8))
7667         while(size--)
7668             pic16_aopPut(AOP(result),zero,size);
7669     else{
7670         switch (size) {
7671             case 1:
7672                 genlshOne (result,left,shCount);
7673                 break;
7674
7675             case 2:
7676             case 3:
7677                 genlshTwo (result,left,shCount);
7678                 break;
7679
7680             case 4:
7681                 genlshFour (result,left,shCount);
7682                 break;
7683         }
7684     }
7685     pic16_freeAsmop(left,NULL,ic,TRUE);
7686     pic16_freeAsmop(result,NULL,ic,TRUE);
7687 }
7688
7689 /*-----------------------------------------------------------------*
7690  * genMultiAsm - repeat assembly instruction for size of register.
7691  * if endian == 1, then the high byte (i.e base address + size of 
7692  * register) is used first else the low byte is used first;
7693  *-----------------------------------------------------------------*/
7694 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7695 {
7696
7697   int offset = 0;
7698
7699   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7700
7701   if(!reg)
7702     return;
7703
7704   if(!endian) {
7705     endian = 1;
7706   } else {
7707     endian = -1;
7708     offset = size-1;
7709   }
7710
7711   while(size--) {
7712     pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
7713     offset += endian;
7714   }
7715
7716 }
7717 /*-----------------------------------------------------------------*/
7718 /* genLeftShift - generates code for left shifting                 */
7719 /*-----------------------------------------------------------------*/
7720 static void genLeftShift (iCode *ic)
7721 {
7722   operand *left,*right, *result;
7723   int size, offset;
7724   char *l;
7725   symbol *tlbl , *tlbl1;
7726   pCodeOp *pctemp;
7727
7728   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7729
7730   right = IC_RIGHT(ic);
7731   left  = IC_LEFT(ic);
7732   result = IC_RESULT(ic);
7733
7734   pic16_aopOp(right,ic,FALSE);
7735
7736   /* if the shift count is known then do it 
7737      as efficiently as possible */
7738   if (AOP_TYPE(right) == AOP_LIT) {
7739     genLeftShiftLiteral (left,right,result,ic);
7740     return ;
7741   }
7742
7743   /* shift count is unknown then we have to form 
7744      a loop get the loop count in B : Note: we take
7745      only the lower order byte since shifting
7746      more that 32 bits make no sense anyway, ( the
7747      largest size of an object can be only 32 bits ) */  
7748
7749     
7750   pic16_aopOp(left,ic,FALSE);
7751   pic16_aopOp(result,ic,FALSE);
7752
7753   /* now move the left to the result if they are not the
7754      same */
7755   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
7756       AOP_SIZE(result) > 1) {
7757
7758     size = AOP_SIZE(result);
7759     offset=0;
7760     while (size--) {
7761       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7762       if (*l == '@' && (IS_AOP_PREG(result))) {
7763
7764         pic16_emitcode("mov","a,%s",l);
7765         pic16_aopPut(AOP(result),"a",offset);
7766       } else {
7767         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
7768         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
7769         //pic16_aopPut(AOP(result),l,offset);
7770       }
7771       offset++;
7772     }
7773   }
7774
7775   size = AOP_SIZE(result);
7776
7777   /* if it is only one byte then */
7778   if (size == 1) {
7779     if(optimized_for_speed) {
7780       pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7781       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
7782       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7783       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7784       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7785       pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7786       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7787       pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
7788       pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
7789       pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
7790       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7791       pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
7792     } else {
7793
7794       tlbl = newiTempLabel(NULL);
7795       if (!pic16_sameRegs(AOP(left),AOP(result))) {
7796                 pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
7797                 pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
7798       }
7799
7800       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7801       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
7802       pic16_emitpLabel(tlbl->key);
7803       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
7804       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7805       emitSKPC;
7806       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7807     }
7808     goto release ;
7809   }
7810     
7811   if (pic16_sameRegs(AOP(left),AOP(result))) {
7812
7813     tlbl = newiTempLabel(NULL);
7814     pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
7815     genMultiAsm(POC_RRCF, result, size,1);
7816     pic16_emitpLabel(tlbl->key);
7817     genMultiAsm(POC_RLCF, result, size,0);
7818     pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
7819     emitSKPC;
7820     pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7821     goto release;
7822   }
7823
7824   //tlbl = newiTempLabel(NULL);
7825   //offset = 0 ;   
7826   //tlbl1 = newiTempLabel(NULL);
7827
7828   //reAdjustPreg(AOP(result));    
7829     
7830   //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7831   //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
7832   //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7833   //MOVA(l);
7834   //pic16_emitcode("add","a,acc");         
7835   //pic16_aopPut(AOP(result),"a",offset++);
7836   //while (--size) {
7837   //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7838   //  MOVA(l);
7839   //  pic16_emitcode("rlc","a");         
7840   //  pic16_aopPut(AOP(result),"a",offset++);
7841   //}
7842   //reAdjustPreg(AOP(result));
7843
7844   //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7845   //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7846
7847
7848   tlbl = newiTempLabel(NULL);
7849   tlbl1= newiTempLabel(NULL);
7850
7851   size = AOP_SIZE(result);
7852   offset = 1;
7853
7854   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
7855
7856   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7857
7858   /* offset should be 0, 1 or 3 */
7859   
7860   pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7861   emitSKPNZ;
7862   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
7863
7864   pic16_emitpcode(POC_MOVWF, pctemp);
7865
7866
7867   pic16_emitpLabel(tlbl->key);
7868
7869   emitCLRC;
7870   pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
7871   while(--size)
7872     pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
7873
7874   pic16_emitpcode(POC_DECFSZ,  pctemp);
7875   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7876   pic16_emitpLabel(tlbl1->key);
7877
7878   pic16_popReleaseTempReg(pctemp);
7879
7880
7881  release:
7882   pic16_freeAsmop (right,NULL,ic,TRUE);
7883   pic16_freeAsmop(left,NULL,ic,TRUE);
7884   pic16_freeAsmop(result,NULL,ic,TRUE);
7885 }
7886
7887 /*-----------------------------------------------------------------*/
7888 /* genrshOne - right shift a one byte quantity by known count      */
7889 /*-----------------------------------------------------------------*/
7890 static void genrshOne (operand *result, operand *left,
7891                        int shCount, int sign)
7892 {
7893     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7894     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7895 }
7896
7897 /*-----------------------------------------------------------------*/
7898 /* genrshTwo - right shift two bytes by known amount != 0          */
7899 /*-----------------------------------------------------------------*/
7900 static void genrshTwo (operand *result,operand *left,
7901                        int shCount, int sign)
7902 {
7903   DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7904   /* if shCount >= 8 */
7905   if (shCount >= 8) {
7906     shCount -= 8 ;
7907     if (shCount)
7908       shiftR1Left2Result(left, MSB16, result, LSB,
7909                          shCount, sign);
7910     else
7911       movLeft2Result(left, MSB16, result, LSB);
7912
7913     pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7914
7915     if(sign) {
7916       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7917       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7918     }
7919   }
7920
7921   /*  1 <= shCount <= 7 */
7922   else
7923     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7924 }
7925
7926 /*-----------------------------------------------------------------*/
7927 /* shiftRLong - shift right one long from left to result           */
7928 /* offl = LSB or MSB16                                             */
7929 /*-----------------------------------------------------------------*/
7930 static void shiftRLong (operand *left, int offl,
7931                         operand *result, int sign)
7932 {
7933     int size = AOP_SIZE(result);
7934     int same = pic16_sameRegs(AOP(left),AOP(result));
7935     int i;
7936     DEBUGpic16_emitcode ("; ***","%s  %d  offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7937
7938         if (same && (offl == MSB16)) { //shift one byte right
7939                 for(i=MSB16;i<size;i++) {
7940                         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7941                         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7942                 }
7943         }
7944
7945     if(sign)
7946                 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7947         else
7948                 emitCLRC;
7949
7950         if (same) {
7951                 if (offl == LSB)
7952                 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7953         } else {
7954         pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7955         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7956         }
7957
7958     if(offl == MSB16) {
7959         /* add sign of "a" */
7960         pic16_addSign(result, MSB32, sign);
7961         }
7962
7963         if (same) {
7964         pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7965         } else {
7966         pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7967         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7968         }
7969         
7970         if (same) {
7971         pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7972         } else {
7973         pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7974         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7975         }
7976
7977         if (same) {
7978         pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7979         } else {
7980         if(offl == LSB){
7981                 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7982                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7983         }
7984         }
7985 }
7986
7987 /*-----------------------------------------------------------------*/
7988 /* genrshFour - shift four byte by a known amount != 0             */
7989 /*-----------------------------------------------------------------*/
7990 static void genrshFour (operand *result, operand *left,
7991                         int shCount, int sign)
7992 {
7993   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7994   /* if shifting more that 3 bytes */
7995   if(shCount >= 24 ) {
7996     shCount -= 24;
7997     if(shCount)
7998       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7999     else
8000       movLeft2Result(left, MSB32, result, LSB);
8001
8002     pic16_addSign(result, MSB16, sign);
8003   }
8004   else if(shCount >= 16){
8005     shCount -= 16;
8006     if(shCount)
8007       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8008     else{
8009       movLeft2Result(left, MSB24, result, LSB);
8010       movLeft2Result(left, MSB32, result, MSB16);
8011     }
8012     pic16_addSign(result, MSB24, sign);
8013   }
8014   else if(shCount >= 8){
8015     shCount -= 8;
8016     if(shCount == 1)
8017       shiftRLong(left, MSB16, result, sign);
8018     else if(shCount == 0){
8019       movLeft2Result(left, MSB16, result, LSB);
8020       movLeft2Result(left, MSB24, result, MSB16);
8021       movLeft2Result(left, MSB32, result, MSB24);
8022       pic16_addSign(result, MSB32, sign);
8023     }
8024     else{ //shcount >= 2
8025       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8026       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8027       /* the last shift is signed */
8028       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8029       pic16_addSign(result, MSB32, sign);
8030     }
8031   }
8032   else{   /* 1 <= shCount <= 7 */
8033     if(shCount <= 2){
8034       shiftRLong(left, LSB, result, sign);
8035       if(shCount == 2)
8036         shiftRLong(result, LSB, result, sign);
8037     }
8038     else{
8039       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8040       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8041       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8042     }
8043   }
8044 }
8045
8046 /*-----------------------------------------------------------------*/
8047 /* genRightShiftLiteral - right shifting by known count            */
8048 /*-----------------------------------------------------------------*/
8049 static void genRightShiftLiteral (operand *left,
8050                                   operand *right,
8051                                   operand *result,
8052                                   iCode *ic,
8053                                   int sign)
8054 {    
8055   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8056   int lsize,res_size;
8057
8058   pic16_freeAsmop(right,NULL,ic,TRUE);
8059
8060   pic16_aopOp(left,ic,FALSE);
8061   pic16_aopOp(result,ic,FALSE);
8062
8063   DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8064
8065 #if VIEW_SIZE
8066   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8067                  AOP_SIZE(left));
8068 #endif
8069
8070   lsize = pic16_getDataSize(left);
8071   res_size = pic16_getDataSize(result);
8072   /* test the LEFT size !!! */
8073
8074   /* I suppose that the left size >= result size */
8075   if(shCount == 0){
8076     while(res_size--)
8077       movLeft2Result(left, lsize, result, res_size);
8078   }
8079
8080   else if(shCount >= (lsize * 8)){
8081
8082     if(res_size == 1) {
8083       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8084       if(sign) {
8085         pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8086         pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8087       }
8088     } else {
8089
8090       if(sign) {
8091         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8092         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8093         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8094         while(res_size--)
8095           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8096
8097       } else {
8098
8099         while(res_size--)
8100           pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8101       }
8102     }
8103   } else {
8104
8105     switch (res_size) {
8106     case 1:
8107       genrshOne (result,left,shCount,sign);
8108       break;
8109
8110     case 2:
8111       genrshTwo (result,left,shCount,sign);
8112       break;
8113
8114     case 4:
8115       genrshFour (result,left,shCount,sign);
8116       break;
8117     default :
8118       break;
8119     }
8120
8121   }
8122
8123   pic16_freeAsmop(left,NULL,ic,TRUE);
8124   pic16_freeAsmop(result,NULL,ic,TRUE);
8125 }
8126
8127 /*-----------------------------------------------------------------*/
8128 /* genSignedRightShift - right shift of signed number              */
8129 /*-----------------------------------------------------------------*/
8130 static void genSignedRightShift (iCode *ic)
8131 {
8132   operand *right, *left, *result;
8133   int size, offset;
8134   //  char *l;
8135   symbol *tlbl, *tlbl1 ;
8136   pCodeOp *pctemp;
8137
8138   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8139
8140   /* we do it the hard way put the shift count in b
8141      and loop thru preserving the sign */
8142   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8143
8144   right = IC_RIGHT(ic);
8145   left  = IC_LEFT(ic);
8146   result = IC_RESULT(ic);
8147
8148   pic16_aopOp(right,ic,FALSE);  
8149   pic16_aopOp(left,ic,FALSE);
8150   pic16_aopOp(result,ic,FALSE);
8151
8152
8153   if ( AOP_TYPE(right) == AOP_LIT) {
8154     genRightShiftLiteral (left,right,result,ic,1);
8155     return ;
8156   }
8157   /* shift count is unknown then we have to form 
8158      a loop get the loop count in B : Note: we take
8159      only the lower order byte since shifting
8160      more that 32 bits make no sense anyway, ( the
8161      largest size of an object can be only 32 bits ) */  
8162
8163   //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8164   //pic16_emitcode("inc","b");
8165   //pic16_freeAsmop (right,NULL,ic,TRUE);
8166   //pic16_aopOp(left,ic,FALSE);
8167   //pic16_aopOp(result,ic,FALSE);
8168
8169   /* now move the left to the result if they are not the
8170      same */
8171   if (!pic16_sameRegs(AOP(left),AOP(result)) && 
8172       AOP_SIZE(result) > 1) {
8173
8174     size = AOP_SIZE(result);
8175     offset=0;
8176     while (size--) { 
8177       /*
8178         l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8179         if (*l == '@' && IS_AOP_PREG(result)) {
8180
8181         pic16_emitcode("mov","a,%s",l);
8182         pic16_aopPut(AOP(result),"a",offset);
8183         } else
8184         pic16_aopPut(AOP(result),l,offset);
8185       */
8186       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
8187       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
8188
8189       offset++;
8190     }
8191   }
8192
8193   /* mov the highest order bit to OVR */    
8194   tlbl = newiTempLabel(NULL);
8195   tlbl1= newiTempLabel(NULL);
8196
8197   size = AOP_SIZE(result);
8198   offset = size - 1;
8199
8200   pctemp = pic16_popGetTempReg();  /* grab a temporary working register. */
8201
8202   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8203
8204   /* offset should be 0, 1 or 3 */
8205   pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8206   emitSKPNZ;
8207   pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
8208
8209   pic16_emitpcode(POC_MOVWF, pctemp);
8210
8211
8212   pic16_emitpLabel(tlbl->key);
8213
8214   pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
8215   pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
8216
8217   while(--size) {
8218     pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
8219   }
8220
8221   pic16_emitpcode(POC_DECFSZ,  pctemp);
8222   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8223   pic16_emitpLabel(tlbl1->key);
8224
8225   pic16_popReleaseTempReg(pctemp);
8226 #if 0
8227   size = AOP_SIZE(result);
8228   offset = size - 1;
8229   pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8230   pic16_emitcode("rlc","a");
8231   pic16_emitcode("mov","ov,c");
8232   /* if it is only one byte then */
8233   if (size == 1) {
8234     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8235     MOVA(l);
8236     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8237     pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8238     pic16_emitcode("mov","c,ov");
8239     pic16_emitcode("rrc","a");
8240     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8241     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8242     pic16_aopPut(AOP(result),"a",0);
8243     goto release ;
8244   }
8245
8246   reAdjustPreg(AOP(result));
8247   pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8248   pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
8249   pic16_emitcode("mov","c,ov");
8250   while (size--) {
8251     l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8252     MOVA(l);
8253     pic16_emitcode("rrc","a");         
8254     pic16_aopPut(AOP(result),"a",offset--);
8255   }
8256   reAdjustPreg(AOP(result));
8257   pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8258   pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8259
8260  release:
8261 #endif
8262
8263   pic16_freeAsmop(left,NULL,ic,TRUE);
8264   pic16_freeAsmop(result,NULL,ic,TRUE);
8265   pic16_freeAsmop(right,NULL,ic,TRUE);
8266 }
8267
8268 /*-----------------------------------------------------------------*/
8269 /* genRightShift - generate code for right shifting                */
8270 /*-----------------------------------------------------------------*/
8271 static void genRightShift (iCode *ic)
8272 {
8273     operand *right, *left, *result;
8274     sym_link *letype ;
8275     int size, offset;
8276     char *l;
8277     symbol *tlbl, *tlbl1 ;
8278
8279     /* if signed then we do it the hard way preserve the
8280     sign bit moving it inwards */
8281     letype = getSpec(operandType(IC_LEFT(ic)));
8282     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8283
8284     if (!SPEC_USIGN(letype)) {
8285         genSignedRightShift (ic);
8286         return ;
8287     }
8288
8289     /* signed & unsigned types are treated the same : i.e. the
8290     signed is NOT propagated inwards : quoting from the
8291     ANSI - standard : "for E1 >> E2, is equivalent to division
8292     by 2**E2 if unsigned or if it has a non-negative value,
8293     otherwise the result is implementation defined ", MY definition
8294     is that the sign does not get propagated */
8295
8296     right = IC_RIGHT(ic);
8297     left  = IC_LEFT(ic);
8298     result = IC_RESULT(ic);
8299
8300     pic16_aopOp(right,ic,FALSE);
8301
8302     /* if the shift count is known then do it 
8303     as efficiently as possible */
8304     if (AOP_TYPE(right) == AOP_LIT) {
8305         genRightShiftLiteral (left,right,result,ic, 0);
8306         return ;
8307     }
8308
8309     /* shift count is unknown then we have to form 
8310     a loop get the loop count in B : Note: we take
8311     only the lower order byte since shifting
8312     more that 32 bits make no sense anyway, ( the
8313     largest size of an object can be only 32 bits ) */  
8314
8315     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8316     pic16_emitcode("inc","b");
8317     pic16_aopOp(left,ic,FALSE);
8318     pic16_aopOp(result,ic,FALSE);
8319
8320     /* now move the left to the result if they are not the
8321     same */
8322     if (!pic16_sameRegs(AOP(left),AOP(result)) && 
8323         AOP_SIZE(result) > 1) {
8324
8325         size = AOP_SIZE(result);
8326         offset=0;
8327         while (size--) {
8328             l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8329             if (*l == '@' && IS_AOP_PREG(result)) {
8330
8331                 pic16_emitcode("mov","a,%s",l);
8332                 pic16_aopPut(AOP(result),"a",offset);
8333             } else
8334                 pic16_aopPut(AOP(result),l,offset);
8335             offset++;
8336         }
8337     }
8338
8339     tlbl = newiTempLabel(NULL);
8340     tlbl1= newiTempLabel(NULL);
8341     size = AOP_SIZE(result);
8342     offset = size - 1;
8343
8344     /* if it is only one byte then */
8345     if (size == 1) {
8346
8347       tlbl = newiTempLabel(NULL);
8348       if (!pic16_sameRegs(AOP(left),AOP(result))) {
8349         pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
8350         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
8351       }
8352
8353       pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
8354       pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
8355       pic16_emitpLabel(tlbl->key);
8356       pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
8357       pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
8358       emitSKPC;
8359       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8360
8361       goto release ;
8362     }
8363
8364     reAdjustPreg(AOP(result));
8365     pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8366     pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
8367     CLRC;
8368     while (size--) {
8369         l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8370         MOVA(l);
8371         pic16_emitcode("rrc","a");         
8372         pic16_aopPut(AOP(result),"a",offset--);
8373     }
8374     reAdjustPreg(AOP(result));
8375
8376     pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8377     pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8378
8379 release:
8380     pic16_freeAsmop(left,NULL,ic,TRUE);
8381     pic16_freeAsmop (right,NULL,ic,TRUE);
8382     pic16_freeAsmop(result,NULL,ic,TRUE);
8383 }
8384
8385 /*-----------------------------------------------------------------*/
8386 /* genUnpackBits - generates code for unpacking bits               */
8387 /*-----------------------------------------------------------------*/
8388 static void genUnpackBits (operand *result, char *rname, int ptype)
8389 {    
8390     int shCnt ;
8391     int rlen = 0 ;
8392     sym_link *etype;
8393     int offset = 0 ;
8394
8395         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8396         etype = getSpec(operandType(result));
8397
8398         /* read the first byte  */
8399         switch (ptype) {
8400                 case POINTER:
8401                 case IPOINTER:
8402                 case PPOINTER:
8403                 case FPOINTER:
8404                 case GPOINTER:
8405                         pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8406                         break;
8407                 case CPOINTER:
8408                         pic16_emitcode("clr","a");
8409                         pic16_emitcode("movc","a","@a+dptr");
8410                         break;
8411         }
8412         
8413
8414         /* if we have bitdisplacement then it fits   */
8415         /* into this byte completely or if length is */
8416         /* less than a byte                          */
8417         if ((shCnt = SPEC_BSTR(etype)) || 
8418                 (SPEC_BLEN(etype) <= 8))  {
8419
8420                 /* shift right acc */
8421                 AccRsh(shCnt, 0);
8422
8423                 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8424                         (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8425
8426 /* VR -- normally I would use the following, but since we use the hack,
8427  * to avoid the masking from AccRsh, why not mask it right now? */
8428
8429 /*
8430                 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8431 */
8432
8433                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8434           return ;
8435         }
8436
8437
8438
8439         fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8440         fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8441         exit(-1);
8442
8443     /* bit field did not fit in a byte  */
8444     rlen = SPEC_BLEN(etype) - 8;
8445     pic16_aopPut(AOP(result),"a",offset++);
8446
8447     while (1)  {
8448
8449         switch (ptype) {
8450         case POINTER:
8451         case IPOINTER:
8452             pic16_emitcode("inc","%s",rname);
8453             pic16_emitcode("mov","a,@%s",rname);
8454             break;
8455             
8456         case PPOINTER:
8457             pic16_emitcode("inc","%s",rname);
8458             pic16_emitcode("movx","a,@%s",rname);
8459             break;
8460
8461         case FPOINTER:
8462             pic16_emitcode("inc","dptr");
8463             pic16_emitcode("movx","a,@dptr");
8464             break;
8465             
8466         case CPOINTER:
8467             pic16_emitcode("clr","a");
8468             pic16_emitcode("inc","dptr");
8469             pic16_emitcode("movc","a","@a+dptr");
8470             break;
8471             
8472         case GPOINTER:
8473             pic16_emitcode("inc","dptr");
8474             pic16_emitcode("lcall","__gptrget");
8475             break;
8476         }
8477
8478         rlen -= 8;            
8479         /* if we are done */
8480         if ( rlen <= 0 )
8481             break ;
8482         
8483         pic16_aopPut(AOP(result),"a",offset++);
8484                               
8485     }
8486     
8487     if (rlen) {
8488         pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8489         pic16_aopPut(AOP(result),"a",offset);          
8490     }
8491     
8492     return ;
8493 }
8494
8495
8496 static void genDataPointerGet(operand *left,
8497                               operand *result,
8498                               iCode *ic)
8499 {
8500   int size, offset = 0, leoffset=0 ;
8501
8502         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8503         pic16_aopOp(result, ic, FALSE);
8504
8505         size = AOP_SIZE(result);
8506 //      fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
8507
8508
8509 #if 0
8510         /* The following tests may save a redudant movff instruction when
8511          * accessing unions */
8512          
8513         /* if they are the same */
8514         if (operandsEqu (left, result)) {
8515                 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
8516                 goto release;
8517         }
8518
8519         /* if they are the same registers */
8520         if (pic16_sameRegs(AOP(left),AOP(result))) {
8521                 DEBUGpic16_emitcode("; ***", "left and result registers are same");
8522                 goto release;
8523         }
8524 #endif
8525
8526 #if 0
8527         if ( AOP_TYPE(left) == AOP_PCODE) {
8528                 fprintf(stderr,"genDataPointerGet   %s, %d\n",
8529                                 AOP(left)->aopu.pcop->name,
8530                                 (AOP(left)->aopu.pcop->type == PO_DIR)?
8531                                 PCOR(AOP(left)->aopu.pcop)->instance:
8532                                 PCOI(AOP(left)->aopu.pcop)->offset);
8533         }
8534 #endif
8535
8536         if(AOP(left)->aopu.pcop->type == PO_DIR)
8537                 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
8538
8539         DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8540
8541         while (size--) {
8542                 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
8543                 
8544                 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
8545                         || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
8546                         mov2w(AOP(left), leoffset);
8547                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
8548                 } else {
8549                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
8550                                 pic16_popGet(AOP(left), leoffset),
8551                                 pic16_popGet(AOP(result), offset)));
8552                 }
8553
8554                 offset++;
8555                 leoffset++;
8556         }
8557
8558 //release:
8559     pic16_freeAsmop(result,NULL,ic,TRUE);
8560 }
8561
8562 void pic16_loadFSR0(operand *op)
8563 {
8564         pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
8565 }
8566
8567
8568 /*-----------------------------------------------------------------*/
8569 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
8570 /*-----------------------------------------------------------------*/
8571 static void genNearPointerGet (operand *left, 
8572                                operand *result, 
8573                                iCode *ic)
8574 {
8575     asmop *aop = NULL;
8576     //regs *preg = NULL ;
8577     sym_link *rtype, *retype;
8578     sym_link *ltype = operandType(left);    
8579
8580         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8581
8582         rtype = operandType(result);
8583         retype= getSpec(rtype);
8584     
8585         pic16_aopOp(left,ic,FALSE);
8586
8587         /* if left is rematerialisable and
8588          * result is not bit variable type and
8589          * the left is pointer to data space i.e
8590          * lower 128 bytes of space */
8591         if (AOP_TYPE(left) == AOP_PCODE
8592                 && !IS_BITFIELD(retype)
8593                 && DCL_TYPE(ltype) == POINTER) {
8594
8595                 genDataPointerGet (left,result,ic);
8596                 pic16_freeAsmop(left, NULL, ic, TRUE);
8597           return ;
8598         }
8599     
8600         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8601
8602         /* if the value is already in a pointer register
8603          * then don't need anything more */
8604         if (!AOP_INPREG(AOP(left))) {
8605                 /* otherwise get a free pointer register */
8606                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8607                 
8608                 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
8609                 pic16_loadFSR0( left );
8610         }
8611 //       else
8612 //      rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8613     
8614     pic16_aopOp (result,ic,FALSE);
8615     
8616       /* if bitfield then unpack the bits */
8617     if (IS_BITFIELD(retype)) 
8618         genUnpackBits (result, NULL, POINTER);
8619     else {
8620         /* we have can just get the values */
8621       int size = AOP_SIZE(result);
8622       int offset = 0;   
8623         
8624       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8625
8626
8627         /* fsr0 is loaded already -- VR */
8628 //      pic16_loadFSR0( left );
8629
8630 //      pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8631 //      pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8632       while(size--) {
8633
8634         if(size) {
8635                 pic16_emitpcode(POC_MOVFF,
8636                         pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
8637                                 pic16_popGet(AOP(result), offset++)));
8638         } else {
8639                 pic16_emitpcode(POC_MOVFF,
8640                         pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
8641                                 pic16_popGet(AOP(result), offset++)));
8642         }
8643       }
8644 #if 0
8645 //      pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
8646 //      pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8647         if(size)
8648           pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8649 #endif
8650 /*
8651         while (size--) {
8652             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8653
8654                 pic16_emitcode("mov","a,@%s",rname);
8655                 pic16_aopPut(AOP(result),"a",offset);
8656             } else {
8657                 sprintf(buffer,"@%s",rname);
8658                 pic16_aopPut(AOP(result),buffer,offset);
8659             }
8660             offset++ ;
8661             if (size)
8662                 pic16_emitcode("inc","%s",rname);
8663         }
8664 */
8665     }
8666
8667     /* now some housekeeping stuff */
8668     if (aop) {
8669         /* we had to allocate for this iCode */
8670     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8671         pic16_freeAsmop(NULL,aop,ic,TRUE);
8672     } else { 
8673         /* we did not allocate which means left
8674            already in a pointer register, then
8675            if size > 0 && this could be used again
8676            we have to point it back to where it 
8677            belongs */
8678     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8679         if (AOP_SIZE(result) > 1 &&
8680             !OP_SYMBOL(left)->remat &&
8681             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8682               ic->depth )) {
8683 //          int size = AOP_SIZE(result) - 1;
8684 //          while (size--)
8685 //              pic16_emitcode("dec","%s",rname);
8686         }
8687     }
8688
8689     /* done */
8690     pic16_freeAsmop(left,NULL,ic,TRUE);
8691     pic16_freeAsmop(result,NULL,ic,TRUE);
8692      
8693 }
8694
8695 /*-----------------------------------------------------------------*/
8696 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
8697 /*-----------------------------------------------------------------*/
8698 static void genPagedPointerGet (operand *left, 
8699                                operand *result, 
8700                                iCode *ic)
8701 {
8702     asmop *aop = NULL;
8703     regs *preg = NULL ;
8704     char *rname ;
8705     sym_link *rtype, *retype;    
8706
8707     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8708
8709     rtype = operandType(result);
8710     retype= getSpec(rtype);
8711     
8712     pic16_aopOp(left,ic,FALSE);
8713
8714   /* if the value is already in a pointer register
8715        then don't need anything more */
8716     if (!AOP_INPREG(AOP(left))) {
8717         /* otherwise get a free pointer register */
8718         aop = newAsmop(0);
8719         preg = getFreePtr(ic,&aop,FALSE);
8720         pic16_emitcode("mov","%s,%s",
8721                 preg->name,
8722                 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8723         rname = preg->name ;
8724     } else
8725         rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8726     
8727     pic16_freeAsmop(left,NULL,ic,TRUE);
8728     pic16_aopOp (result,ic,FALSE);
8729
8730     /* if bitfield then unpack the bits */
8731     if (IS_BITFIELD(retype)) 
8732         genUnpackBits (result,rname,PPOINTER);
8733     else {
8734         /* we have can just get the values */
8735         int size = AOP_SIZE(result);
8736         int offset = 0 ;        
8737         
8738         while (size--) {
8739             
8740             pic16_emitcode("movx","a,@%s",rname);
8741             pic16_aopPut(AOP(result),"a",offset);
8742             
8743             offset++ ;
8744             
8745             if (size)
8746                 pic16_emitcode("inc","%s",rname);
8747         }
8748     }
8749
8750     /* now some housekeeping stuff */
8751     if (aop) {
8752         /* we had to allocate for this iCode */
8753         pic16_freeAsmop(NULL,aop,ic,TRUE);
8754     } else { 
8755         /* we did not allocate which means left
8756            already in a pointer register, then
8757            if size > 0 && this could be used again
8758            we have to point it back to where it 
8759            belongs */
8760         if (AOP_SIZE(result) > 1 &&
8761             !OP_SYMBOL(left)->remat &&
8762             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8763               ic->depth )) {
8764             int size = AOP_SIZE(result) - 1;
8765             while (size--)
8766                 pic16_emitcode("dec","%s",rname);
8767         }
8768     }
8769
8770     /* done */
8771     pic16_freeAsmop(result,NULL,ic,TRUE);
8772     
8773         
8774 }
8775
8776 /*-----------------------------------------------------------------*/
8777 /* genFarPointerGet - gget value from far space                    */
8778 /*-----------------------------------------------------------------*/
8779 static void genFarPointerGet (operand *left,
8780                               operand *result, iCode *ic)
8781 {
8782     int size, offset ;
8783     sym_link *retype = getSpec(operandType(result));
8784
8785     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8786
8787     pic16_aopOp(left,ic,FALSE);
8788
8789     /* if the operand is already in dptr 
8790     then we do nothing else we move the value to dptr */
8791     if (AOP_TYPE(left) != AOP_STR) {
8792         /* if this is remateriazable */
8793         if (AOP_TYPE(left) == AOP_IMMD)
8794             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8795         else { /* we need to get it byte by byte */
8796             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8797             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8798             if (options.model == MODEL_FLAT24)
8799             {
8800                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8801             }
8802         }
8803     }
8804     /* so dptr know contains the address */
8805     pic16_freeAsmop(left,NULL,ic,TRUE);
8806     pic16_aopOp(result,ic,FALSE);
8807
8808     /* if bit then unpack */
8809     if (IS_BITFIELD(retype)) 
8810         genUnpackBits(result,"dptr",FPOINTER);
8811     else {
8812         size = AOP_SIZE(result);
8813         offset = 0 ;
8814
8815         while (size--) {
8816             pic16_emitcode("movx","a,@dptr");
8817             pic16_aopPut(AOP(result),"a",offset++);
8818             if (size)
8819                 pic16_emitcode("inc","dptr");
8820         }
8821     }
8822
8823     pic16_freeAsmop(result,NULL,ic,TRUE);
8824 }
8825 #if 0
8826 /*-----------------------------------------------------------------*/
8827 /* genCodePointerGet - get value from code space                  */
8828 /*-----------------------------------------------------------------*/
8829 static void genCodePointerGet (operand *left,
8830                                 operand *result, iCode *ic)
8831 {
8832     int size, offset ;
8833     sym_link *retype = getSpec(operandType(result));
8834
8835     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8836
8837     pic16_aopOp(left,ic,FALSE);
8838
8839     /* if the operand is already in dptr 
8840     then we do nothing else we move the value to dptr */
8841     if (AOP_TYPE(left) != AOP_STR) {
8842         /* if this is remateriazable */
8843         if (AOP_TYPE(left) == AOP_IMMD)
8844             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8845         else { /* we need to get it byte by byte */
8846             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8847             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8848             if (options.model == MODEL_FLAT24)
8849             {
8850                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8851             }
8852         }
8853     }
8854     /* so dptr know contains the address */
8855     pic16_freeAsmop(left,NULL,ic,TRUE);
8856     pic16_aopOp(result,ic,FALSE);
8857
8858     /* if bit then unpack */
8859     if (IS_BITFIELD(retype)) 
8860         genUnpackBits(result,"dptr",CPOINTER);
8861     else {
8862         size = AOP_SIZE(result);
8863         offset = 0 ;
8864
8865         while (size--) {
8866             pic16_emitcode("clr","a");
8867             pic16_emitcode("movc","a,@a+dptr");
8868             pic16_aopPut(AOP(result),"a",offset++);
8869             if (size)
8870                 pic16_emitcode("inc","dptr");
8871         }
8872     }
8873
8874     pic16_freeAsmop(result,NULL,ic,TRUE);
8875 }
8876 #endif
8877 /*-----------------------------------------------------------------*/
8878 /* genGenPointerGet - gget value from generic pointer space        */
8879 /*-----------------------------------------------------------------*/
8880 static void genGenPointerGet (operand *left,
8881                               operand *result, iCode *ic)
8882 {
8883   int size, offset, lit;
8884   sym_link *retype = getSpec(operandType(result));
8885
8886         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8887         pic16_aopOp(left,ic,FALSE);
8888         pic16_aopOp(result,ic,FALSE);
8889         size = AOP_SIZE(result);
8890
8891         DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8892
8893         if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
8894
8895                 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
8896                 // load FSR0 from immediate
8897                 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
8898
8899 //              pic16_loadFSR0( left );
8900
8901                 offset = 0;
8902                 while(size--) {
8903                         if(size) {
8904                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8905                         } else {
8906                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8907                         }
8908                         offset++;
8909                 }
8910                 goto release;
8911
8912         }
8913         else { /* we need to get it byte by byte */
8914                 // set up FSR0 with address from left
8915                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
8916                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
8917
8918                 offset = 0 ;
8919
8920                 while(size--) {
8921                         if(size) {
8922                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8923                         } else {
8924                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8925                         }
8926                         offset++;
8927                 }
8928                 goto release;
8929         }
8930
8931   /* if bit then unpack */
8932         if (IS_BITFIELD(retype)) 
8933                 genUnpackBits(result,"BAD",GPOINTER);
8934
8935         release:
8936         pic16_freeAsmop(left,NULL,ic,TRUE);
8937         pic16_freeAsmop(result,NULL,ic,TRUE);
8938
8939 }
8940
8941 /*-----------------------------------------------------------------*/
8942 /* genConstPointerGet - get value from const generic pointer space */
8943 /*-----------------------------------------------------------------*/
8944 static void genConstPointerGet (operand *left,
8945                                 operand *result, iCode *ic)
8946 {
8947   //sym_link *retype = getSpec(operandType(result));
8948   symbol *albl = newiTempLabel(NULL);
8949   symbol *blbl = newiTempLabel(NULL);
8950   PIC_OPCODE poc;
8951
8952   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8953   pic16_aopOp(left,ic,FALSE);
8954   pic16_aopOp(result,ic,FALSE);
8955
8956
8957   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8958
8959   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8960
8961   pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8962   pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8963   pic16_emitpLabel(albl->key);
8964
8965   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8966     
8967   /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8968   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8969   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8970   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8971   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8972
8973   pic16_emitpLabel(blbl->key);
8974
8975   pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8976
8977
8978   pic16_freeAsmop(left,NULL,ic,TRUE);
8979   pic16_freeAsmop(result,NULL,ic,TRUE);
8980
8981 }
8982 /*-----------------------------------------------------------------*/
8983 /* genPointerGet - generate code for pointer get                   */
8984 /*-----------------------------------------------------------------*/
8985 static void genPointerGet (iCode *ic)
8986 {
8987     operand *left, *result ;
8988     sym_link *type, *etype;
8989     int p_type;
8990
8991     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8992
8993     left = IC_LEFT(ic);
8994     result = IC_RESULT(ic) ;
8995
8996     /* depending on the type of pointer we need to
8997     move it to the correct pointer register */
8998     type = operandType(left);
8999     etype = getSpec(type);
9000
9001 #if 0
9002     if (IS_PTR_CONST(type))
9003 #else
9004     if (IS_CODEPTR(type))
9005 #endif
9006       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9007
9008     /* if left is of type of pointer then it is simple */
9009     if (IS_PTR(type) && !IS_FUNC(type->next)) 
9010         p_type = DCL_TYPE(type);
9011     else {
9012         /* we have to go by the storage class */
9013         p_type = PTR_TYPE(SPEC_OCLS(etype));
9014
9015         DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9016
9017         if (SPEC_OCLS(etype)->codesp ) {
9018           DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9019           //p_type = CPOINTER ; 
9020         }
9021         else
9022             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9023               DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9024                /*p_type = FPOINTER ;*/ 
9025             else
9026                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9027                   DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9028 /*                  p_type = PPOINTER; */
9029                 else
9030                     if (SPEC_OCLS(etype) == idata )
9031                       DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9032 /*                      p_type = IPOINTER; */
9033                     else
9034                       DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9035 /*                      p_type = POINTER ; */
9036     }
9037
9038     /* now that we have the pointer type we assign
9039     the pointer values */
9040     switch (p_type) {
9041
9042     case POINTER:       
9043     case IPOINTER:
9044         genNearPointerGet (left,result,ic);
9045         break;
9046
9047     case PPOINTER:
9048         genPagedPointerGet(left,result,ic);
9049         break;
9050
9051     case FPOINTER:
9052         genFarPointerGet (left,result,ic);
9053         break;
9054
9055     case CPOINTER:
9056         genConstPointerGet (left,result,ic);
9057         //pic16_emitcodePointerGet (left,result,ic);
9058         break;
9059
9060     case GPOINTER:
9061 #if 0
9062       if (IS_PTR_CONST(type))
9063         genConstPointerGet (left,result,ic);
9064       else
9065 #endif
9066         genGenPointerGet (left,result,ic);
9067       break;
9068     }
9069
9070 }
9071
9072 /*-----------------------------------------------------------------*/
9073 /* genPackBits - generates code for packed bit storage             */
9074 /*-----------------------------------------------------------------*/
9075 static void genPackBits (sym_link    *etype ,
9076                          operand *right ,
9077                          char *rname, int p_type)
9078 {
9079   int shCnt = 0 ;
9080   int offset = 0  ;
9081   int rLen = 0 ;
9082   int blen, bstr ;   
9083   char *l ;
9084
9085         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9086         blen = SPEC_BLEN(etype);
9087         bstr = SPEC_BSTR(etype);
9088
9089         if(AOP_TYPE(right) == AOP_LIT) {
9090                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9091                 offset++;
9092         } else
9093                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9094
9095 /*      l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9096         MOVA(l);   
9097 */
9098         /* if the bit lenth is less than or    */
9099         /* it exactly fits a byte then         */
9100         if((shCnt=SPEC_BSTR(etype))
9101                 || SPEC_BLEN(etype) <= 8 )  {
9102
9103                 /* shift left acc */
9104                 AccLsh(shCnt);
9105
9106                 /* using PRODL as a temporary register here */
9107                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9108
9109                 switch (p_type) {
9110                         case FPOINTER:
9111                         case POINTER:
9112                         case GPOINTER:
9113                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9114 //                              pic16_emitcode ("mov","b,a");
9115 //                              pic16_emitcode("mov","a,@%s",rname);
9116                                 break;
9117                 }
9118 #if 1
9119                 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9120                         (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9121                                         (unsigned char)(0xff >> (8-bstr))) ));
9122                 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9123                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9124 #endif
9125
9126 #if 0
9127                 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9128                                         ((unsigned char)(0xFF << (blen+bstr)) | 
9129                                         (unsigned char)(0xFF >> (8-bstr)) ) );
9130                 pic16_emitcode ("orl","a,b");
9131                 if (p_type == GPOINTER)
9132                         pic16_emitcode("pop","b");
9133
9134                 
9135                 switch (p_type) {
9136                         case POINTER:
9137                                 pic16_emitcode("mov","@%s,a",rname);
9138                                 break;
9139                         case FPOINTER:
9140                                 pic16_emitcode("movx","@dptr,a");
9141                                 break;
9142                         case GPOINTER:
9143                                 DEBUGpic16_emitcode(";lcall","__gptrput");
9144                                 break;
9145                 }
9146 #endif
9147
9148           return;
9149         }
9150
9151
9152         fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9153         fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9154         exit(-1);
9155
9156
9157     /* if we r done */
9158     if ( SPEC_BLEN(etype) <= 8 )
9159         return ;
9160
9161     pic16_emitcode("inc","%s",rname);
9162     rLen = SPEC_BLEN(etype) ;     
9163
9164
9165
9166     /* now generate for lengths greater than one byte */
9167     while (1) {
9168
9169         l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9170
9171         rLen -= 8 ;
9172         if (rLen <= 0 )
9173             break ;
9174
9175         switch (p_type) {
9176             case POINTER:
9177                 if (*l == '@') {
9178                     MOVA(l);
9179                     pic16_emitcode("mov","@%s,a",rname);
9180                 } else
9181                     pic16_emitcode("mov","@%s,%s",rname,l);
9182                 break;
9183
9184             case FPOINTER:
9185                 MOVA(l);
9186                 pic16_emitcode("movx","@dptr,a");
9187                 break;
9188
9189             case GPOINTER:
9190                 MOVA(l);
9191                 DEBUGpic16_emitcode(";lcall","__gptrput");
9192                 break;  
9193         }   
9194         pic16_emitcode ("inc","%s",rname);
9195     }
9196
9197     MOVA(l);
9198
9199     /* last last was not complete */
9200     if (rLen)   {
9201         /* save the byte & read byte */
9202         switch (p_type) {
9203             case POINTER:
9204                 pic16_emitcode ("mov","b,a");
9205                 pic16_emitcode("mov","a,@%s",rname);
9206                 break;
9207
9208             case FPOINTER:
9209                 pic16_emitcode ("mov","b,a");
9210                 pic16_emitcode("movx","a,@dptr");
9211                 break;
9212
9213             case GPOINTER:
9214                 pic16_emitcode ("push","b");
9215                 pic16_emitcode ("push","acc");
9216                 pic16_emitcode ("lcall","__gptrget");
9217                 pic16_emitcode ("pop","b");
9218                 break;
9219         }
9220
9221         pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9222         pic16_emitcode ("orl","a,b");
9223     }
9224
9225     if (p_type == GPOINTER)
9226         pic16_emitcode("pop","b");
9227
9228     switch (p_type) {
9229
9230     case POINTER:
9231         pic16_emitcode("mov","@%s,a",rname);
9232         break;
9233         
9234     case FPOINTER:
9235         pic16_emitcode("movx","@dptr,a");
9236         break;
9237         
9238     case GPOINTER:
9239         DEBUGpic16_emitcode(";lcall","__gptrput");
9240         break;                  
9241     }
9242 }
9243 /*-----------------------------------------------------------------*/
9244 /* genDataPointerSet - remat pointer to data space                 */
9245 /*-----------------------------------------------------------------*/
9246 static void genDataPointerSet(operand *right,
9247                               operand *result,
9248                               iCode *ic)
9249 {
9250     int size, offset = 0, resoffset=0 ;
9251
9252     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9253     pic16_aopOp(right,ic,FALSE);
9254
9255     size = AOP_SIZE(right);
9256         fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9257
9258 #if 1
9259     if ( AOP_TYPE(result) == AOP_PCODE) {
9260       fprintf(stderr,"genDataPointerSet   %s, %d\n",
9261               AOP(result)->aopu.pcop->name,
9262                 (AOP(result)->aopu.pcop->type == PO_DIR)?
9263               PCOR(AOP(result)->aopu.pcop)->instance:
9264               PCOI(AOP(result)->aopu.pcop)->offset);
9265     }
9266 #endif
9267
9268         if(AOP(result)->aopu.pcop->type == PO_DIR)
9269                 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9270
9271         while (size--) {
9272                 if (AOP_TYPE(right) == AOP_LIT) {
9273                   unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9274
9275                         lit = lit >> (8*offset);
9276                         if(lit&0xff) {
9277                                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9278                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9279                         } else {
9280                                 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),resoffset));
9281                         }
9282                 } else {
9283                         mov2w(AOP(right), offset);
9284                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9285                 }
9286                 offset++;
9287                 resoffset++;
9288         }
9289
9290     pic16_freeAsmop(right,NULL,ic,TRUE);
9291 }
9292
9293
9294
9295 /*-----------------------------------------------------------------*/
9296 /* genNearPointerSet - pic16_emitcode for near pointer put         */
9297 /*-----------------------------------------------------------------*/
9298 static void genNearPointerSet (operand *right,
9299                                operand *result, 
9300                                iCode *ic)
9301 {
9302   asmop *aop = NULL;
9303   char *l;
9304   sym_link *retype;
9305   sym_link *ptype = operandType(result);
9306   sym_link *resetype;
9307     
9308         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9309         retype= getSpec(operandType(right));
9310         resetype = getSpec(operandType(result));
9311   
9312         pic16_aopOp(result,ic,FALSE);
9313     
9314         /* if the result is rematerializable &
9315          * in data space & not a bit variable */
9316         
9317         /* and result is not a bit variable */
9318         if (AOP_TYPE(result) == AOP_PCODE
9319 //              && AOP_TYPE(result) == AOP_IMMD
9320                 && DCL_TYPE(ptype) == POINTER
9321                 && !IS_BITFIELD(retype)
9322                 && !IS_BITFIELD(resetype)) {
9323
9324                 genDataPointerSet (right,result,ic);
9325                 pic16_freeAsmop(result,NULL,ic,TRUE);
9326           return;
9327         }
9328
9329         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9330         pic16_aopOp(right,ic,FALSE);
9331         DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9332
9333         /* if the value is already in a pointer register
9334          * then don't need anything more */
9335         if (!AOP_INPREG(AOP(result))) {
9336                 /* otherwise get a free pointer register */
9337                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9338
9339                 pic16_loadFSR0( result );
9340         }
9341 //      else
9342 //      rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9343
9344         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9345
9346         /* if bitfield then unpack the bits */
9347         if (IS_BITFIELD(resetype)) {
9348                 genPackBits (resetype, right, NULL, POINTER);
9349         } else {
9350                 /* we have can just get the values */
9351           int size = AOP_SIZE(right);
9352           int offset = 0 ;    
9353
9354                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9355                 while (size--) {
9356                         l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9357                         if (*l == '@' ) {
9358                                 //MOVA(l);
9359                                 //pic16_emitcode("mov","@%s,a",rname);
9360                                 pic16_emitcode("movf","indf0,w ;1");
9361                         } else {
9362
9363                                 if (AOP_TYPE(right) == AOP_LIT) {
9364                                   unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9365
9366                                         if(lit) {
9367                                                 pic16_emitcode("movlw","%s",l);
9368                                                 pic16_emitcode("movwf","indf0 ;2");
9369                                         } else 
9370                                                 pic16_emitcode("clrf","indf0");
9371                                 } else {
9372                                         pic16_emitcode("movf","%s,w",l);
9373                                         pic16_emitcode("movwf","indf0 ;2");
9374                                 }
9375                                 //pic16_emitcode("mov","@%s,%s",rname,l);
9376                         }
9377                         if (size)
9378                                 pic16_emitcode("incf","fsr0,f ;3");
9379                         //pic16_emitcode("inc","%s",rname);
9380                         offset++;
9381                 }
9382         }
9383
9384         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9385         /* now some housekeeping stuff */
9386         if (aop) {
9387                 /* we had to allocate for this iCode */
9388                 pic16_freeAsmop(NULL,aop,ic,TRUE);
9389         } else { 
9390                 /* we did not allocate which means left
9391                  * already in a pointer register, then
9392                  * if size > 0 && this could be used again
9393                  * we have to point it back to where it 
9394                  * belongs */
9395                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9396                 if (AOP_SIZE(right) > 1
9397                         && !OP_SYMBOL(result)->remat
9398                         && ( OP_SYMBOL(result)->liveTo > ic->seq
9399                                 || ic->depth )) {
9400
9401                   int size = AOP_SIZE(right) - 1;
9402
9403                         while (size--)
9404                                 pic16_emitcode("decf","fsr0,f");
9405                         //pic16_emitcode("dec","%s",rname);
9406                 }
9407         }
9408
9409         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9410         /* done */
9411 //release:
9412         pic16_freeAsmop(right,NULL,ic,TRUE);
9413         pic16_freeAsmop(result,NULL,ic,TRUE);
9414 }
9415
9416 /*-----------------------------------------------------------------*/
9417 /* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
9418 /*-----------------------------------------------------------------*/
9419 static void genPagedPointerSet (operand *right,
9420                                operand *result, 
9421                                iCode *ic)
9422 {
9423     asmop *aop = NULL;
9424     regs *preg = NULL ;
9425     char *rname , *l;
9426     sym_link *retype;
9427        
9428     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9429
9430     retype= getSpec(operandType(right));
9431     
9432     pic16_aopOp(result,ic,FALSE);
9433     
9434     /* if the value is already in a pointer register
9435        then don't need anything more */
9436     if (!AOP_INPREG(AOP(result))) {
9437         /* otherwise get a free pointer register */
9438         aop = newAsmop(0);
9439         preg = getFreePtr(ic,&aop,FALSE);
9440         pic16_emitcode("mov","%s,%s",
9441                 preg->name,
9442                 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9443         rname = preg->name ;
9444     } else
9445         rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9446     
9447     pic16_freeAsmop(result,NULL,ic,TRUE);
9448     pic16_aopOp (right,ic,FALSE);
9449
9450     /* if bitfield then unpack the bits */
9451     if (IS_BITFIELD(retype)) 
9452         genPackBits (retype,right,rname,PPOINTER);
9453     else {
9454         /* we have can just get the values */
9455         int size = AOP_SIZE(right);
9456         int offset = 0 ;        
9457         
9458         while (size--) {
9459             l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9460             
9461             MOVA(l);
9462             pic16_emitcode("movx","@%s,a",rname);
9463
9464             if (size)
9465                 pic16_emitcode("inc","%s",rname);
9466
9467             offset++;
9468         }
9469     }
9470     
9471     /* now some housekeeping stuff */
9472     if (aop) {
9473         /* we had to allocate for this iCode */
9474         pic16_freeAsmop(NULL,aop,ic,TRUE);
9475     } else { 
9476         /* we did not allocate which means left
9477            already in a pointer register, then
9478            if size > 0 && this could be used again
9479            we have to point it back to where it 
9480            belongs */
9481         if (AOP_SIZE(right) > 1 &&
9482             !OP_SYMBOL(result)->remat &&
9483             ( OP_SYMBOL(result)->liveTo > ic->seq ||
9484               ic->depth )) {
9485             int size = AOP_SIZE(right) - 1;
9486             while (size--)
9487                 pic16_emitcode("dec","%s",rname);
9488         }
9489     }
9490
9491     /* done */
9492     pic16_freeAsmop(right,NULL,ic,TRUE);
9493     
9494         
9495 }
9496
9497 /*-----------------------------------------------------------------*/
9498 /* genFarPointerSet - set value from far space                     */
9499 /*-----------------------------------------------------------------*/
9500 static void genFarPointerSet (operand *right,
9501                               operand *result, iCode *ic)
9502 {
9503     int size, offset ;
9504     sym_link *retype = getSpec(operandType(right));
9505
9506     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9507     pic16_aopOp(result,ic,FALSE);
9508
9509     /* if the operand is already in dptr 
9510     then we do nothing else we move the value to dptr */
9511     if (AOP_TYPE(result) != AOP_STR) {
9512         /* if this is remateriazable */
9513         if (AOP_TYPE(result) == AOP_IMMD)
9514             pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9515         else { /* we need to get it byte by byte */
9516             pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9517             pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9518             if (options.model == MODEL_FLAT24)
9519             {
9520                pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9521             }
9522         }
9523     }
9524     /* so dptr know contains the address */
9525     pic16_freeAsmop(result,NULL,ic,TRUE);
9526     pic16_aopOp(right,ic,FALSE);
9527
9528     /* if bit then unpack */
9529     if (IS_BITFIELD(retype)) 
9530         genPackBits(retype,right,"dptr",FPOINTER);
9531     else {
9532         size = AOP_SIZE(right);
9533         offset = 0 ;
9534
9535         while (size--) {
9536             char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9537             MOVA(l);
9538             pic16_emitcode("movx","@dptr,a");
9539             if (size)
9540                 pic16_emitcode("inc","dptr");
9541         }
9542     }
9543
9544     pic16_freeAsmop(right,NULL,ic,TRUE);
9545 }
9546
9547 /*-----------------------------------------------------------------*/
9548 /* genGenPointerSet - set value from generic pointer space         */
9549 /*-----------------------------------------------------------------*/
9550 static void genGenPointerSet (operand *right,
9551                               operand *result, iCode *ic)
9552 {
9553         int size, offset, lit;
9554         sym_link *retype = getSpec(operandType(right));
9555
9556         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9557
9558         pic16_aopOp(result,ic,FALSE);
9559         pic16_aopOp(right,ic,FALSE);
9560         size = AOP_SIZE(right);
9561         offset = 0;
9562
9563         DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9564
9565         /* if the operand is already in dptr 
9566                 then we do nothing else we move the value to dptr */
9567         if (AOP_TYPE(result) != AOP_STR) {
9568                 /* if this is remateriazable */
9569                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9570                 // WARNING: anythig until "else" is untested!
9571                 if (AOP_TYPE(result) == AOP_IMMD) {
9572                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9573                         lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
9574                         // load FSR0 from immediate
9575                         pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9576                         offset = 0;
9577                         while(size--) {
9578                                 if(size) {
9579                                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9580                                 } else {
9581                                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9582                                 }
9583                                 offset++;
9584                         }
9585                         goto release;
9586                 }
9587                 else { /* we need to get it byte by byte */
9588                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9589                         //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9590
9591                         // set up FSR0 with address of result
9592                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9593                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9594
9595                         /* hack hack! see if this the FSR. If so don't load W */
9596                         if(AOP_TYPE(right) != AOP_ACC) {
9597
9598                                 DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9599
9600                                 while(size--) {
9601                                         if(size) {
9602                                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9603                                         } else {
9604                                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9605                                         }
9606                                         offset++;
9607                                 }
9608                                 goto release;
9609                         } 
9610                         // right = ACC
9611                         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9612                         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9613                         goto release;
9614         } // if (AOP_TYPE(result) != AOP_IMMD)
9615
9616         } // if (AOP_TYPE(result) != AOP_STR)
9617         /* so dptr know contains the address */
9618
9619
9620         /* if bit then unpack */
9621         if (IS_BITFIELD(retype)) 
9622                 genPackBits(retype,right,"dptr",GPOINTER);
9623         else {
9624                 size = AOP_SIZE(right);
9625                 offset = 0 ;
9626
9627                 DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9628
9629                 // set up FSR0 with address of result
9630                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9631                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9632         
9633                 while (size--) {
9634                         if (AOP_TYPE(right) == AOP_LIT) {
9635                                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9636                                 if (size) {
9637                                         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
9638                                 } else {
9639                                         pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9640                                 }
9641                         } else { // no literal
9642                                 if(size) {
9643                                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9644                                 } else {
9645                                         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9646                                 }
9647                         }
9648                         offset++;
9649         }
9650         }
9651
9652         release:
9653         pic16_freeAsmop(right,NULL,ic,TRUE);
9654         pic16_freeAsmop(result,NULL,ic,TRUE);
9655 }
9656
9657 /*-----------------------------------------------------------------*/
9658 /* genPointerSet - stores the value into a pointer location        */
9659 /*-----------------------------------------------------------------*/
9660 static void genPointerSet (iCode *ic)
9661 {    
9662     operand *right, *result ;
9663     sym_link *type, *etype;
9664     int p_type;
9665
9666     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9667
9668     right = IC_RIGHT(ic);
9669     result = IC_RESULT(ic) ;
9670
9671     /* depending on the type of pointer we need to
9672     move it to the correct pointer register */
9673     type = operandType(result);
9674     etype = getSpec(type);
9675     /* if left is of type of pointer then it is simple */
9676     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9677         p_type = DCL_TYPE(type);
9678     }
9679     else {
9680         /* we have to go by the storage class */
9681         p_type = PTR_TYPE(SPEC_OCLS(etype));
9682
9683 /*      if (SPEC_OCLS(etype)->codesp ) { */
9684 /*          p_type = CPOINTER ;  */
9685 /*      } */
9686 /*      else */
9687 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9688 /*              p_type = FPOINTER ; */
9689 /*          else */
9690 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9691 /*                  p_type = PPOINTER ; */
9692 /*              else */
9693 /*                  if (SPEC_OCLS(etype) == idata ) */
9694 /*                      p_type = IPOINTER ; */
9695 /*                  else */
9696 /*                      p_type = POINTER ; */
9697     }
9698
9699     /* now that we have the pointer type we assign
9700     the pointer values */
9701     switch (p_type) {
9702
9703     case POINTER:
9704     case IPOINTER:
9705         genNearPointerSet (right,result,ic);
9706         break;
9707
9708     case PPOINTER:
9709         genPagedPointerSet (right,result,ic);
9710         break;
9711
9712     case FPOINTER:
9713         genFarPointerSet (right,result,ic);
9714         break;
9715
9716     case GPOINTER:
9717         genGenPointerSet (right,result,ic);
9718         break;
9719
9720     default:
9721       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9722               "genPointerSet: illegal pointer type");
9723     }
9724 }
9725
9726 /*-----------------------------------------------------------------*/
9727 /* genIfx - generate code for Ifx statement                        */
9728 /*-----------------------------------------------------------------*/
9729 static void genIfx (iCode *ic, iCode *popIc)
9730 {
9731   operand *cond = IC_COND(ic);
9732   int isbit =0;
9733
9734   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9735
9736   pic16_aopOp(cond,ic,FALSE);
9737
9738   /* get the value into acc */
9739   if (AOP_TYPE(cond) != AOP_CRY)
9740     pic16_toBoolean(cond);
9741   else
9742     isbit = 1;
9743   /* the result is now in the accumulator */
9744   pic16_freeAsmop(cond,NULL,ic,TRUE);
9745
9746   /* if there was something to be popped then do it */
9747   if (popIc)
9748     genIpop(popIc);
9749
9750   /* if the condition is  a bit variable */
9751   if (isbit && IS_ITEMP(cond) && 
9752       SPIL_LOC(cond)) {
9753     genIfxJump(ic,SPIL_LOC(cond)->rname);
9754     DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9755   }
9756   else {
9757     if (isbit && !IS_ITEMP(cond))
9758       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9759     else
9760       genIfxJump(ic,"a");
9761   }
9762   ic->generated = 1;
9763
9764 }
9765
9766 /*-----------------------------------------------------------------*/
9767 /* genAddrOf - generates code for address of                       */
9768 /*-----------------------------------------------------------------*/
9769 static void genAddrOf (iCode *ic)
9770 {
9771   operand *result, *left;
9772   int size;
9773   symbol *sym;  // = OP_SYMBOL(IC_LEFT(ic));
9774   pCodeOp *pcop0, *pcop1, *pcop2;
9775
9776         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9777
9778         pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9779         pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9780
9781         sym = OP_SYMBOL( left );
9782
9783         size = AOP_SIZE(IC_RESULT(ic));
9784
9785         if(pic16_debug_verbose) {
9786                 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9787                         __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9788         }
9789         
9790         /* Assume that what we want the address of is in data space
9791          * since there is no stack on the PIC, yet! -- VR */
9792         /* low */
9793         pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9794
9795         /* high */
9796         pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9797         
9798         /* upper */
9799         pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9800         
9801
9802         if (size == 3) {
9803                 pic16_emitpcode(POC_MOVLW, pcop0);
9804                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9805                 pic16_emitpcode(POC_MOVLW, pcop1);
9806                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9807                 pic16_emitpcode(POC_MOVLW, pcop2);
9808                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9809         } else
9810         if (size == 2) {
9811                 pic16_emitpcode(POC_MOVLW, pcop0);
9812                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9813                 pic16_emitpcode(POC_MOVLW, pcop1);
9814                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9815         } else {
9816                 pic16_emitpcode(POC_MOVLW, pcop0);
9817                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9818         }
9819
9820         pic16_freeAsmop(result,NULL,ic,TRUE);
9821         pic16_freeAsmop(left, NULL, ic, FALSE);
9822 }
9823
9824
9825 #if 0
9826 /*-----------------------------------------------------------------*/
9827 /* genFarFarAssign - assignment when both are in far space         */
9828 /*-----------------------------------------------------------------*/
9829 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9830 {
9831     int size = AOP_SIZE(right);
9832     int offset = 0;
9833     char *l ;
9834     /* first push the right side on to the stack */
9835     while (size--) {
9836         l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9837         MOVA(l);
9838         pic16_emitcode ("push","acc");
9839     }
9840     
9841     pic16_freeAsmop(right,NULL,ic,FALSE);
9842     /* now assign DPTR to result */
9843     pic16_aopOp(result,ic,FALSE);
9844     size = AOP_SIZE(result);
9845     while (size--) {
9846         pic16_emitcode ("pop","acc");
9847         pic16_aopPut(AOP(result),"a",--offset);
9848     }
9849     pic16_freeAsmop(result,NULL,ic,FALSE);
9850         
9851 }
9852 #endif
9853
9854 /*-----------------------------------------------------------------*/
9855 /* genAssign - generate code for assignment                        */
9856 /*-----------------------------------------------------------------*/
9857 static void genAssign (iCode *ic)
9858 {
9859   operand *result, *right;
9860   int size, offset,know_W;
9861   unsigned long lit = 0L;
9862
9863   result = IC_RESULT(ic);
9864   right  = IC_RIGHT(ic) ;
9865
9866   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9867   
9868   /* if they are the same */
9869   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9870     return ;
9871
9872   pic16_aopOp(right,ic,FALSE);
9873   pic16_aopOp(result,ic,TRUE);
9874
9875   DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9876
9877   /* if they are the same registers */
9878   if (pic16_sameRegs(AOP(right),AOP(result)))
9879     goto release;
9880
9881   /* if the result is a bit */
9882   if (AOP_TYPE(result) == AOP_CRY) {
9883     /* if the right size is a literal then
9884        we know what the value is */
9885     if (AOP_TYPE(right) == AOP_LIT) {
9886           
9887       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9888                   pic16_popGet(AOP(result),0));
9889
9890       if (((int) operandLitValue(right))) 
9891         pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9892                        AOP(result)->aopu.aop_dir,
9893                        AOP(result)->aopu.aop_dir);
9894       else
9895         pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9896                        AOP(result)->aopu.aop_dir,
9897                        AOP(result)->aopu.aop_dir);
9898       goto release;
9899     }
9900
9901     /* the right is also a bit variable */
9902     if (AOP_TYPE(right) == AOP_CRY) {
9903       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9904       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
9905       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9906
9907       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9908                      AOP(result)->aopu.aop_dir,
9909                      AOP(result)->aopu.aop_dir);
9910       pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9911                      AOP(right)->aopu.aop_dir,
9912                      AOP(right)->aopu.aop_dir);
9913       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9914                      AOP(result)->aopu.aop_dir,
9915                      AOP(result)->aopu.aop_dir);
9916       goto release ;
9917     }
9918
9919     /* we need to or */
9920     pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
9921     pic16_toBoolean(right);
9922     emitSKPZ;
9923     pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
9924     //pic16_aopPut(AOP(result),"a",0);
9925     goto release ;
9926   }
9927
9928   /* bit variables done */
9929   /* general case */
9930   size = AOP_SIZE(result);
9931   offset = 0 ;
9932   if(AOP_TYPE(right) == AOP_LIT)
9933     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9934
9935 /* VR - What is this?! */
9936   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9937   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9938     if(aopIdx(AOP(result),0) == 4) {
9939   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9940       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9941       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9942       goto release;
9943     } else
9944       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9945   }
9946
9947   know_W=-1;
9948   while (size--) {
9949   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9950     if(AOP_TYPE(right) == AOP_LIT) {
9951       if(lit&0xff) {
9952         if(know_W != (lit&0xff))
9953           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9954         know_W = lit&0xff;
9955         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9956       } else
9957         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9958
9959       lit >>= 8;
9960
9961     } else if (AOP_TYPE(right) == AOP_CRY) {
9962       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9963       if(offset == 0) {
9964         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9965         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9966       }
9967     } else {
9968   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9969
9970 #if 1
9971         /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9972            normally should work, but mind that the W register live range
9973            is not checked, so if the code generator assumes that the W
9974            is already loaded after such a pair, wrong code will be generated.
9975            
9976            Checking the live range is the next step.
9977            This is experimental code yet and has not been fully tested yet.
9978            USE WITH CARE. Revert to old code by setting 0 to the condition above.
9979            Vangelis Rokas 030603 (vrokas@otenet.gr) */
9980            
9981         pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9982 #else   
9983         /* This is the old code, which is assumed(?!) that works fine(!?) */
9984
9985         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9986         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9987 #endif
9988     }
9989             
9990     offset++;
9991   }
9992
9993     
9994  release:
9995   pic16_freeAsmop (right,NULL,ic,FALSE);
9996   pic16_freeAsmop (result,NULL,ic,TRUE);
9997 }   
9998
9999 /*-----------------------------------------------------------------*/
10000 /* genJumpTab - generates code for jump table                       */
10001 /*-----------------------------------------------------------------*/
10002 static void genJumpTab (iCode *ic)
10003 {
10004     symbol *jtab;
10005     char *l;
10006
10007     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10008
10009     pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10010     /* get the condition into accumulator */
10011     l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10012     MOVA(l);
10013     /* multiply by three */
10014     pic16_emitcode("add","a,acc");
10015     pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10016
10017     jtab = newiTempLabel(NULL);
10018     pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10019     pic16_emitcode("jmp","@a+dptr");
10020     pic16_emitcode("","%05d_DS_:",jtab->key+100);
10021
10022     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10023     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10024     emitSKPNC;
10025     pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10026     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10027     pic16_emitpLabel(jtab->key);
10028
10029     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10030
10031     /* now generate the jump labels */
10032     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10033          jtab = setNextItem(IC_JTLABELS(ic))) {
10034         pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10035         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10036         
10037     }
10038
10039 }
10040
10041 /*-----------------------------------------------------------------*/
10042 /* genMixedOperation - gen code for operators between mixed types  */
10043 /*-----------------------------------------------------------------*/
10044 /*
10045   TSD - Written for the PIC port - but this unfortunately is buggy.
10046   This routine is good in that it is able to efficiently promote 
10047   types to different (larger) sizes. Unfortunately, the temporary
10048   variables that are optimized out by this routine are sometimes
10049   used in other places. So until I know how to really parse the 
10050   iCode tree, I'm going to not be using this routine :(.
10051 */
10052 static int genMixedOperation (iCode *ic)
10053 {
10054 #if 0
10055   operand *result = IC_RESULT(ic);
10056   sym_link *ctype = operandType(IC_LEFT(ic));
10057   operand *right = IC_RIGHT(ic);
10058   int ret = 0;
10059   int big,small;
10060   int offset;
10061
10062   iCode *nextic;
10063   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10064
10065   pic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10066
10067   nextic = ic->next;
10068   if(!nextic)
10069     return 0;
10070
10071   nextright = IC_RIGHT(nextic);
10072   nextleft  = IC_LEFT(nextic);
10073   nextresult = IC_RESULT(nextic);
10074
10075   pic16_aopOp(right,ic,FALSE);
10076   pic16_aopOp(result,ic,FALSE);
10077   pic16_aopOp(nextright,  nextic, FALSE);
10078   pic16_aopOp(nextleft,   nextic, FALSE);
10079   pic16_aopOp(nextresult, nextic, FALSE);
10080
10081   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10082
10083     operand *t = right;
10084     right = nextright;
10085     nextright = t; 
10086
10087     pic16_emitcode(";remove right +","");
10088
10089   } else   if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10090 /*
10091     operand *t = right;
10092     right = nextleft;
10093     nextleft = t; 
10094 */
10095     pic16_emitcode(";remove left +","");
10096   } else
10097     return 0;
10098
10099   big = AOP_SIZE(nextleft);
10100   small = AOP_SIZE(nextright);
10101
10102   switch(nextic->op) {
10103
10104   case '+':
10105     pic16_emitcode(";optimize a +","");
10106     /* if unsigned or not an integral type */
10107     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10108       pic16_emitcode(";add a bit to something","");
10109     } else {
10110
10111       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10112
10113       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10114         pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10115         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10116       } else
10117         pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10118
10119       offset = 0;
10120       while(--big) {
10121
10122         offset++;
10123
10124         if(--small) {
10125           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10126             pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10127             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10128           }
10129
10130           pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10131           emitSKPNC;
10132           pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10133                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10134                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10135           pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10136           pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10137
10138         } else {
10139           pic16_emitcode("rlf","known_zero,w");
10140
10141           /*
10142             if right is signed
10143               btfsc  right,7
10144                addlw ff
10145           */
10146           if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10147             pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10148             pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10149           } else {
10150             pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10151           }
10152         }
10153       }
10154       ret = 1;
10155     }
10156   }
10157   ret = 1;
10158
10159 release:
10160   pic16_freeAsmop(right,NULL,ic,TRUE);
10161   pic16_freeAsmop(result,NULL,ic,TRUE);
10162   pic16_freeAsmop(nextright,NULL,ic,TRUE);
10163   pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10164   if(ret)
10165     nextic->generated = 1;
10166
10167   return ret;
10168 #else
10169   return 0;
10170 #endif
10171 }
10172 /*-----------------------------------------------------------------*/
10173 /* genCast - gen code for casting                                  */
10174 /*-----------------------------------------------------------------*/
10175 static void genCast (iCode *ic)
10176 {
10177   operand *result = IC_RESULT(ic);
10178   sym_link *ctype = operandType(IC_LEFT(ic));
10179   sym_link *rtype = operandType(IC_RIGHT(ic));
10180   operand *right = IC_RIGHT(ic);
10181   int size, offset ;
10182
10183         DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10184         /* if they are equivalent then do nothing */
10185         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10186                 return ;
10187
10188         pic16_aopOp(right,ic,FALSE) ;
10189         pic16_aopOp(result,ic,FALSE);
10190
10191         DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10192
10193         /* if the result is a bit */
10194         if (AOP_TYPE(result) == AOP_CRY) {
10195         
10196                 /* if the right size is a literal then
10197                  * we know what the value is */
10198                 DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10199
10200                 if (AOP_TYPE(right) == AOP_LIT) {
10201                         pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10202                                 pic16_popGet(AOP(result),0));
10203
10204                         if (((int) operandLitValue(right))) 
10205                                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10206                                         AOP(result)->aopu.aop_dir,
10207                                         AOP(result)->aopu.aop_dir);
10208                         else
10209                                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10210                                         AOP(result)->aopu.aop_dir,
10211                                         AOP(result)->aopu.aop_dir);
10212                         goto release;
10213                 }
10214
10215                 /* the right is also a bit variable */
10216                 if (AOP_TYPE(right) == AOP_CRY) {
10217                         emitCLRC;
10218                         pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
10219
10220                         pic16_emitcode("clrc","");
10221                         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10222                                 AOP(right)->aopu.aop_dir,
10223                                 AOP(right)->aopu.aop_dir);
10224                         pic16_aopPut(AOP(result),"c",0);
10225                         goto release ;
10226                 }
10227
10228                 /* we need to or */
10229                 if (AOP_TYPE(right) == AOP_REG) {
10230                         pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
10231                         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10232                         pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
10233                 }
10234                 pic16_toBoolean(right);
10235                 pic16_aopPut(AOP(result),"a",0);
10236                 goto release ;
10237         }
10238
10239         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10240           int offset = 1;
10241
10242                 size = AOP_SIZE(result);
10243
10244                 DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10245
10246                 pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
10247                 pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
10248                 pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
10249
10250                 while (size--)
10251                         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
10252
10253                 goto release;
10254         }
10255
10256         /* if they are the same size : or less */
10257         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10258
10259                 /* if they are in the same place */
10260                 if (pic16_sameRegs(AOP(right),AOP(result)))
10261                         goto release;
10262
10263                 DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10264 #if 0
10265                 if (IS_PTR_CONST(rtype))
10266 #else
10267                 if (IS_CODEPTR(rtype))
10268 #endif
10269                         DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10270
10271 #if 0
10272                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10273 #else
10274                 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10275 #endif
10276                         DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10277
10278 #if 0
10279                 if(AOP_TYPE(right) == AOP_IMMD) {
10280                   pCodeOp *pcop0, *pcop1, *pcop2;
10281                   symbol *sym = OP_SYMBOL( right );
10282
10283                         size = AOP_SIZE(result);
10284                         /* low */
10285                         pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10286                         /* high */
10287                         pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10288                         /* upper */
10289                         pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10290         
10291                         if (size == 3) {
10292                                 pic16_emitpcode(POC_MOVLW, pcop0);
10293                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10294                                 pic16_emitpcode(POC_MOVLW, pcop1);
10295                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10296                                 pic16_emitpcode(POC_MOVLW, pcop2);
10297                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10298                         } else
10299                         if (size == 2) {
10300                                 pic16_emitpcode(POC_MOVLW, pcop0);
10301                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10302                                 pic16_emitpcode(POC_MOVLW, pcop1);
10303                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10304                         } else {
10305                                 pic16_emitpcode(POC_MOVLW, pcop0);
10306                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10307                         }
10308                 } else
10309 #endif
10310                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10311                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10312                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10313                         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10314                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10315                         if(AOP_SIZE(result) <2)
10316                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10317                 } else {
10318                         /* if they in different places then copy */
10319                         size = AOP_SIZE(result);
10320                         offset = 0 ;
10321                         while (size--) {
10322                                 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10323                                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10324                                 offset++;
10325                         }
10326                 }
10327                 goto release;
10328         }
10329
10330         /* if the result is of type pointer */
10331         if (IS_PTR(ctype)) {
10332           int p_type;
10333           sym_link *type = operandType(right);
10334           sym_link *etype = getSpec(type);
10335
10336                 DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
10337
10338                 /* pointer to generic pointer */
10339                 if (IS_GENPTR(ctype)) {
10340                   char *l = zero;
10341             
10342                         if (IS_PTR(type)) 
10343                                 p_type = DCL_TYPE(type);
10344                         else {
10345                 /* we have to go by the storage class */
10346                 p_type = PTR_TYPE(SPEC_OCLS(etype));
10347
10348 /*              if (SPEC_OCLS(etype)->codesp )  */
10349 /*                  p_type = CPOINTER ;  */
10350 /*              else */
10351 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10352 /*                      p_type = FPOINTER ; */
10353 /*                  else */
10354 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10355 /*                          p_type = PPOINTER; */
10356 /*                      else */
10357 /*                          if (SPEC_OCLS(etype) == idata ) */
10358 /*                              p_type = IPOINTER ; */
10359 /*                          else */
10360 /*                              p_type = POINTER ; */
10361             }
10362                 
10363             /* the first two bytes are known */
10364       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
10365             size = GPTRSIZE - 1; 
10366             offset = 0 ;
10367             while (size--) {
10368               if(offset < AOP_SIZE(right)) {
10369       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
10370                 if ((AOP_TYPE(right) == AOP_PCODE) && 
10371                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10372                   pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10373                   pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10374                 } else { 
10375                   pic16_aopPut(AOP(result),
10376                          pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10377                          offset);
10378                 }
10379               } else 
10380                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10381               offset++;
10382             }
10383             /* the last byte depending on type */
10384             switch (p_type) {
10385             case IPOINTER:
10386             case POINTER:
10387                 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10388                 break;
10389             case FPOINTER:
10390               pic16_emitcode(";BUG!? ","%d",__LINE__);
10391                 l = one;
10392                 break;
10393             case CPOINTER:
10394               pic16_emitcode(";BUG!? ","%d",__LINE__);
10395                 l = "#0x02";
10396                 break;                          
10397             case PPOINTER:
10398               pic16_emitcode(";BUG!? ","%d",__LINE__);
10399                 l = "#0x03";
10400                 break;
10401                 
10402             default:
10403                 /* this should never happen */
10404                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10405                        "got unknown pointer type");
10406                 exit(1);
10407             }
10408             //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
10409             goto release ;
10410         }
10411         
10412         /* just copy the pointers */
10413         size = AOP_SIZE(result);
10414         offset = 0 ;
10415         while (size--) {
10416             pic16_aopPut(AOP(result),
10417                    pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10418                    offset);
10419             offset++;
10420         }
10421         goto release ;
10422     }
10423     
10424
10425
10426     /* so we now know that the size of destination is greater
10427     than the size of the source.
10428     Now, if the next iCode is an operator then we might be
10429     able to optimize the operation without performing a cast.
10430     */
10431     if(genMixedOperation(ic))
10432       goto release;
10433
10434     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10435     
10436     /* we move to result for the size of source */
10437     size = AOP_SIZE(right);
10438     offset = 0 ;
10439     while (size--) {
10440       pic16_emitpcode(POC_MOVFW,   pic16_popGet(AOP(right),offset));
10441       pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset));
10442       offset++;
10443     }
10444
10445     /* now depending on the sign of the destination */
10446     size = AOP_SIZE(result) - AOP_SIZE(right);
10447     /* if unsigned or not an integral type */
10448     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10449       while (size--)
10450         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
10451     } else {
10452       /* we need to extend the sign :( */
10453
10454       if(size == 1) {
10455         /* Save one instruction of casting char to int */
10456         pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
10457         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10458         pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
10459       } else {
10460         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10461
10462         if(offset)
10463           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10464         else
10465           pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10466         
10467         pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
10468
10469         while (size--)
10470           pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
10471       }
10472     }
10473
10474 release:
10475     pic16_freeAsmop(right,NULL,ic,TRUE);
10476     pic16_freeAsmop(result,NULL,ic,TRUE);
10477
10478 }
10479
10480 /*-----------------------------------------------------------------*/
10481 /* genDjnz - generate decrement & jump if not zero instrucion      */
10482 /*-----------------------------------------------------------------*/
10483 static int genDjnz (iCode *ic, iCode *ifx)
10484 {
10485     symbol *lbl, *lbl1;
10486     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10487
10488     if (!ifx)
10489         return 0;
10490     
10491     /* if the if condition has a false label
10492        then we cannot save */
10493     if (IC_FALSE(ifx))
10494         return 0;
10495
10496     /* if the minus is not of the form 
10497        a = a - 1 */
10498     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10499         !IS_OP_LITERAL(IC_RIGHT(ic)))
10500         return 0;
10501
10502     if (operandLitValue(IC_RIGHT(ic)) != 1)
10503         return 0;
10504
10505     /* if the size of this greater than one then no
10506        saving */
10507     if (getSize(operandType(IC_RESULT(ic))) > 1)
10508         return 0;
10509
10510     /* otherwise we can save BIG */
10511     lbl = newiTempLabel(NULL);
10512     lbl1= newiTempLabel(NULL);
10513
10514     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10515     
10516     if (IS_AOP_PREG(IC_RESULT(ic))) {
10517         pic16_emitcode("dec","%s",
10518                  pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10519         pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10520         pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10521     } else {    
10522
10523
10524       pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10525       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10526
10527       pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10528       pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10529
10530     }
10531 /*     pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10532 /*     pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10533 /*     pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10534 /*     pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10535
10536     
10537     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10538     ifx->generated = 1;
10539     return 1;
10540 }
10541
10542 /*-----------------------------------------------------------------*/
10543 /* genReceive - generate code for a receive iCode                  */
10544 /*-----------------------------------------------------------------*/
10545 static void genReceive (iCode *ic)
10546 {    
10547         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10548
10549         if (isOperandInFarSpace(IC_RESULT(ic)) &&
10550                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10551                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10552
10553           int size = getSize(operandType(IC_RESULT(ic)));
10554           int offset =  pic16_fReturnSizePic - size;
10555
10556                 while (size--) {
10557                         pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10558                                         fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10559                         offset++;
10560                 }
10561
10562                 DEBUGpic16_emitcode ("; ***","1 %s  %d",__FUNCTION__,__LINE__);
10563
10564                 pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
10565                 size = AOP_SIZE(IC_RESULT(ic));
10566                 offset = 0;
10567                 while (size--) {
10568                         pic16_emitcode ("pop","acc");
10569                         pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10570                 }
10571         } else {
10572                 DEBUGpic16_emitcode ("; ***","2 %s  %d",__FUNCTION__,__LINE__);
10573
10574                 _G.accInUse++;
10575                 pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
10576                 _G.accInUse--;
10577                 assignResultValue(IC_RESULT(ic), 0);
10578         }
10579
10580         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10581 }
10582
10583 /*-----------------------------------------------------------------*/
10584 /* genDummyRead - generate code for dummy read of volatiles        */
10585 /*-----------------------------------------------------------------*/
10586 static void
10587 genDummyRead (iCode * ic)
10588 {
10589   pic16_emitcode ("; genDummyRead","");
10590   pic16_emitcode ("; not implemented","");
10591
10592   ic = ic;
10593 }
10594
10595 /*-----------------------------------------------------------------*/
10596 /* genpic16Code - generate code for pic16 based controllers        */
10597 /*-----------------------------------------------------------------*/
10598 /*
10599  * At this point, ralloc.c has gone through the iCode and attempted
10600  * to optimize in a way suitable for a PIC. Now we've got to generate
10601  * PIC instructions that correspond to the iCode.
10602  *
10603  * Once the instructions are generated, we'll pass through both the
10604  * peep hole optimizer and the pCode optimizer.
10605  *-----------------------------------------------------------------*/
10606
10607 void genpic16Code (iCode *lic)
10608 {
10609     iCode *ic;
10610     int cln = 0;
10611
10612     lineHead = lineCurr = NULL;
10613
10614     pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10615     pic16_addpBlock(pb);
10616
10617 #if 0
10618     /* if debug information required */
10619     if (options.debug && currFunc) {
10620       if (currFunc) {
10621         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10622         _G.debugLine = 1;
10623         if (IS_STATIC(currFunc->etype)) {
10624           pic16_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
10625           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10626         } else {
10627           pic16_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
10628           //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10629         }
10630         _G.debugLine = 0;
10631       }
10632     }
10633 #endif
10634
10635     for (ic = lic ; ic ; ic = ic->next ) {
10636
10637       DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10638         if ( cln != ic->lineno ) {
10639             if ( options.debug ) {
10640                 _G.debugLine = 1;
10641                 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10642                          FileBaseName(ic->filename),ic->lineno,
10643                          ic->level,ic->block);
10644                 _G.debugLine = 0;
10645             }
10646             
10647             if(!options.noCcodeInAsm) {
10648                 pic16_addpCode2pBlock(pb,
10649                         pic16_newpCodeCSource(ic->lineno, ic->filename, 
10650                                 printCLine(ic->filename, ic->lineno)));
10651             }
10652
10653             cln = ic->lineno ;
10654         }
10655         
10656         if(options.iCodeInAsm) {
10657                 /* insert here code to print iCode as comment */
10658                 pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic));
10659         }
10660         
10661         /* if the result is marked as
10662            spilt and rematerializable or code for
10663            this has already been generated then
10664            do nothing */
10665         if (resultRemat(ic) || ic->generated ) 
10666             continue ;
10667         
10668         /* depending on the operation */
10669         switch (ic->op) {
10670         case '!' :
10671             pic16_genNot(ic);
10672             break;
10673             
10674         case '~' :
10675             pic16_genCpl(ic);
10676             break;
10677             
10678         case UNARYMINUS:
10679             genUminus (ic);
10680             break;
10681             
10682         case IPUSH:
10683             genIpush (ic);
10684             break;
10685             
10686         case IPOP:
10687             /* IPOP happens only when trying to restore a 
10688                spilt live range, if there is an ifx statement
10689                following this pop then the if statement might
10690                be using some of the registers being popped which
10691                would destroy the contents of the register so
10692                we need to check for this condition and handle it */
10693             if (ic->next            && 
10694                 ic->next->op == IFX &&
10695                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10696                 genIfx (ic->next,ic);
10697             else
10698                 genIpop (ic);
10699             break; 
10700             
10701         case CALL:
10702             genCall (ic);
10703             break;
10704             
10705         case PCALL:
10706             genPcall (ic);
10707             break;
10708             
10709         case FUNCTION:
10710             genFunction (ic);
10711             break;
10712             
10713         case ENDFUNCTION:
10714             genEndFunction (ic);
10715             break;
10716             
10717         case RETURN:
10718             genRet (ic);
10719             break;
10720             
10721         case LABEL:
10722             genLabel (ic);
10723             break;
10724             
10725         case GOTO:
10726             genGoto (ic);
10727             break;
10728             
10729         case '+' :
10730             pic16_genPlus (ic) ;
10731             break;
10732             
10733         case '-' :
10734             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10735                 pic16_genMinus (ic);
10736             break;
10737             
10738         case '*' :
10739             genMult (ic);
10740             break;
10741             
10742         case '/' :
10743             genDiv (ic) ;
10744             break;
10745             
10746         case '%' :
10747             genMod (ic);
10748             break;
10749             
10750         case '>' :
10751             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10752             break;
10753             
10754         case '<' :
10755             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10756             break;
10757             
10758         case LE_OP:
10759         case GE_OP:
10760         case NE_OP:
10761             
10762             /* note these two are xlated by algebraic equivalence
10763                during parsing SDCC.y */
10764             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10765                    "got '>=' or '<=' shouldn't have come here");
10766             break;      
10767             
10768         case EQ_OP:
10769             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10770             break;          
10771             
10772         case AND_OP:
10773             genAndOp (ic);
10774             break;
10775             
10776         case OR_OP:
10777             genOrOp (ic);
10778             break;
10779             
10780         case '^' :
10781             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10782             break;
10783             
10784         case '|' :
10785                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10786             break;
10787             
10788         case BITWISEAND:
10789             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10790             break;
10791             
10792         case INLINEASM:
10793             genInline (ic);
10794             break;
10795             
10796         case RRC:
10797             genRRC (ic);
10798             break;
10799             
10800         case RLC:
10801             genRLC (ic);
10802             break;
10803             
10804         case GETHBIT:
10805             genGetHbit (ic);
10806             break;
10807             
10808         case LEFT_OP:
10809             genLeftShift (ic);
10810             break;
10811             
10812         case RIGHT_OP:
10813             genRightShift (ic);
10814             break;
10815             
10816         case GET_VALUE_AT_ADDRESS:
10817             genPointerGet(ic);
10818             break;
10819             
10820         case '=' :
10821             if (POINTER_SET(ic))
10822                 genPointerSet(ic);
10823             else
10824                 genAssign(ic);
10825             break;
10826             
10827         case IFX:
10828             genIfx (ic,NULL);
10829             break;
10830             
10831         case ADDRESS_OF:
10832             genAddrOf (ic);
10833             break;
10834             
10835         case JUMPTABLE:
10836             genJumpTab (ic);
10837             break;
10838             
10839         case CAST:
10840             genCast (ic);
10841             break;
10842             
10843         case RECEIVE:
10844             genReceive(ic);
10845             break;
10846             
10847         case SEND:
10848             addSet(&_G.sendSet,ic);
10849             break;
10850
10851         case DUMMY_READ_VOLATILE:
10852           genDummyRead (ic);
10853           break;
10854
10855         default :
10856             ic = ic;
10857         }
10858     }
10859
10860
10861     /* now we are ready to call the
10862        peep hole optimizer */
10863     if (!options.nopeep) {
10864       peepHole (&lineHead);
10865     }
10866     /* now do the actual printing */
10867     printLine (lineHead,codeOutFile);
10868
10869 #ifdef PCODE_DEBUG
10870     DFPRINTF((stderr,"printing pBlock\n\n"));
10871     pic16_printpBlock(stdout,pb);
10872 #endif
10873
10874     return;
10875 }
10876