* src/pic/device.c (dump_sfr): replaced register declaration with
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for pic
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   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh  Moved aopLiteral to SDCCglue.c to help the split
29       Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #include "common.h"
40 #include "SDCCpeeph.h"
41 #include "ralloc.h"
42 #include "pcode.h"
43 #include "gen.h"
44
45 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
46 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 void genMult8X8_8 (operand *, operand *,operand *);
48 extern void printpBlock(FILE *of, pBlock *pb);
49
50 static int labelOffset=0;
51 extern int debug_verbose;
52 static int optimized_for_speed = 0;
53
54 /* max_key keeps track of the largest label number used in 
55 a function. This is then used to adjust the label offset
56 for the next function.
57 */
58 static int max_key=0;
59 static int GpsuedoStkPtr=0;
60
61 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
62 unsigned int pic14aopLiteral (value *val, int offset);
63 const char *AopType(short type);
64
65 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff)
66
67 /* this is the down and dirty file with all kinds of 
68 kludgy & hacky stuff. This is what it is all about
69 CODE GENERATION for a specific MCU . some of the
70 routines may be reusable, will have to see */
71
72 static char *zero = "#0x00";
73 static char *one  = "#0x01";
74 static char *spname = "sp";
75
76 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
77 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
78 static char **fReturn = fReturnpic14;
79
80 //static char *accUse[] = {"a","b"};
81
82 //static short rbank = -1;
83
84 static struct {
85         short r0Pushed;
86         short r1Pushed;
87         short accInUse;
88         short inLine;
89         short debugLine;
90         short nRegsSaved;
91         set *sendSet;
92 } _G;
93
94 /* Resolved ifx structure. This structure stores information
95 about an iCode ifx that makes it easier to generate code.
96 */
97 typedef struct resolvedIfx {
98         symbol *lbl;     /* pointer to a label */
99         int condition;   /* true or false ifx */
100         int generated;   /* set true when the code associated with the ifx
101                           * is generated */
102 } resolvedIfx;
103
104 extern int pic14_ptrRegReq ;
105 extern int pic14_nRegs;
106 extern FILE *codeOutFile;
107 static void saverbank (int, iCode *,bool);
108
109 static lineNode *lineHead = NULL;
110 static lineNode *lineCurr = NULL;
111
112 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
113 0xE0, 0xC0, 0x80, 0x00};
114 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
115 0x07, 0x03, 0x01, 0x00};
116
117 static  pBlock *pb;
118
119 /*-----------------------------------------------------------------*/
120 /*      my_powof2(n) - If `n' is an integaer power of 2, then the          */
121 /*                                 exponent of 2 is returned, otherwise -1 is      */
122 /*                                 returned.                                                                       */
123 /* note that this is similar to the function `powof2' in SDCCsymt  */
124 /* if(n == 2^y)                                                                                                    */
125 /*       return y;                                                                                                         */
126 /* return -1;                                                                                                      */
127 /*-----------------------------------------------------------------*/
128 static int my_powof2 (unsigned long num)
129 {
130         if(num) {
131                 if( (num & (num-1)) == 0) {
132                         int nshifts = -1;
133                         while(num) {
134                                 num>>=1;
135                                 nshifts++;
136                         }
137                         return nshifts;
138                 }
139         }
140         
141         return -1;
142 }
143
144 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
145 {
146         
147         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
148                 line_no,
149                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
150                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
151                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
152                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
153                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
154                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
155                 ((result) ? AOP_SIZE(result) : 0));
156         
157 }
158
159 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
160 {
161         
162         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
163                 line_no,
164                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
165                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
166                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
167                 ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
168                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
169                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
170         
171 }
172
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
174 {
175         va_list ap;
176         char lb[INITIAL_INLINEASM];  
177         char *lbp = lb;
178         
179         if(!debug_verbose && !options.debug)
180                 return;
181         
182         va_start(ap,fmt);   
183         
184         if (inst && *inst) {
185                 if (fmt && *fmt)
186                         sprintf(lb,"%s\t",inst);
187                 else
188                         sprintf(lb,"%s",inst);
189                 vsprintf(lb+(strlen(lb)),fmt,ap);
190         }  else
191                 vsprintf(lb,fmt,ap);
192         
193         while (isspace(*lbp)) lbp++;
194         
195         if (lbp && *lbp) 
196                 lineCurr = (lineCurr ?
197                 connectLine(lineCurr,newLineNode(lb)) :
198         (lineHead = newLineNode(lb)));
199         lineCurr->isInline = _G.inLine;
200         lineCurr->isDebug  = _G.debugLine;
201         
202         addpCode2pBlock(pb,newpCodeCharP(lb));
203         
204         va_end(ap);
205 }
206
207 static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
208 {
209 #if defined (HAVE_VSNPRINTF)
210   vsnprintf (buf, size, fmt, ap);
211 #elif defined (HAVE_VSPRINTF)
212   vsprintf (buf, size, fmt, ap);
213   if (strlen (buf) >= size)
214   {
215     fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
216   }
217 #elif defined (HAVE_SNPRINTF)
218   snprintf (buf, size, "vs(n)printf required");
219 #elif defined (HAVE_SRINTF)
220   sprintf (buf, "vs(n)printf required");
221   if (strlen (buf) >= size)
222   {
223     fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
224   }
225 #else
226   assert ( !"neither vsnprintf nor vsprintf is present -- unable to proceed" );
227 #endif
228 }
229
230 void emitpComment (const char *fmt, ...)
231 {
232   va_list va;
233   char buffer[4096];
234   
235   va_start (va, fmt);
236   if (pb) {
237     Safe_vsnprintf (buffer, 4096, fmt, va);
238     //fprintf (stderr, "%s\n" ,buffer);
239     addpCode2pBlock (pb, newpCodeCharP (buffer));
240   }
241   va_end (va);
242 }
243
244 void emitpLabel(int key)
245 {
246         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
247 }
248
249 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
250 {
251         if(pcop)
252                 addpCode2pBlock(pb,newpCode(poc,pcop));
253         else
254                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
255 }
256
257 void emitpcodeNULLop(PIC_OPCODE poc)
258 {
259         
260         addpCode2pBlock(pb,newpCode(poc,NULL));
261         
262 }
263
264
265 /*-----------------------------------------------------------------*/
266 /* pic14_emitcode - writes the code into a file : for now it is simple    */
267 /*-----------------------------------------------------------------*/
268 void pic14_emitcode (char *inst,char *fmt, ...)
269 {
270         va_list ap;
271         char lb[INITIAL_INLINEASM];  
272         char *lbp = lb;
273         
274         va_start(ap,fmt);   
275         
276         if (inst && *inst) {
277                 if (fmt && *fmt)
278                         sprintf(lb,"%s\t",inst);
279                 else
280                         sprintf(lb,"%s",inst);
281                 vsprintf(lb+(strlen(lb)),fmt,ap);
282         }  else
283                 vsprintf(lb,fmt,ap);
284         
285         while (isspace(*lbp)) lbp++;
286         
287         if (lbp && *lbp) 
288                 lineCurr = (lineCurr ?
289                 connectLine(lineCurr,newLineNode(lb)) :
290         (lineHead = newLineNode(lb)));
291         lineCurr->isInline = _G.inLine;
292         lineCurr->isDebug  = _G.debugLine;
293         
294         if(debug_verbose)
295                 addpCode2pBlock(pb,newpCodeCharP(lb));
296         
297         va_end(ap);
298 }
299
300 /*-----------------------------------------------------------------*/
301 /* pic14_emitDebuggerSymbol - associate the current code location  */
302 /*       with a debugger symbol                                                                            */
303 /*-----------------------------------------------------------------*/
304 void
305 pic14_emitDebuggerSymbol (char * debugSym)
306 {
307         _G.debugLine = 1;
308         pic14_emitcode ("", ";%s ==.", debugSym);
309         _G.debugLine = 0;
310 }
311
312
313 /*-----------------------------------------------------------------*/
314 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
315 /*-----------------------------------------------------------------*/
316 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
317 {
318         bool r0iu = FALSE , r1iu = FALSE;
319         bool r0ou = FALSE , r1ou = FALSE;
320         
321         /* the logic: if r0 & r1 used in the instruction
322         then we are in trouble otherwise */
323         
324         /* first check if r0 & r1 are used by this
325         instruction, in which case we are in trouble */
326         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
327                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
328         {
329                 goto endOfWorld;          
330         }
331         
332         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
333         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
334         
335         /* if no usage of r0 then return it */
336         if (!r0iu && !r0ou) {
337                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
338                 (*aopp)->type = AOP_R0;
339                 
340                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
341         }
342         
343         /* if no usage of r1 then return it */
344         if (!r1iu && !r1ou) {
345                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346                 (*aopp)->type = AOP_R1;
347                 
348                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
349         }    
350         
351         /* now we know they both have usage */
352         /* if r0 not used in this instruction */
353         if (!r0iu) {
354                 /* push it if not already pushed */
355                 if (!_G.r0Pushed) {
356                         //pic14_emitcode ("push","%s",
357                         //                pic14_regWithIdx(R0_IDX)->dname);
358                         _G.r0Pushed++ ;
359                 }
360                 
361                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
362                 (*aopp)->type = AOP_R0;
363                 
364                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
365         }
366         
367         /* if r1 not used then */
368         
369         if (!r1iu) {
370                 /* push it if not already pushed */
371                 if (!_G.r1Pushed) {
372                         //pic14_emitcode ("push","%s",
373                         //                pic14_regWithIdx(R1_IDX)->dname);
374                         _G.r1Pushed++ ;
375                 }
376                 
377                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
378                 (*aopp)->type = AOP_R1;
379                 return pic14_regWithIdx(R1_IDX);
380         }
381         
382 endOfWorld :
383         /* I said end of world but not quite end of world yet */
384         /* if this is a result then we can push it on the stack*/
385         if (result) {
386                 (*aopp)->type = AOP_STK;        
387                 return NULL;
388         }
389         
390         /* other wise this is true end of the world */
391         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
392                 "getFreePtr should never reach here");
393         exit(0);
394 }
395
396 /*-----------------------------------------------------------------*/
397 /* newAsmop - creates a new asmOp                                                                  */
398 /*-----------------------------------------------------------------*/
399 asmop *newAsmop (short type)
400 {
401         asmop *aop;
402         
403         aop = Safe_calloc(1,sizeof(asmop));
404         aop->type = type;
405         return aop;
406 }
407
408 static void genSetDPTR(int n)
409 {
410         if (!n)
411         {
412                 pic14_emitcode(";", "Select standard DPTR");
413                 pic14_emitcode("mov", "dps, #0x00");
414         }
415         else
416         {
417                 pic14_emitcode(";", "Select alternate DPTR");
418                 pic14_emitcode("mov", "dps, #0x01");
419         }
420 }
421
422 /*-----------------------------------------------------------------*/
423 /* resolveIfx - converts an iCode ifx into a form more useful for  */
424 /*                              generating code                                                                    */
425 /*-----------------------------------------------------------------*/
426 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
427 {
428         if(!resIfx) 
429                 return;
430         
431         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
432         
433         resIfx->condition = 1;  /* assume that the ifx is true */
434         resIfx->generated = 0;  /* indicate that the ifx has not been used */
435         
436         if(!ifx) {
437                 resIfx->lbl = newiTempLabel(NULL);      /* oops, there is no ifx. so create a label */
438                                                                                         /*
439                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
440                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
441                 */
442         } else {
443                 if(IC_TRUE(ifx)) {
444                         resIfx->lbl = IC_TRUE(ifx);
445                 } else {
446                         resIfx->lbl = IC_FALSE(ifx);
447                         resIfx->condition = 0;
448                 }
449                 /*
450                 if(IC_TRUE(ifx)) 
451                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
452                 if(IC_FALSE(ifx)) 
453                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
454                 */
455         }
456         
457         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
458         
459 }
460 /*-----------------------------------------------------------------*/
461 /* pointerCode - returns the code for a pointer type                       */
462 /*-----------------------------------------------------------------*/
463 static int pointerCode (sym_link *etype)
464 {
465         
466         return PTR_TYPE(SPEC_OCLS(etype));
467         
468 }
469
470 /*-----------------------------------------------------------------*/
471 /* aopForSym - for a true symbol                                                                   */
472 /*-----------------------------------------------------------------*/
473 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
474 {
475         asmop *aop;
476         memmap *space= SPEC_OCLS(sym->etype);
477         
478         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
479         /* if already has one */
480         if (sym->aop)
481                 return sym->aop;
482         
483         /* assign depending on the storage class */
484         /* if it is on the stack or indirectly addressable */
485         /* space we need to assign either r0 or r1 to it         */    
486         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
487                 sym->aop = aop = newAsmop(0);
488                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
489                 aop->size = getSize(sym->type);
490                 
491                 /* now assign the address of the variable to 
492                 the pointer register */
493                 if (aop->type != AOP_STK) {
494                         
495                         if (sym->onStack) {
496                                 if ( _G.accInUse )
497                                         pic14_emitcode("push","acc");
498                                 
499                                 pic14_emitcode("mov","a,_bp");
500                                 pic14_emitcode("add","a,#0x%02x",
501                                         ((sym->stack < 0) ?
502                                         ((char)(sym->stack - _G.nRegsSaved )) :
503                                 ((char)sym->stack)) & 0xff);
504                                 pic14_emitcode("mov","%s,a",
505                                         aop->aopu.aop_ptr->name);
506                                 
507                                 if ( _G.accInUse )
508                                         pic14_emitcode("pop","acc");
509                         } else
510                                 pic14_emitcode("mov","%s,#%s",
511                                 aop->aopu.aop_ptr->name,
512                                 sym->rname);
513                         aop->paged = space->paged;
514                 } else
515                         aop->aopu.aop_stk = sym->stack;
516                 return aop;
517         }
518         
519         if (sym->onStack && options.stack10bit)
520         {
521                 /* It's on the 10 bit stack, which is located in
522                 * far data space.
523                 */
524                 
525                 //DEBUGpic14_emitcode(";","%d",__LINE__);
526                 
527                 if ( _G.accInUse )
528                         pic14_emitcode("push","acc");
529                 
530                 pic14_emitcode("mov","a,_bp");
531                 pic14_emitcode("add","a,#0x%02x",
532                         ((sym->stack < 0) ?
533                         ((char)(sym->stack - _G.nRegsSaved )) :
534                 ((char)sym->stack)) & 0xff);
535                 
536                 genSetDPTR(1);
537                 pic14_emitcode ("mov","dpx1,#0x40");
538                 pic14_emitcode ("mov","dph1,#0x00");
539                 pic14_emitcode ("mov","dpl1, a");
540                 genSetDPTR(0);
541                 
542                 if ( _G.accInUse )
543                         pic14_emitcode("pop","acc");
544                 
545                 sym->aop = aop = newAsmop(AOP_DPTR2);
546                 aop->size = getSize(sym->type); 
547                 return aop;
548         }
549         
550         //DEBUGpic14_emitcode(";","%d",__LINE__);
551         /* if in bit space */
552         if (IN_BITSPACE(space)) {
553                 sym->aop = aop = newAsmop (AOP_CRY);
554                 aop->aopu.aop_dir = sym->rname ;
555                 aop->size = getSize(sym->type);
556                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
557                 return aop;
558         }
559         /* if it is in direct space */
560         if (IN_DIRSPACE(space)) {
561                 sym->aop = aop = newAsmop (AOP_DIR);
562                 aop->aopu.aop_dir = sym->rname ;
563                 aop->size = getSize(sym->type);
564                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
565                 return aop;
566         }
567         
568         /* special case for a function */
569         if (IS_FUNC(sym->type)) {   
570                 
571                 sym->aop = aop = newAsmop(AOP_PCODE);
572                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
573                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
574                 PCOI(aop->aopu.pcop)->_function = 1;
575                 PCOI(aop->aopu.pcop)->index = 0;
576                 aop->size = FPTRSIZE; 
577                 /*
578                 sym->aop = aop = newAsmop(AOP_IMMD);    
579                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
580                 strcpy(aop->aopu.aop_immd,sym->rname);
581                 aop->size = FPTRSIZE; 
582                 */
583                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
584                 return aop;
585         }
586         
587         
588         /* only remaining is far space */
589         /* in which case DPTR gets the address */
590         sym->aop = aop = newAsmop(AOP_PCODE);
591         
592         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
593         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
594         PCOI(aop->aopu.pcop)->index = 0;
595         
596         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
597                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
598         
599         allocDirReg (IC_LEFT(ic));
600         
601         aop->size = FPTRSIZE; 
602         /*
603         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
604         sym->aop = aop = newAsmop(AOP_DPTR);
605         pic14_emitcode ("mov","dptr,#%s", sym->rname);
606         aop->size = getSize(sym->type);
607         
608           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
609         */
610         
611         /* if it is in code space */
612         if (IN_CODESPACE(space))
613                 aop->code = 1;
614         
615         return aop;       
616 }
617
618 /*-----------------------------------------------------------------*/
619 /* aopForRemat - rematerialzes an object                                                   */
620 /*-----------------------------------------------------------------*/
621 static asmop *aopForRemat (operand *op) // x symbol *sym)
622 {
623         symbol *sym = OP_SYMBOL(op);
624         iCode *ic = NULL;
625         asmop *aop = newAsmop(AOP_PCODE);
626         int val = 0;
627         int offset = 0;
628         
629         ic = sym->rematiCode;
630         
631         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
632         if(IS_OP_POINTER(op)) {
633                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
634         }
635         for (;;) {
636                 if (ic->op == '+') {
637                         val += (int) operandLitValue(IC_RIGHT(ic));
638                 } else if (ic->op == '-') {
639                         val -= (int) operandLitValue(IC_RIGHT(ic));
640                 } else
641                         break;
642                 
643                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
644         }
645         
646         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
647         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
648         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
649         PCOI(aop->aopu.pcop)->index = val;
650         
651         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
652                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
653                 val, IS_PTR_CONST(operandType(op)));
654         
655         //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
656         
657         allocDirReg (IC_LEFT(ic));
658         
659         return aop;              
660 }
661
662 int aopIdx (asmop *aop, int offset)
663 {
664         if(!aop)
665                 return -1;
666         
667         if(aop->type !=  AOP_REG)
668                 return -2;
669         
670         return aop->aopu.aop_reg[offset]->rIdx;
671         
672 }
673 /*-----------------------------------------------------------------*/
674 /* regsInCommon - two operands have some registers in common       */
675 /*-----------------------------------------------------------------*/
676 static bool regsInCommon (operand *op1, operand *op2)
677 {
678         symbol *sym1, *sym2;
679         int i;
680         
681         /* if they have registers in common */
682         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
683                 return FALSE ;
684         
685         sym1 = OP_SYMBOL(op1);
686         sym2 = OP_SYMBOL(op2);
687         
688         if (sym1->nRegs == 0 || sym2->nRegs == 0)
689                 return FALSE ;
690         
691         for (i = 0 ; i < sym1->nRegs ; i++) {
692                 int j;
693                 if (!sym1->regs[i])
694                         continue ;
695                 
696                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
697                         if (!sym2->regs[j])
698                                 continue ;
699                         
700                         if (sym2->regs[j] == sym1->regs[i])
701                                 return TRUE ;
702                 }
703         }
704         
705         return FALSE ;
706 }
707
708 /*-----------------------------------------------------------------*/
709 /* operandsEqu - equivalent                                                                        */
710 /*-----------------------------------------------------------------*/
711 static bool operandsEqu ( operand *op1, operand *op2)
712 {
713         symbol *sym1, *sym2;
714         
715         /* if they not symbols */
716         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
717                 return FALSE;
718         
719         sym1 = OP_SYMBOL(op1);
720         sym2 = OP_SYMBOL(op2);
721         
722         /* if both are itemps & one is spilt
723         and the other is not then false */
724         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
725                 sym1->isspilt != sym2->isspilt )
726                 return FALSE ;
727         
728         /* if they are the same */
729         if (sym1 == sym2)
730                 return TRUE ;
731         
732         if (sym1->rname[0] && sym2->rname[0]
733                 && strcmp (sym1->rname, sym2->rname) == 0)
734                 return TRUE;
735         
736         
737         /* if left is a tmp & right is not */
738         if (IS_ITEMP(op1)  && 
739                 !IS_ITEMP(op2) &&
740                 sym1->isspilt  &&
741                 (sym1->usl.spillLoc == sym2))
742                 return TRUE;
743         
744         if (IS_ITEMP(op2)  && 
745                 !IS_ITEMP(op1) &&
746                 sym2->isspilt  &&
747                 sym1->level > 0 &&
748                 (sym2->usl.spillLoc == sym1))
749                 return TRUE ;
750         
751         return FALSE ;
752 }
753
754 /*-----------------------------------------------------------------*/
755 /* pic14_sameRegs - two asmops have the same registers             */
756 /*-----------------------------------------------------------------*/
757 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
758 {
759         int i;
760         
761         if (aop1 == aop2)
762                 return TRUE ;
763         
764         if (aop1->type != AOP_REG ||
765                 aop2->type != AOP_REG )
766                 return FALSE ;
767         
768         if (aop1->size != aop2->size )
769                 return FALSE ;
770         
771         for (i = 0 ; i < aop1->size ; i++ )
772                 if (aop1->aopu.aop_reg[i] !=
773                         aop2->aopu.aop_reg[i] )
774                         return FALSE ;
775                 
776                 return TRUE ;
777 }
778
779 /*-----------------------------------------------------------------*/
780 /* aopOp - allocates an asmop for an operand  :                    */
781 /*-----------------------------------------------------------------*/
782 void aopOp (operand *op, iCode *ic, bool result)
783 {
784         asmop *aop;
785         symbol *sym;
786         int i;
787         
788         if (!op)
789                 return ;
790         
791         /* if this a literal */
792         if (IS_OP_LITERAL(op)) {
793                 op->aop = aop = newAsmop(AOP_LIT);
794                 aop->aopu.aop_lit = op->operand.valOperand;
795                 aop->size = getSize(operandType(op));
796                 return;
797         }
798         
799         {
800                 sym_link *type = operandType(op);
801                 if(IS_PTR_CONST(type))
802                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
803         }
804         
805         /* if already has a asmop then continue */
806         if (op->aop)
807                 return ;
808         
809         /* if the underlying symbol has a aop */
810         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
811                 DEBUGpic14_emitcode(";","%d",__LINE__);
812                 op->aop = OP_SYMBOL(op)->aop;
813                 return;
814         }
815         
816         /* if this is a true symbol */
817         if (IS_TRUE_SYMOP(op)) {          
818                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
819                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
820                 return ;
821         }
822         
823         /* this is a temporary : this has
824         only four choices :
825         a) register
826         b) spillocation
827         c) rematerialize 
828         d) conditional   
829         e) can be a return use only */
830         
831         sym = OP_SYMBOL(op);
832         
833         
834         /* if the type is a conditional */
835         if (sym->regType == REG_CND) {
836                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
837                 aop->size = 0;
838                 return;
839         }
840         
841         /* if it is spilt then two situations
842         a) is rematerialize 
843         b) has a spill location */
844         if (sym->isspilt || sym->nRegs == 0) {
845                 
846                 DEBUGpic14_emitcode(";","%d",__LINE__);
847                 /* rematerialize it NOW */
848                 if (sym->remat) {
849                         
850                         sym->aop = op->aop = aop = aopForRemat (op);
851                         aop->size = getSize(sym->type);
852                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
853                         return;
854                 }
855                 
856 #if 0
857                 /* WREG is not usable as an ordinary operand with PIC architecture,
858                  * one might introduce a scratch register that can be used to make
859                  * WREG accesible as an operand... disable WREG for now */
860                 if (sym->accuse) {
861                         int i;
862                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
863                         aop->size = getSize(sym->type);
864                         for ( i = 0 ; i < 2 ; i++ )
865                                 aop->aopu.aop_str[i] = accUse[i];
866                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
867                         return;  
868                 }
869 #endif
870                 
871                 if (sym->ruonly ) {
872                         if(sym->isptr) {        // && sym->uptr 
873                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
874                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
875                                 
876                                 //PCOI(aop->aopu.pcop)->_const = 0;
877                                 //PCOI(aop->aopu.pcop)->index = 0;
878                                 /*
879                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
880                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
881                                 */
882                                 //allocDirReg (IC_LEFT(ic));
883                                 
884                                 aop->size = getSize(sym->type);
885                                 DEBUGpic14_emitcode(";","%d",__LINE__);
886                                 return;
887                                 
888                         } else {
889                                 
890                                 unsigned i;
891                                 
892                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
893                                 aop->size = getSize(sym->type);
894                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
895                                         aop->aopu.aop_str[i] = fReturn[i];
896                                 
897                                 DEBUGpic14_emitcode(";","%d",__LINE__);
898                                 return;
899                         }
900                 }
901                 
902                 /* else spill location  */
903                 if (sym->usl.spillLoc)
904                 {
905                         if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
906                         {
907                                 /* force a new aop if sizes differ */
908                                 sym->usl.spillLoc->aop = NULL;
909                         }
910                         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
911                                 __FUNCTION__,__LINE__,
912                                 sym->usl.spillLoc->rname,
913                                 sym->rname, sym->usl.spillLoc->offset);
914                 
915                         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
916                         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
917                         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
918                                 getSize(sym->type), 
919                                 sym->usl.spillLoc->offset);
920                         aop->size = getSize(sym->type);
921                 
922                         return;
923                 }
924         }
925         
926         {
927                 sym_link *type = operandType(op);
928                 if(IS_PTR_CONST(type)) 
929                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
930         }
931         
932         /* must be in a register */
933         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
934         sym->aop = op->aop = aop = newAsmop(AOP_REG);
935         aop->size = sym->nRegs;
936         for ( i = 0 ; i < sym->nRegs ;i++)
937                 aop->aopu.aop_reg[i] = sym->regs[i];
938 }
939
940 /*-----------------------------------------------------------------*/
941 /* freeAsmop - free up the asmop given to an operand                       */
942 /*----------------------------------------------------------------*/
943 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
944 {       
945         asmop *aop ;
946         
947         if (!op)
948                 aop = aaop;
949         else 
950                 aop = op->aop;
951         
952         if (!aop)
953                 return ;
954         
955         if (aop->freed)
956                 goto dealloc; 
957         
958         aop->freed = 1;
959         
960         /* depending on the asmop type only three cases need work AOP_RO
961         , AOP_R1 && AOP_STK */
962 #if 0
963         switch (aop->type) {
964         case AOP_R0 :
965                 if (_G.r0Pushed ) {
966                         if (pop) {
967                                 pic14_emitcode ("pop","ar0");     
968                                 _G.r0Pushed--;
969                         }
970                 }
971                 bitVectUnSetBit(ic->rUsed,R0_IDX);
972                 break;
973                 
974         case AOP_R1 :
975                 if (_G.r1Pushed ) {
976                         if (pop) {
977                                 pic14_emitcode ("pop","ar1");
978                                 _G.r1Pushed--;
979                         }
980                 }
981                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
982                 break;
983                 
984         case AOP_STK :
985                 {
986                         int sz = aop->size;      
987                         int stk = aop->aopu.aop_stk + aop->size;
988                         bitVectUnSetBit(ic->rUsed,R0_IDX);
989                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
990                         
991                         getFreePtr(ic,&aop,FALSE);
992                         
993                         if (options.stack10bit)
994                         {
995                                 /* I'm not sure what to do here yet... */
996                                 /* #STUB */
997                                 fprintf(stderr, 
998                                         "*** Warning: probably generating bad code for "
999                                         "10 bit stack mode.\n");
1000                         }
1001                         
1002                         if (stk) {
1003                                 pic14_emitcode ("mov","a,_bp");
1004                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1005                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1006                         } else {
1007                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1008                         }
1009                         
1010                         while (sz--) {
1011                                 pic14_emitcode("pop","acc");
1012                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1013                                 if (!sz) break;
1014                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1015                         }
1016                         op->aop = aop;
1017                         freeAsmop(op,NULL,ic,TRUE);
1018                         if (_G.r0Pushed) {
1019                                 pic14_emitcode("pop","ar0");
1020                                 _G.r0Pushed--;
1021                         }
1022                         
1023                         if (_G.r1Pushed) {
1024                                 pic14_emitcode("pop","ar1");
1025                                 _G.r1Pushed--;
1026                         }         
1027                 }
1028         }
1029 #endif
1030         
1031 dealloc:
1032         /* all other cases just dealloc */
1033         if (op ) {
1034                 op->aop = NULL;
1035                 if (IS_SYMOP(op)) {
1036                         OP_SYMBOL(op)->aop = NULL;      
1037                         /* if the symbol has a spill */
1038                         if (SPIL_LOC(op))
1039                                 SPIL_LOC(op)->aop = NULL;
1040                 }
1041         }
1042 }
1043
1044 /*-----------------------------------------------------------------*/
1045 /* aopGet - for fetching value of the aop                                                  */
1046 /*-----------------------------------------------------------------*/
1047 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1048 {
1049         char *s = buffer ;
1050         char *rs;
1051         
1052         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1053         /* offset is greater than
1054         size then zero */
1055         if (offset > (aop->size - 1) &&
1056                 aop->type != AOP_LIT)
1057                 return zero;
1058         
1059         /* depending on type */
1060         switch (aop->type) {
1061                 
1062         case AOP_R0:
1063         case AOP_R1:
1064                 DEBUGpic14_emitcode(";","%d",__LINE__);
1065                 /* if we need to increment it */           
1066                 while (offset > aop->coff) {            
1067                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1068                         aop->coff++;
1069                 }
1070                 
1071                 while (offset < aop->coff) {
1072                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1073                         aop->coff--;
1074                 }
1075                 
1076                 aop->coff = offset ;
1077                 if (aop->paged) {
1078                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1079                         return (dname ? "acc" : "a");
1080                 }               
1081                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1082                 rs = Safe_calloc(1,strlen(s)+1);
1083                 strcpy(rs,s);   
1084                 return rs;
1085                 
1086         case AOP_DPTR:
1087         case AOP_DPTR2:
1088                 DEBUGpic14_emitcode(";","%d",__LINE__);
1089                 if (aop->type == AOP_DPTR2)
1090                 {
1091                         genSetDPTR(1);
1092                 }
1093                 
1094                 while (offset > aop->coff) {
1095                         pic14_emitcode ("inc","dptr");
1096                         aop->coff++;
1097                 }
1098                 
1099                 while (offset < aop->coff) {            
1100                         pic14_emitcode("lcall","__decdptr");
1101                         aop->coff--;
1102                 }
1103                 
1104                 aop->coff = offset;
1105                 if (aop->code) {
1106                         pic14_emitcode("clr","a");
1107                         pic14_emitcode("movc","a,@a+dptr");
1108                 }
1109                 else {
1110                         pic14_emitcode("movx","a,@dptr");
1111                 }
1112                 
1113                 if (aop->type == AOP_DPTR2)
1114                 {
1115                         genSetDPTR(0);
1116                 }
1117                 
1118                 return (dname ? "acc" : "a");
1119                 
1120                 
1121         case AOP_IMMD:
1122                 if (bit16) 
1123                         sprintf (s,"%s",aop->aopu.aop_immd);
1124                 else
1125                         if (offset) 
1126                                 sprintf(s,"(%s >> %d)",
1127                                 aop->aopu.aop_immd,
1128                                 offset*8);
1129                         else
1130                                 sprintf(s,"%s",
1131                                 aop->aopu.aop_immd);
1132                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1133                         rs = Safe_calloc(1,strlen(s)+1);
1134                         strcpy(rs,s);   
1135                         return rs;
1136                         
1137         case AOP_DIR:
1138                 if (offset) {
1139                         sprintf(s,"(%s + %d)",
1140                                 aop->aopu.aop_dir,
1141                                 offset);
1142                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1143                 } else
1144                         sprintf(s,"%s",aop->aopu.aop_dir);
1145                 rs = Safe_calloc(1,strlen(s)+1);
1146                 strcpy(rs,s);   
1147                 return rs;
1148                 
1149         case AOP_REG:
1150                 //if (dname) 
1151                 //        return aop->aopu.aop_reg[offset]->dname;
1152                 //else
1153                 return aop->aopu.aop_reg[offset]->name;
1154                 
1155         case AOP_CRY:
1156                 //pic14_emitcode(";","%d",__LINE__);
1157                 return aop->aopu.aop_dir;
1158                 
1159         case AOP_ACC:
1160                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1161                 return "AOP_accumulator_bug";
1162                 
1163         case AOP_LIT:
1164                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1165                 rs = Safe_calloc(1,strlen(s)+1);
1166                 strcpy(rs,s);   
1167                 return rs;
1168                 
1169         case AOP_STR:
1170                 aop->coff = offset ;
1171                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1172                         dname)
1173                         return "acc";
1174                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1175                 
1176                 return aop->aopu.aop_str[offset];
1177                 
1178         case AOP_PCODE:
1179                 {
1180                         pCodeOp *pcop = aop->aopu.pcop;
1181                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1182                         if(pcop->name) {
1183                                 if (offset) {
1184                                         DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1185                                         sprintf(s,"(%s+%d)", pcop->name,offset);
1186                                 } else {
1187                                         DEBUGpic14_emitcode(";","%s",pcop->name);
1188                                         sprintf(s,"%s", pcop->name);
1189                                 }
1190                         } else
1191                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1192                         
1193                 }
1194                 rs = Safe_calloc(1,strlen(s)+1);
1195                 strcpy(rs,s);   
1196                 return rs;
1197                 
1198   }
1199   
1200   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1201           "aopget got unsupported aop->type");
1202   exit(0);
1203 }
1204
1205
1206 /*-----------------------------------------------------------------*/
1207 /* popGetTempReg - create a new temporary pCodeOp                                  */
1208 /*-----------------------------------------------------------------*/
1209 pCodeOp *popGetTempReg(void)
1210 {
1211         
1212         pCodeOp *pcop;
1213         
1214         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1215         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1216                 PCOR(pcop)->r->wasUsed=1;
1217                 PCOR(pcop)->r->isFree=0;
1218         }
1219         
1220         return pcop;
1221 }
1222
1223 /*-----------------------------------------------------------------*/
1224 /* popReleaseTempReg - create a new temporary pCodeOp                              */
1225 /*-----------------------------------------------------------------*/
1226 void popReleaseTempReg(pCodeOp *pcop)
1227 {
1228         
1229         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1230                 PCOR(pcop)->r->isFree = 1;
1231         
1232 }
1233 /*-----------------------------------------------------------------*/
1234 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetLabel(unsigned int key)
1237 {
1238         
1239         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1240         
1241         if(key>(unsigned int)max_key)
1242                 max_key = key;
1243         
1244         return newpCodeOpLabel(NULL,key+100+labelOffset);
1245 }
1246
1247 /*-------------------------------------------------------------------*/
1248 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1249 /*-------------------------------------------------------------------*/
1250 pCodeOp *popGetHighLabel(unsigned int key)
1251 {
1252         pCodeOp *pcop;
1253         pcop = popGetLabel(key);
1254         PCOLAB(pcop)->offset = 1;
1255         return pcop;
1256 }
1257
1258 /*-----------------------------------------------------------------*/
1259 /* popGetLit - asm operator to pcode operator conversion                           */
1260 /*-----------------------------------------------------------------*/
1261 pCodeOp *popGetLit(unsigned int lit)
1262 {
1263         
1264         return newpCodeOpLit(lit);
1265 }
1266
1267 /*-----------------------------------------------------------------*/
1268 /* popGetImmd - asm operator to pcode immediate conversion                 */
1269 /*-----------------------------------------------------------------*/
1270 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1271 {
1272         
1273         return newpCodeOpImmd(name, offset,index, 0, is_func);
1274 }
1275
1276
1277 /*-----------------------------------------------------------------*/
1278 /* popGetWithString - asm operator to pcode operator conversion                    */
1279 /*-----------------------------------------------------------------*/
1280 pCodeOp *popGetWithString(char *str, int isExtern)
1281 {
1282         pCodeOp *pcop;
1283         
1284         
1285         if(!str) {
1286                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1287                 exit (1);
1288         }
1289         
1290         pcop = newpCodeOp(str,PO_STR);
1291         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1292         
1293         return pcop;
1294 }
1295
1296 /*-----------------------------------------------------------------*/
1297 /* popRegFromString -                                                                                      */
1298 /*-----------------------------------------------------------------*/
1299 pCodeOp *popRegFromString(char *str, int size, int offset)
1300 {
1301         
1302         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1303         pcop->type = PO_DIR;
1304         
1305         DEBUGpic14_emitcode(";","%d",__LINE__);
1306         
1307         if(!str)
1308                 str = "BAD_STRING";
1309         
1310         pcop->name = Safe_calloc(1,strlen(str)+1);
1311         strcpy(pcop->name,str);
1312         
1313         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1314         
1315         PCOR(pcop)->r = dirregWithName(pcop->name);
1316         if(PCOR(pcop)->r == NULL) {
1317                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1318                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1319                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1320         } else {
1321                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1322         }
1323         PCOR(pcop)->instance = offset;
1324         
1325         return pcop;
1326 }
1327
1328 /*-----------------------------------------------------------------*/
1329 /*-----------------------------------------------------------------*/
1330 pCodeOp *popRegFromIdx(int rIdx)
1331 {
1332         pCodeOp *pcop;
1333         
1334         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1335                 __FUNCTION__,__LINE__,rIdx);
1336         
1337         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1338         
1339         PCOR(pcop)->rIdx = rIdx;
1340         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1341         PCOR(pcop)->r->isFree = 0;
1342         PCOR(pcop)->r->wasUsed = 1;
1343         
1344         pcop->type = PCOR(pcop)->r->pc_type;
1345         
1346         
1347         return pcop;
1348 }
1349
1350 /*-----------------------------------------------------------------*/
1351 /* popGet - asm operator to pcode operator conversion                      */
1352 /*-----------------------------------------------------------------*/
1353 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1354 {
1355         //char *s = buffer ;
1356         //char *rs;
1357         
1358         pCodeOp *pcop;
1359         
1360         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1361         /* offset is greater than
1362         size then zero */
1363
1364         if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0))))
1365         {
1366           fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size);
1367         }
1368         assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0)));
1369         
1370         /* XXX: still needed for BIT operands (AOP_CRY) */
1371         if (offset > (aop->size - 1) &&
1372                 aop->type != AOP_LIT)
1373                 return NULL;  //zero;
1374         
1375         /* depending on type */
1376         switch (aop->type) {
1377                 
1378         case AOP_R0:
1379         case AOP_R1:
1380         case AOP_DPTR:
1381         case AOP_DPTR2:
1382         case AOP_ACC:
1383                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1384                 return NULL;
1385                 
1386         case AOP_IMMD:
1387                 DEBUGpic14_emitcode(";","%d",__LINE__);
1388                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1389                 
1390         case AOP_DIR:
1391                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1392 #if 0
1393                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394                 pcop->type = PO_DIR;
1395                 
1396                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1397                 strcpy(pcop->name,aop->aopu.aop_dir);   
1398                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1399                 if(PCOR(pcop)->r == NULL) {
1400                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1401                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1402                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1403                 } else {
1404                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1405                 }
1406                 PCOR(pcop)->instance = offset;
1407                 
1408                 return pcop;
1409 #endif
1410                 
1411         case AOP_REG:
1412                 {
1413                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1414                         
1415                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1416                         PCOR(pcop)->rIdx = rIdx;
1417                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1418                         PCOR(pcop)->r->wasUsed=1;
1419                         PCOR(pcop)->r->isFree=0;
1420                         
1421                         PCOR(pcop)->instance = offset;
1422                         pcop->type = PCOR(pcop)->r->pc_type;
1423                         //rs = aop->aopu.aop_reg[offset]->name;
1424                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1425                         return pcop;
1426                 }
1427                 
1428         case AOP_CRY:
1429                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1430                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1431                 //if(PCOR(pcop)->r == NULL)
1432                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1433                 return pcop;
1434                 
1435         case AOP_LIT:
1436                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1437                 
1438         case AOP_STR:
1439                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1440                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1441                 /*
1442                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1443                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1444                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1445                 pcop->type = PCOR(pcop)->r->pc_type;
1446                 pcop->name = PCOR(pcop)->r->name;
1447                 
1448                   return pcop;
1449                 */
1450                 
1451         case AOP_PCODE:
1452                 pcop = NULL;
1453                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
1454                         __LINE__, 
1455                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1456                 //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
1457                 switch (aop->aopu.pcop->type)
1458                 {
1459                 case PO_IMMEDIATE:
1460                   pcop = pCodeOpCopy (aop->aopu.pcop);
1461                   /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1462                    * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1463                   PCOI(pcop)->index += offset;
1464                   //PCOI(pcop)->offset = 0;
1465                   break;
1466                 case PO_DIR:
1467                   pcop = pCodeOpCopy (aop->aopu.pcop);
1468                   PCOR(pcop)->instance = offset;
1469                   break;
1470                 default:
1471                   assert ( !"unhandled pCode type" );
1472                   break;
1473                 } // switch
1474                 return pcop;
1475         }
1476         
1477         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1478                 "popGet got unsupported aop->type");
1479         exit(0);
1480 }
1481
1482 /*-----------------------------------------------------------------*/
1483 /* popGetAddr - access the low/high word of a symbol (immediate)   */
1484 /*              (for non-PO_IMMEDIATEs this is the same as poGet)  */
1485 /*-----------------------------------------------------------------*/
1486 pCodeOp *popGetAddr (asmop *aop, int offset, int index)
1487 {
1488   if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
1489   {
1490     pCodeOp *pcop = aop->aopu.pcop;
1491     pcop = pCodeOpCopy (pcop);
1492     /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1493      * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1494     PCOI(pcop)->offset += offset;
1495     PCOI(pcop)->index += index;
1496     return pcop;
1497   } else {
1498     return popGet (aop, offset + index);
1499   }
1500 }
1501
1502 /*-----------------------------------------------------------------*/
1503 /* aopPut - puts a string for a aop                                                        */
1504 /*-----------------------------------------------------------------*/
1505 void aopPut (asmop *aop, char *s, int offset)
1506 {
1507         char *d = buffer ;
1508         symbol *lbl ;
1509         
1510         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1511         
1512         if (aop->size && offset > ( aop->size - 1)) {
1513                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1514                         "aopPut got offset > aop->size");
1515                 exit(0);
1516         }
1517         
1518         /* will assign value to value */
1519         /* depending on where it is ofcourse */
1520         switch (aop->type) {
1521         case AOP_DIR:
1522                 if (offset) {
1523                         sprintf(d,"(%s + %d)",
1524                                 aop->aopu.aop_dir,offset);
1525                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1526                         
1527                 } else
1528                         sprintf(d,"%s",aop->aopu.aop_dir);
1529                 
1530                 if (strcmp(d,s)) {
1531                         DEBUGpic14_emitcode(";","%d",__LINE__);
1532                         if(strcmp(s,"W"))
1533                                 pic14_emitcode("movf","%s,w",s);
1534                         pic14_emitcode("movwf","%s",d);
1535                         
1536                         if(strcmp(s,"W")) {
1537                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1538                                 if(offset >= aop->size) {
1539                                         emitpcode(POC_CLRF,popGet(aop,offset));
1540                                         break;
1541                                 } else
1542                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1543                         }
1544                         
1545                         emitpcode(POC_MOVWF,popGet(aop,offset));
1546                         
1547                         
1548                 }
1549                 break;
1550                 
1551         case AOP_REG:
1552                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1553                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1554                         /*
1555                         if (*s == '@'             ||
1556                         strcmp(s,"r0") == 0 ||
1557                         strcmp(s,"r1") == 0 ||
1558                         strcmp(s,"r2") == 0 ||
1559                         strcmp(s,"r3") == 0 ||
1560                         strcmp(s,"r4") == 0 ||
1561                         strcmp(s,"r5") == 0 ||
1562                         strcmp(s,"r6") == 0 || 
1563                         strcmp(s,"r7") == 0 )
1564                         pic14_emitcode("mov","%s,%s  ; %d",
1565                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1566                         else
1567                         */
1568                         
1569                         if(strcmp(s,"W")==0 )
1570                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1571                         
1572                         pic14_emitcode("movwf","%s",
1573                                 aop->aopu.aop_reg[offset]->name);
1574                         
1575                         if(strcmp(s,zero)==0) {
1576                                 emitpcode(POC_CLRF,popGet(aop,offset));
1577                                 
1578                         } else if(strcmp(s,"W")==0) {
1579                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1580                                 pcop->type = PO_GPR_REGISTER;
1581                                 
1582                                 PCOR(pcop)->rIdx = -1;
1583                                 PCOR(pcop)->r = NULL;
1584                                 
1585                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1586                                 pcop->name = Safe_strdup(s);
1587                                 emitpcode(POC_MOVFW,pcop);
1588                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1589                         } else if(strcmp(s,one)==0) {
1590                                 emitpcode(POC_CLRF,popGet(aop,offset));
1591                                 emitpcode(POC_INCF,popGet(aop,offset));
1592                         } else {
1593                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1594                         }
1595                 }
1596                 break;
1597                 
1598         case AOP_DPTR:
1599         case AOP_DPTR2:
1600                 
1601                 if (aop->type == AOP_DPTR2)
1602                 {
1603                         genSetDPTR(1);
1604                 }
1605                 
1606                 if (aop->code) {
1607                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1608                                 "aopPut writting to code space");
1609                         exit(0);
1610                 }
1611                 
1612                 while (offset > aop->coff) {
1613                         aop->coff++;
1614                         pic14_emitcode ("inc","dptr");
1615                 }
1616                 
1617                 while (offset < aop->coff) {
1618                         aop->coff-- ;
1619                         pic14_emitcode("lcall","__decdptr");
1620                 }
1621                 
1622                 aop->coff = offset;
1623                 
1624                 /* if not in accumulater */
1625                 MOVA(s);
1626                 
1627                 pic14_emitcode ("movx","@dptr,a");
1628                 
1629                 if (aop->type == AOP_DPTR2)
1630                 {
1631                         genSetDPTR(0);
1632                 }
1633                 break;
1634                 
1635         case AOP_R0:
1636         case AOP_R1:
1637                 while (offset > aop->coff) {
1638                         aop->coff++;
1639                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1640                 }
1641                 while (offset < aop->coff) {
1642                         aop->coff-- ;
1643                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1644                 }
1645                 aop->coff = offset;
1646                 
1647                 if (aop->paged) {
1648                         MOVA(s);                         
1649                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1650                         
1651                 } else
1652                         if (*s == '@') {
1653                                 MOVA(s);
1654                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1655                         } else
1656                                 if (strcmp(s,"r0") == 0 ||
1657                                         strcmp(s,"r1") == 0 ||
1658                                         strcmp(s,"r2") == 0 ||
1659                                         strcmp(s,"r3") == 0 ||
1660                                         strcmp(s,"r4") == 0 ||
1661                                         strcmp(s,"r5") == 0 ||
1662                                         strcmp(s,"r6") == 0 || 
1663                                         strcmp(s,"r7") == 0 ) {
1664                                         char buffer[10];
1665                                         sprintf(buffer,"a%s",s);
1666                                         pic14_emitcode("mov","@%s,%s",
1667                                                 aop->aopu.aop_ptr->name,buffer);
1668                                 } else
1669                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1670                                 
1671                                 break;
1672                                 
1673         case AOP_STK:
1674                 if (strcmp(s,"a") == 0)
1675                         pic14_emitcode("push","acc");
1676                 else
1677                         pic14_emitcode("push","%s",s);
1678                 
1679                 break;
1680                 
1681         case AOP_CRY:
1682                 /* if bit variable */
1683                 if (!aop->aopu.aop_dir) {
1684                         pic14_emitcode("clr","a");
1685                         pic14_emitcode("rlc","a");
1686                 } else {
1687                         if (s == zero) 
1688                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1689                         else
1690                                 if (s == one)
1691                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1692                                 else
1693                                         if (!strcmp(s,"c"))
1694                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1695                                         else {
1696                                                 lbl = newiTempLabel(NULL);
1697                                                 
1698                                                 if (strcmp(s,"a")) {
1699                                                         MOVA(s);
1700                                                 }
1701                                                 pic14_emitcode("clr","c");
1702                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1703                                                 pic14_emitcode("cpl","c");
1704                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1705                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1706                                         }
1707                 }
1708                 break;
1709                 
1710         case AOP_STR:
1711                 aop->coff = offset;
1712                 if (strcmp(aop->aopu.aop_str[offset],s))
1713                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1714                 break;
1715                 
1716         case AOP_ACC:
1717                 aop->coff = offset;
1718                 if (!offset && (strcmp(s,"acc") == 0))
1719                         break;
1720                 
1721                 if (strcmp(aop->aopu.aop_str[offset],s))
1722                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1723                 break;
1724                 
1725         default :
1726                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1727                         "aopPut got unsupported aop->type");
1728                 exit(0);
1729         }
1730         
1731 }
1732
1733 /*-----------------------------------------------------------------*/
1734 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1735 /*-----------------------------------------------------------------*/
1736 void mov2w (asmop *aop, int offset)
1737 {
1738         
1739         if(!aop)
1740                 return;
1741         
1742         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1743         
1744         if ( aop_isLitLike (aop) )
1745                 emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
1746         else
1747                 emitpcode(POC_MOVFW,popGet(aop,offset));
1748         
1749 }
1750
1751 /*-----------------------------------------------------------------*/
1752 /* reAdjustPreg - points a register back to where it should        */
1753 /*-----------------------------------------------------------------*/
1754 static void reAdjustPreg (asmop *aop)
1755 {
1756         int size ;
1757         
1758         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1759         aop->coff = 0;
1760         if ((size = aop->size) <= 1)
1761                 return ;
1762         size-- ;
1763         switch (aop->type) {
1764         case AOP_R0 :
1765         case AOP_R1 :
1766                 while (size--)
1767                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1768                 break;                  
1769         case AOP_DPTR :
1770         case AOP_DPTR2:
1771                 if (aop->type == AOP_DPTR2)
1772                 {
1773                         genSetDPTR(1);
1774                 } 
1775                 while (size--)
1776                 {
1777                         pic14_emitcode("lcall","__decdptr");
1778                 }
1779                 
1780                 if (aop->type == AOP_DPTR2)
1781                 {
1782                         genSetDPTR(0);
1783                 }
1784                 break;
1785                 
1786         }
1787         
1788 }
1789
1790
1791 #if 0
1792 /*-----------------------------------------------------------------*/
1793 /* opIsGptr: returns non-zero if the passed operand is             */
1794 /* a generic pointer type.                                         */
1795 /*-----------------------------------------------------------------*/ 
1796 static int opIsGptr(operand *op)
1797 {
1798         sym_link *type = operandType(op);
1799         
1800         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1801         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1802         {
1803                 return 1;
1804         }
1805         return 0;          
1806 }
1807 #endif
1808
1809 /*-----------------------------------------------------------------*/
1810 /* pic14_getDataSize - get the operand data size                   */
1811 /*-----------------------------------------------------------------*/
1812 int pic14_getDataSize(operand *op)
1813 {
1814         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1815         
1816         
1817         return AOP_SIZE(op);
1818         
1819         // tsd- in the pic port, the genptr size is 1, so this code here
1820         // fails. ( in the 8051 port, the size was 4).
1821 #if 0
1822         int size;
1823         size = AOP_SIZE(op);
1824         if (size == GPTRSIZE)
1825         {
1826                 sym_link *type = operandType(op);
1827                 if (IS_GENPTR(type))
1828                 {
1829                         /* generic pointer; arithmetic operations
1830                         * should ignore the high byte (pointer type).
1831                         */
1832                         size--;
1833                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1834                 }
1835         }
1836         return size;
1837 #endif
1838 }
1839
1840 /*-----------------------------------------------------------------*/
1841 /* pic14_outAcc - output Acc                                       */
1842 /*-----------------------------------------------------------------*/
1843 void pic14_outAcc(operand *result)
1844 {
1845         int size,offset;
1846         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1847         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1848         
1849         
1850         size = pic14_getDataSize(result);
1851         if(size){
1852                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1853                 size--;
1854                 offset = 1;
1855                 /* unsigned or positive */
1856                 while(size--)
1857                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1858         }
1859         
1860 }
1861
1862 /*-----------------------------------------------------------------*/
1863 /* pic14_outBitC - output a bit C                                  */
1864 /*-----------------------------------------------------------------*/
1865 void pic14_outBitC(operand *result)
1866 {
1867         
1868         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1869         /* if the result is bit */
1870         if (AOP_TYPE(result) == AOP_CRY) 
1871                 aopPut(AOP(result),"c",0);
1872         else {
1873                 pic14_emitcode("clr","a  ; %d", __LINE__);
1874                 pic14_emitcode("rlc","a");
1875                 pic14_outAcc(result);
1876         }
1877 }
1878
1879 /*-----------------------------------------------------------------*/
1880 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1881 /*-----------------------------------------------------------------*/
1882 void pic14_toBoolean(operand *oper)
1883 {
1884         int size = AOP_SIZE(oper) - 1;
1885         int offset = 1;
1886         
1887         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1888         
1889         if ( AOP_TYPE(oper) != AOP_ACC) {
1890                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1891         }
1892         while (size--) {
1893                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1894         }
1895 }
1896
1897
1898 /*-----------------------------------------------------------------*/
1899 /* genNot - generate code for ! operation                          */
1900 /*-----------------------------------------------------------------*/
1901 static void genNot (iCode *ic)
1902 {
1903         symbol *tlbl;
1904         int size;
1905
1906         FENTRY;
1907         
1908         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1909         /* assign asmOps to operand & result */
1910         aopOp (IC_LEFT(ic),ic,FALSE);
1911         aopOp (IC_RESULT(ic),ic,TRUE);
1912         
1913         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1914         /* if in bit space then a special case */
1915         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1916                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1917                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1918                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1919                 } else {
1920                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1921                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1922                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1923                 }
1924                 goto release;
1925         }
1926         
1927         size = AOP_SIZE(IC_LEFT(ic));
1928         if(size == 1) {
1929                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1930                 emitpcode(POC_ANDLW,popGetLit(1));
1931                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1932                 goto release;
1933         }
1934         pic14_toBoolean(IC_LEFT(ic));
1935         
1936         tlbl = newiTempLabel(NULL);
1937         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1938         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1939         pic14_outBitC(IC_RESULT(ic));
1940         
1941 release:        
1942         /* release the aops */
1943         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1944         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1945 }
1946
1947
1948 /*-----------------------------------------------------------------*/
1949 /* genCpl - generate code for complement                                                   */
1950 /*-----------------------------------------------------------------*/
1951 static void genCpl (iCode *ic)
1952 {
1953         operand *left, *result;
1954         int size, offset=0;  
1955         
1956         FENTRY;
1957         
1958         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1959         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1960         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1961         
1962         /* if both are in bit space then 
1963         a special case */
1964         if (AOP_TYPE(result) == AOP_CRY &&
1965                 AOP_TYPE(left) == AOP_CRY ) { 
1966                 
1967                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1968                 pic14_emitcode("cpl","c"); 
1969                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1970                 goto release; 
1971         } 
1972         
1973         size = AOP_SIZE(result);
1974         while (size--) {
1975                 
1976                 if(AOP_TYPE(left) == AOP_ACC) 
1977                         emitpcode(POC_XORLW, popGetLit(0xff));
1978                 else
1979                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1980                 
1981                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1982                 offset++;
1983         }
1984         
1985         
1986 release:
1987         /* release the aops */
1988         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1989         freeAsmop(result,NULL,ic,TRUE);
1990 }
1991
1992 /*-----------------------------------------------------------------*/
1993 /* genUminusFloat - unary minus for floating points                        */
1994 /*-----------------------------------------------------------------*/
1995 static void genUminusFloat(operand *op,operand *result)
1996 {
1997         int size ,offset =0 ;
1998         char *l;
1999         
2000         FENTRY;
2001
2002         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2003         /* for this we just need to flip the 
2004         first it then copy the rest in place */
2005         size = AOP_SIZE(op) - 1;
2006         l = aopGet(AOP(op),3,FALSE,FALSE);
2007         
2008         MOVA(l);          
2009         
2010         pic14_emitcode("cpl","acc.7");
2011         aopPut(AOP(result),"a",3);      
2012         
2013         while(size--) {
2014                 aopPut(AOP(result),
2015                         aopGet(AOP(op),offset,FALSE,FALSE),
2016                         offset);
2017                 offset++;
2018         }                
2019 }
2020
2021 /*-----------------------------------------------------------------*/
2022 /* genUminus - unary minus code generation                                                 */
2023 /*-----------------------------------------------------------------*/
2024 static void genUminus (iCode *ic)
2025 {
2026         int size, i;
2027         sym_link *optype, *rtype;
2028         
2029         FENTRY;
2030         
2031         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2032         /* assign asmops */
2033         aopOp(IC_LEFT(ic),ic,FALSE);
2034         aopOp(IC_RESULT(ic),ic,TRUE);
2035         
2036         /* if both in bit space then special
2037         case */
2038         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2039                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
2040                 
2041                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
2042                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2043                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
2044                 
2045                 goto release; 
2046         } 
2047         
2048         optype = operandType(IC_LEFT(ic));
2049         rtype = operandType(IC_RESULT(ic));
2050         
2051         /* if float then do float stuff */
2052         if (IS_FLOAT(optype)) {
2053                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2054                 goto release;
2055         }
2056         
2057         /* otherwise subtract from zero by taking the 2's complement */
2058         size = AOP_SIZE(IC_LEFT(ic));
2059         
2060         for(i=0; i<size; i++) {
2061                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2062                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2063                 else {
2064                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2065                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2066                 }
2067         }
2068         
2069         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2070         for(i=1; i<size; i++) {
2071                 emitSKPNZ;
2072                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2073         }
2074         
2075 release:
2076         /* release the aops */
2077         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2078         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
2079 }
2080
2081 /*-----------------------------------------------------------------*/
2082 /* saveRegisters - will look for a call and save the registers     */
2083 /*-----------------------------------------------------------------*/
2084 static void saveRegisters(iCode *lic) 
2085 {
2086         int i;
2087         iCode *ic;
2088         bitVect *rsave;
2089         sym_link *dtype;
2090         
2091         FENTRY;
2092
2093         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2094         /* look for call */
2095         for (ic = lic ; ic ; ic = ic->next) 
2096                 if (ic->op == CALL || ic->op == PCALL)
2097                         break;
2098                 
2099                 if (!ic) {
2100                         fprintf(stderr,"found parameter push with no function call\n");
2101                         return ;
2102                 }
2103                 
2104                 /* if the registers have been saved already then
2105                 do nothing */
2106                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2107                         return ;
2108                 
2109                         /* find the registers in use at this time 
2110                 and push them away to safety */
2111                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2112                         ic->rUsed);
2113                 
2114                 ic->regsSaved = 1;
2115                 if (options.useXstack) {
2116                         if (bitVectBitValue(rsave,R0_IDX))
2117                                 pic14_emitcode("mov","b,r0");
2118                         pic14_emitcode("mov","r0,%s",spname);
2119                         for (i = 0 ; i < pic14_nRegs ; i++) {
2120                                 if (bitVectBitValue(rsave,i)) {
2121                                         if (i == R0_IDX)
2122                                                 pic14_emitcode("mov","a,b");
2123                                         else
2124                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2125                                         pic14_emitcode("movx","@r0,a");
2126                                         pic14_emitcode("inc","r0");
2127                                 }
2128                         }
2129                         pic14_emitcode("mov","%s,r0",spname);
2130                         if (bitVectBitValue(rsave,R0_IDX))
2131                                 pic14_emitcode("mov","r0,b");     
2132                 }// else
2133                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2134                 //        if (bitVectBitValue(rsave,i))
2135                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2136                 //}
2137                 
2138                 dtype = operandType(IC_LEFT(ic));
2139                 if (currFunc && dtype && 
2140                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2141                         IFFUNC_ISISR(currFunc->type) &&
2142                         !ic->bankSaved) 
2143                         
2144                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2145                 
2146 }
2147 /*-----------------------------------------------------------------*/
2148 /* unsaveRegisters - pop the pushed registers                                      */
2149 /*-----------------------------------------------------------------*/
2150 static void unsaveRegisters (iCode *ic)
2151 {
2152         int i;
2153         bitVect *rsave;
2154         
2155         FENTRY;
2156
2157         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2158         /* find the registers in use at this time 
2159         and push them away to safety */
2160         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2161                 ic->rUsed);
2162         
2163         if (options.useXstack) {
2164                 pic14_emitcode("mov","r0,%s",spname); 
2165                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2166                         if (bitVectBitValue(rsave,i)) {
2167                                 pic14_emitcode("dec","r0");
2168                                 pic14_emitcode("movx","a,@r0");
2169                                 if (i == R0_IDX)
2170                                         pic14_emitcode("mov","b,a");
2171                                 else
2172                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2173                         }       
2174                         
2175                 }
2176                 pic14_emitcode("mov","%s,r0",spname);
2177                 if (bitVectBitValue(rsave,R0_IDX))
2178                         pic14_emitcode("mov","r0,b");
2179         } //else
2180         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2181         //      if (bitVectBitValue(rsave,i))
2182         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2183         //}
2184         
2185 }  
2186
2187
2188 /*-----------------------------------------------------------------*/
2189 /* pushSide -                            */
2190 /*-----------------------------------------------------------------*/
2191 static void pushSide(operand * oper, int size)
2192 {
2193 #if 0
2194         int offset = 0;
2195         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2196         while (size--) {
2197                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2198                 if (AOP_TYPE(oper) != AOP_REG &&
2199                         AOP_TYPE(oper) != AOP_DIR &&
2200                         strcmp(l,"a") ) {
2201                         pic14_emitcode("mov","a,%s",l);
2202                         pic14_emitcode("push","acc");
2203                 } else
2204                         pic14_emitcode("push","%s",l);
2205         }
2206 #endif
2207 }
2208
2209 /*-----------------------------------------------------------------*/
2210 /* assignResultValue -                           */
2211 /*-----------------------------------------------------------------*/
2212 static void assignResultValue(operand * oper)
2213 {
2214         int size = AOP_SIZE(oper);
2215         
2216         FENTRY;
2217
2218         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2219         
2220         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2221         
2222         while (size--) {
2223                 if (GpsuedoStkPtr++)
2224                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2225                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2226         }
2227 }
2228
2229
2230 /*-----------------------------------------------------------------*/
2231 /* genIpush - genrate code for pushing this gets a little complex  */
2232 /*-----------------------------------------------------------------*/
2233 static void genIpush (iCode *ic)
2234 {
2235         FENTRY;
2236         
2237         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2238 #if 0
2239         int size, offset = 0 ;
2240         char *l;
2241         
2242         
2243         /* if this is not a parm push : ie. it is spill push 
2244         and spill push is always done on the local stack */
2245         if (!ic->parmPush) {
2246                 
2247                 /* and the item is spilt then do nothing */
2248                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2249                         return ;
2250                 
2251                 aopOp(IC_LEFT(ic),ic,FALSE);
2252                 size = AOP_SIZE(IC_LEFT(ic));
2253                 /* push it on the stack */
2254                 while(size--) {
2255                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2256                         if (*l == '#') {
2257                                 MOVA(l);
2258                                 l = "acc";
2259                         }
2260                         pic14_emitcode("push","%s",l);
2261                 }
2262                 return ;                
2263         }
2264         
2265         /* this is a paramter push: in this case we call
2266         the routine to find the call and save those
2267         registers that need to be saved */   
2268         saveRegisters(ic);
2269         
2270         /* then do the push */
2271         aopOp(IC_LEFT(ic),ic,FALSE);
2272         
2273         
2274         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2275         size = AOP_SIZE(IC_LEFT(ic));
2276         
2277         while (size--) {
2278                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2279                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2280                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2281                         strcmp(l,"a") ) {
2282                         pic14_emitcode("mov","a,%s",l);
2283                         pic14_emitcode("push","acc");
2284                 } else
2285                         pic14_emitcode("push","%s",l);
2286         }         
2287         
2288         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2289 #endif
2290 }
2291
2292 /*-----------------------------------------------------------------*/
2293 /* genIpop - recover the registers: can happen only for spilling   */
2294 /*-----------------------------------------------------------------*/
2295 static void genIpop (iCode *ic)
2296 {
2297         FENTRY;
2298
2299         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2300 #if 0
2301         int size,offset ;
2302         
2303         
2304         /* if the temp was not pushed then */
2305         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2306                 return ;
2307         
2308         aopOp(IC_LEFT(ic),ic,FALSE);
2309         size = AOP_SIZE(IC_LEFT(ic));
2310         offset = (size-1);
2311         while (size--) 
2312                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2313                 FALSE,TRUE));
2314         
2315         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2316 #endif
2317 }
2318
2319 /*-----------------------------------------------------------------*/
2320 /* unsaverbank - restores the resgister bank from stack                    */
2321 /*-----------------------------------------------------------------*/
2322 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2323 {
2324         FENTRY;
2325
2326         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2327 #if 0
2328         int i;
2329         asmop *aop ;
2330         regs *r = NULL;
2331         
2332         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2333         if (popPsw) {
2334                 if (options.useXstack) {
2335                         aop = newAsmop(0);
2336                         r = getFreePtr(ic,&aop,FALSE);
2337                         
2338                         
2339                         pic14_emitcode("mov","%s,_spx",r->name);
2340                         pic14_emitcode("movx","a,@%s",r->name);
2341                         pic14_emitcode("mov","psw,a");
2342                         pic14_emitcode("dec","%s",r->name);
2343                         
2344                 }else
2345                         pic14_emitcode ("pop","psw");
2346         }
2347         
2348         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2349                 if (options.useXstack) {           
2350                         pic14_emitcode("movx","a,@%s",r->name);
2351                         //pic14_emitcode("mov","(%s+%d),a",
2352                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2353                         pic14_emitcode("dec","%s",r->name);
2354                         
2355                 } else 
2356                         pic14_emitcode("pop",""); //"(%s+%d)",
2357                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2358         }
2359         
2360         if (options.useXstack) {
2361                 
2362                 pic14_emitcode("mov","_spx,%s",r->name);
2363                 freeAsmop(NULL,aop,ic,TRUE);
2364                 
2365         }
2366 #endif 
2367 }
2368
2369 /*-----------------------------------------------------------------*/
2370 /* saverbank - saves an entire register bank on the stack                  */
2371 /*-----------------------------------------------------------------*/
2372 static void saverbank (int bank, iCode *ic, bool pushPsw)
2373 {
2374         FENTRY;
2375
2376         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2377 #if 0
2378         int i;
2379         asmop *aop ;
2380         regs *r = NULL;
2381         
2382         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2383         if (options.useXstack) {
2384                 
2385                 aop = newAsmop(0);
2386                 r = getFreePtr(ic,&aop,FALSE);  
2387                 pic14_emitcode("mov","%s,_spx",r->name);
2388                 
2389         }
2390         
2391         for (i = 0 ; i < pic14_nRegs ;i++) {
2392                 if (options.useXstack) {
2393                         pic14_emitcode("inc","%s",r->name);
2394                         //pic14_emitcode("mov","a,(%s+%d)",
2395                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2396                         pic14_emitcode("movx","@%s,a",r->name);                 
2397                 } else 
2398                         pic14_emitcode("push","");// "(%s+%d)",
2399                 //regspic14[i].base,8*bank+regspic14[i].offset);
2400         }
2401         
2402         if (pushPsw) {
2403                 if (options.useXstack) {
2404                         pic14_emitcode("mov","a,psw");
2405                         pic14_emitcode("movx","@%s,a",r->name); 
2406                         pic14_emitcode("inc","%s",r->name);
2407                         pic14_emitcode("mov","_spx,%s",r->name);                 
2408                         freeAsmop (NULL,aop,ic,TRUE);
2409                         
2410                 } else
2411                         pic14_emitcode("push","psw");
2412                 
2413                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2414         }
2415         ic->bankSaved = 1;
2416 #endif
2417 }
2418
2419 /*-----------------------------------------------------------------*/
2420 /* genCall - generates a call statement                                                    */
2421 /*-----------------------------------------------------------------*/
2422 static void genCall (iCode *ic)
2423 {
2424         sym_link *dtype;         
2425         symbol *sym;
2426         unsigned char *name;
2427         int isExtern;
2428         
2429         FENTRY;
2430
2431         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2432         
2433         /* if caller saves & we have not saved then */
2434         if (!ic->regsSaved)
2435                 saveRegisters(ic);
2436         
2437                 /* if we are calling a function that is not using
2438                 the same register bank then we need to save the
2439         destination registers on the stack */
2440         dtype = operandType(IC_LEFT(ic));
2441         if (currFunc && dtype && 
2442                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2443                 IFFUNC_ISISR(currFunc->type) &&
2444                 !ic->bankSaved) 
2445                 
2446                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2447         
2448         /* if send set is not empty the assign */
2449         if (_G.sendSet) {
2450                 iCode *sic;
2451                 /* For the Pic port, there is no data stack.
2452                 * So parameters passed to functions are stored
2453                 * in registers. (The pCode optimizer will get
2454                 * rid of most of these :).
2455                 */
2456                 int psuedoStkPtr=-1;
2457                 int firstTimeThruLoop = 1;
2458                 
2459                 _G.sendSet = reverseSet(_G.sendSet);
2460                 
2461                 /* First figure how many parameters are getting passed */
2462                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2463                 sic = setNextItem(_G.sendSet)) {
2464                         
2465                         aopOp(IC_LEFT(sic),sic,FALSE);
2466                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2467                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2468                 }
2469                 
2470                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2471                 sic = setNextItem(_G.sendSet)) {
2472                         int size, offset = 0;
2473                         
2474                         aopOp(IC_LEFT(sic),sic,FALSE);
2475                         size = AOP_SIZE(IC_LEFT(sic));
2476                         
2477                         while (size--) {
2478                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2479                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2480                                 
2481                                 if(!firstTimeThruLoop) {
2482                                         /* If this is not the first time we've been through the loop
2483                                         * then we need to save the parameter in a temporary
2484                                         * register. The last byte of the last parameter is
2485                                         * passed in W. */
2486                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2487                                         
2488                                 }
2489                                 firstTimeThruLoop=0;
2490                                 
2491                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2492                                 offset++;
2493                         }
2494                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2495                 }
2496                 _G.sendSet = NULL;
2497         }
2498         /* make the call */
2499         sym = OP_SYMBOL(IC_LEFT(ic));
2500         name = sym->rname[0] ? sym->rname : sym->name;
2501         isExtern = IS_EXTERN(sym->etype);
2502         if (isExtern) {
2503                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2504         }
2505         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2506         if (isExtern) {
2507                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2508         }
2509         GpsuedoStkPtr=0;
2510         /* if we need assign a result value */
2511         if ((IS_ITEMP(IC_RESULT(ic)) && 
2512                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2513                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2514                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2515                 
2516                 _G.accInUse++;
2517                 aopOp(IC_RESULT(ic),ic,FALSE);
2518                 _G.accInUse--;
2519                 
2520                 assignResultValue(IC_RESULT(ic));
2521                 
2522                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2523                         AopType(AOP_TYPE(IC_RESULT(ic))));
2524                 
2525                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2526         }
2527         
2528         /* adjust the stack for parameters if 
2529         required */
2530         if (ic->parmBytes) {
2531                 int i;
2532                 if (ic->parmBytes > 3) {
2533                         pic14_emitcode("mov","a,%s",spname);
2534                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2535                         pic14_emitcode("mov","%s,a",spname);
2536                 } else 
2537                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2538                                 pic14_emitcode("dec","%s",spname);
2539                         
2540         }
2541         
2542         /* if register bank was saved then pop them */
2543         if (ic->bankSaved)
2544                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2545         
2546         /* if we hade saved some registers then unsave them */
2547         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2548                 unsaveRegisters (ic);
2549         
2550         
2551 }
2552
2553 /*-----------------------------------------------------------------*/
2554 /* genPcall - generates a call by pointer statement                        */
2555 /*-----------------------------------------------------------------*/
2556 static void genPcall (iCode *ic)
2557 {
2558         sym_link *dtype;
2559         symbol *albl = newiTempLabel(NULL);
2560         symbol *blbl = newiTempLabel(NULL);
2561         PIC_OPCODE poc;
2562         pCodeOp *pcop;
2563         operand *left;
2564         
2565         FENTRY;
2566
2567         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2568         /* if caller saves & we have not saved then */
2569         if (!ic->regsSaved)
2570                 saveRegisters(ic);
2571         
2572                 /* if we are calling a function that is not using
2573                 the same register bank then we need to save the
2574         destination registers on the stack */
2575         dtype = operandType(IC_LEFT(ic));
2576         if (currFunc && dtype && 
2577                 IFFUNC_ISISR(currFunc->type) &&
2578                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2579                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2580         
2581         left = IC_LEFT(ic);
2582         aopOp(left,ic,FALSE);
2583         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2584         
2585         pushSide(IC_LEFT(ic), FPTRSIZE);
2586         
2587         /* if send set is not empty, assign parameters */
2588         if (_G.sendSet) {
2589                 
2590                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2591                 /* no way to pass args - W always gets used to make the call */
2592         }
2593         /* first idea - factor out a common helper function and call it.
2594         But don't know how to get it generated only once in its own block
2595         
2596         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2597                 char *rname;
2598                 char *buffer;
2599                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2600                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2601                 buffer = Safe_calloc(1,strlen(rname)+16);
2602                 sprintf(buffer, "%s_goto_helper", rname);
2603                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2604                 free(buffer);
2605         }
2606         */
2607         emitpcode(POC_CALL,popGetLabel(albl->key));
2608         pcop = popGetLabel(blbl->key);
2609         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2610         emitpcode(POC_GOTO,pcop);
2611         emitpLabel(albl->key);
2612         
2613         poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW );
2614         
2615         emitpcode(poc,popGetAddr(AOP(left),1,0));
2616         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2617         emitpcode(poc,popGetAddr(AOP(left),0,0));
2618         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2619         
2620         emitpLabel(blbl->key);
2621         
2622         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2623         
2624         /* if we need to assign a result value */
2625         if ((IS_ITEMP(IC_RESULT(ic)) &&
2626                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2627                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2628                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2629                 
2630                 _G.accInUse++;
2631                 aopOp(IC_RESULT(ic),ic,FALSE);
2632                 _G.accInUse--;
2633                 
2634                 assignResultValue(IC_RESULT(ic));
2635                 
2636                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2637         }
2638         
2639         /* if register bank was saved then unsave them */
2640         if (currFunc && dtype && 
2641                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2642                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2643         
2644                 /* if we hade saved some registers then
2645         unsave them */
2646         if (ic->regsSaved)
2647                 unsaveRegisters (ic);
2648         
2649 }
2650
2651 /*-----------------------------------------------------------------*/
2652 /* resultRemat - result  is rematerializable                                       */
2653 /*-----------------------------------------------------------------*/
2654 static int resultRemat (iCode *ic)
2655 {
2656         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2657         FENTRY;
2658
2659         if (SKIP_IC(ic) || ic->op == IFX)
2660                 return 0;
2661         
2662         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2663                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2664                 if (sym->remat && !POINTER_SET(ic)) 
2665                         return 1;
2666         }
2667         
2668         return 0;
2669 }
2670
2671 #if defined(__BORLANDC__) || defined(_MSC_VER)
2672 #define STRCASECMP stricmp
2673 #else
2674 #define STRCASECMP strcasecmp
2675 #endif
2676
2677 #if 0
2678 /*-----------------------------------------------------------------*/
2679 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2680 /*-----------------------------------------------------------------*/
2681 static bool inExcludeList(char *s)
2682 {
2683         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2684         int i =0;
2685         
2686         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2687         if (options.excludeRegs[i] &&
2688                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2689                 return FALSE ;
2690         
2691         for ( i = 0 ; options.excludeRegs[i]; i++) {
2692                 if (options.excludeRegs[i] &&
2693                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2694                         return TRUE;
2695         }
2696         return FALSE ;
2697 }
2698 #endif
2699
2700 /*-----------------------------------------------------------------*/
2701 /* genFunction - generated code for function entry                                 */
2702 /*-----------------------------------------------------------------*/
2703 static void genFunction (iCode *ic)
2704 {
2705         symbol *sym;
2706         sym_link *ftype;
2707         
2708         FENTRY;
2709
2710         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2711         
2712         labelOffset += (max_key+4);
2713         max_key=0;
2714         GpsuedoStkPtr=0;
2715         _G.nRegsSaved = 0;
2716         /* create the function header */
2717         pic14_emitcode(";","-----------------------------------------");
2718         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2719         pic14_emitcode(";","-----------------------------------------");
2720         
2721         pic14_emitcode("","%s:",sym->rname);
2722         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2723         
2724         ftype = operandType(IC_LEFT(ic));
2725         
2726         /* if critical function then turn interrupts off */
2727         if (IFFUNC_ISCRITICAL(ftype))
2728                 pic14_emitcode("clr","ea");
2729         
2730                 /* here we need to generate the equates for the
2731         register bank if required */
2732 #if 0
2733         if (FUNC_REGBANK(ftype) != rbank) {
2734                 int i ;
2735                 
2736                 rbank = FUNC_REGBANK(ftype);
2737                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2738                         if (strcmp(regspic14[i].base,"0") == 0)
2739                                 pic14_emitcode("","%s = 0x%02x",
2740                                 regspic14[i].dname,
2741                                 8*rbank+regspic14[i].offset);
2742                         else
2743                                 pic14_emitcode ("","%s = %s + 0x%02x",
2744                                 regspic14[i].dname,
2745                                 regspic14[i].base,
2746                                 8*rbank+regspic14[i].offset);
2747                 }
2748         }
2749 #endif
2750         
2751         /* if this is an interrupt service routine */
2752         if (IFFUNC_ISISR(sym->type)) {
2753         /*  already done in pic14createInterruptVect() - delete me
2754         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2755         emitpcodeNULLop(POC_NOP);
2756         emitpcodeNULLop(POC_NOP);
2757         emitpcodeNULLop(POC_NOP);
2758                 */
2759                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2760                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2761                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2762                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2763                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2764                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2765                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2766                 
2767                 pBlockConvert2ISR(pb);
2768 #if 0  
2769                 if (!inExcludeList("acc"))              
2770                         pic14_emitcode ("push","acc");  
2771                 if (!inExcludeList("b"))
2772                         pic14_emitcode ("push","b");
2773                 if (!inExcludeList("dpl"))
2774                         pic14_emitcode ("push","dpl");
2775                 if (!inExcludeList("dph"))
2776                         pic14_emitcode ("push","dph");
2777                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2778                 {
2779                         pic14_emitcode ("push", "dpx");
2780                         /* Make sure we're using standard DPTR */
2781                         pic14_emitcode ("push", "dps");
2782                         pic14_emitcode ("mov", "dps, #0x00");
2783                         if (options.stack10bit)
2784                         { 
2785                                 /* This ISR could conceivably use DPTR2. Better save it. */
2786                                 pic14_emitcode ("push", "dpl1");
2787                                 pic14_emitcode ("push", "dph1");
2788                                 pic14_emitcode ("push", "dpx1");
2789                         }
2790                 }
2791                 /* if this isr has no bank i.e. is going to
2792                 run with bank 0 , then we need to save more
2793                 registers :-) */
2794                 if (!FUNC_REGBANK(sym->type)) {
2795                         
2796                 /* if this function does not call any other
2797                 function then we can be economical and
2798                         save only those registers that are used */
2799                         if (! IFFUNC_HASFCALL(sym->type)) {
2800                                 int i;
2801                                 
2802                                 /* if any registers used */
2803                                 if (sym->regsUsed) {
2804                                         /* save the registers used */
2805                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2806                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2807                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2808                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2809                                         }
2810                                 }
2811                                 
2812                         } else {
2813                         /* this function has    a function call cannot
2814                         determines register usage so we will have the
2815                                 entire bank */
2816                                 saverbank(0,ic,FALSE);
2817                         }       
2818                 }
2819 #endif
2820         } else {
2821         /* if callee-save to be used for this function
2822                 then save the registers being used in this function */
2823                 if (IFFUNC_CALLEESAVES(sym->type)) {
2824                         int i;
2825                         
2826                         /* if any registers used */
2827                         if (sym->regsUsed) {
2828                                 /* save the registers used */
2829                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2830                                         if (bitVectBitValue(sym->regsUsed,i) ||
2831                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2832                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2833                                                 _G.nRegsSaved++;
2834                                         }
2835                                 }
2836                         }
2837                 }
2838         }
2839         
2840         /* set the register bank to the desired value */
2841         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2842                 pic14_emitcode("push","psw");
2843                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2844         }
2845         
2846         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2847                 
2848                 if (options.useXstack) {
2849                         pic14_emitcode("mov","r0,%s",spname);
2850                         pic14_emitcode("mov","a,_bp");
2851                         pic14_emitcode("movx","@r0,a");
2852                         pic14_emitcode("inc","%s",spname);
2853                 }
2854                 else
2855                 {
2856                         /* set up the stack */
2857                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2858                 }
2859                 pic14_emitcode ("mov","_bp,%s",spname);
2860         }
2861         
2862         /* adjust the stack for the function */
2863         if (sym->stack) {
2864                 
2865                 int i = sym->stack;
2866                 if (i > 256 ) 
2867                         werror(W_STACK_OVERFLOW,sym->name);
2868                 
2869                 if (i > 3 && sym->recvSize < 4) {                
2870                         
2871                         pic14_emitcode ("mov","a,sp");
2872                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2873                         pic14_emitcode ("mov","sp,a");
2874                         
2875                 }
2876                 else
2877                         while(i--)
2878                                 pic14_emitcode("inc","sp");
2879         }
2880         
2881         if (sym->xstack) {
2882                 
2883                 pic14_emitcode ("mov","a,_spx");
2884                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2885                 pic14_emitcode ("mov","_spx,a");
2886         }
2887         
2888 }
2889
2890 /*-----------------------------------------------------------------*/
2891 /* genEndFunction - generates epilogue for functions                       */
2892 /*-----------------------------------------------------------------*/
2893 static void genEndFunction (iCode *ic)
2894 {
2895         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2896         
2897         FENTRY;
2898
2899         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2900         
2901         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2902         {
2903                 pic14_emitcode ("mov","%s,_bp",spname);
2904         }
2905         
2906         /* if use external stack but some variables were
2907         added to the local stack then decrement the
2908         local stack */
2909         if (options.useXstack && sym->stack) {    
2910                 pic14_emitcode("mov","a,sp");
2911                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2912                 pic14_emitcode("mov","sp,a");
2913         }
2914         
2915         
2916         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2917                 if (options.useXstack) {
2918                         pic14_emitcode("mov","r0,%s",spname);
2919                         pic14_emitcode("movx","a,@r0");
2920                         pic14_emitcode("mov","_bp,a");
2921                         pic14_emitcode("dec","%s",spname);
2922                 }
2923                 else
2924                 {
2925                         pic14_emitcode ("pop","_bp");
2926                 }
2927         }
2928         
2929         /* restore the register bank    */        
2930         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2931                 pic14_emitcode ("pop","psw");
2932         
2933         if (IFFUNC_ISISR(sym->type)) {
2934                 
2935                 /* now we need to restore the registers */
2936                 /* if this isr has no bank i.e. is going to
2937                 run with bank 0 , then we need to save more
2938 registers :-) */
2939                 if (!FUNC_REGBANK(sym->type)) {
2940                         
2941                 /* if this function does not call any other
2942                 function then we can be economical and
2943                         save only those registers that are used */
2944                         if (! IFFUNC_HASFCALL(sym->type)) {
2945                                 int i;
2946                                 
2947                                 /* if any registers used */
2948                                 if (sym->regsUsed) {
2949                                         /* save the registers used */
2950                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2951                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2952                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2953                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2954                                         }
2955                                 }
2956                                 
2957                         } else {
2958                         /* this function has    a function call cannot
2959                         determines register usage so we will have the
2960                                 entire bank */
2961                                 unsaverbank(0,ic,FALSE);
2962                         }       
2963                 }
2964 #if 0
2965                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2966                 {
2967                         if (options.stack10bit)
2968                         {
2969                                 pic14_emitcode ("pop", "dpx1");
2970                                 pic14_emitcode ("pop", "dph1");
2971                                 pic14_emitcode ("pop", "dpl1");
2972                         } 
2973                         pic14_emitcode ("pop", "dps");
2974                         pic14_emitcode ("pop", "dpx");
2975                 }
2976                 if (!inExcludeList("dph"))
2977                         pic14_emitcode ("pop","dph");
2978                 if (!inExcludeList("dpl"))
2979                         pic14_emitcode ("pop","dpl");
2980                 if (!inExcludeList("b"))
2981                         pic14_emitcode ("pop","b");
2982                 if (!inExcludeList("acc"))
2983                         pic14_emitcode ("pop","acc");
2984                 
2985                 if (IFFUNC_ISCRITICAL(sym->type))
2986                         pic14_emitcode("setb","ea");
2987 #endif
2988                 
2989                 /* if debug then send end of function */
2990                 /*      if (options.debug && currFunc) { */
2991                 if (currFunc) {
2992                         debugFile->writeEndFunction (currFunc, ic, 1);
2993                 }
2994                 
2995                 pic14_emitcode ("reti","");
2996                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2997                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2998                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2999                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
3000                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
3001                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
3002                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
3003                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
3004                 emitpcodeNULLop(POC_RETFIE);
3005         }
3006         else {
3007                 if (IFFUNC_ISCRITICAL(sym->type))
3008                         pic14_emitcode("setb","ea");
3009                 
3010                 if (IFFUNC_CALLEESAVES(sym->type)) {
3011                         int i;
3012                         
3013                         /* if any registers used */
3014                         if (sym->regsUsed) {
3015                                 /* save the registers used */
3016                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3017                                         if (bitVectBitValue(sym->regsUsed,i) ||
3018                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3019                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
3020                                 }
3021                         }
3022                         
3023                 }
3024                 
3025                 /* if debug then send end of function */
3026                 if (currFunc) {
3027                         debugFile->writeEndFunction (currFunc, ic, 1);
3028                 }
3029                 
3030                 pic14_emitcode ("return","");
3031                 emitpcodeNULLop(POC_RETURN);
3032                 
3033                 /* Mark the end of a function */
3034                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
3035         }
3036         
3037 }
3038
3039 /*-----------------------------------------------------------------*/
3040 /* genRet - generate code for return statement                                     */
3041 /*-----------------------------------------------------------------*/
3042 static void genRet (iCode *ic)
3043 {
3044         int size,offset = 0 , pushed = 0;
3045         
3046         FENTRY;
3047
3048         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3049         /* if we have no return value then
3050         just generate the "ret" */
3051         if (!IC_LEFT(ic)) 
3052                 goto jumpret;           
3053         
3054                 /* we have something to return then
3055         move the return value into place */
3056         aopOp(IC_LEFT(ic),ic,FALSE);
3057         size = AOP_SIZE(IC_LEFT(ic));
3058         
3059         while (size--) {
3060                 char *l ;
3061                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3062                         /* #NOCHANGE */
3063                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
3064                                 FALSE,TRUE);
3065                         pic14_emitcode("push","%s",l);
3066                         pushed++;
3067                 } else {
3068                         l = aopGet(AOP(IC_LEFT(ic)),offset,
3069                                 FALSE,FALSE);
3070                         if (strcmp(fReturn[offset],l)) {
3071                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
3072                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3073                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3074                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3075                                         emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
3076                                 }else {
3077                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3078                                 }
3079                                 if(size) {
3080                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
3081                                 }
3082                                 offset++;
3083                         }
3084                 }
3085         }
3086         
3087         if (pushed) {
3088                 while(pushed) {
3089                         pushed--;
3090                         if (strcmp(fReturn[pushed],"a"))
3091                                 pic14_emitcode("pop",fReturn[pushed]);
3092                         else
3093                                 pic14_emitcode("pop","acc");
3094                 }
3095         }
3096         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3097         
3098 jumpret:
3099         /* generate a jump to the return label
3100         if the next is not the return statement */
3101         if (!(ic->next && ic->next->op == LABEL &&
3102                 IC_LABEL(ic->next) == returnLabel)) {
3103                 
3104                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3105                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3106         }
3107         
3108 }
3109
3110 /*-----------------------------------------------------------------*/
3111 /* genLabel - generates a label                                                                    */
3112 /*-----------------------------------------------------------------*/
3113 static void genLabel (iCode *ic)
3114 {
3115         FENTRY;
3116
3117         /* special case never generate */
3118         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3119         if (IC_LABEL(ic) == entryLabel)
3120                 return ;
3121         
3122         emitpLabel(IC_LABEL(ic)->key);
3123         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3124 }
3125
3126 /*-----------------------------------------------------------------*/
3127 /* genGoto - generates a goto                                                                      */
3128 /*-----------------------------------------------------------------*/
3129 //tsd
3130 static void genGoto (iCode *ic)
3131 {
3132         FENTRY;
3133
3134         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3135         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3136 }
3137
3138
3139 /*-----------------------------------------------------------------*/
3140 /* genMultbits :- multiplication of bits                                                   */
3141 /*-----------------------------------------------------------------*/
3142 static void genMultbits (operand *left, 
3143                                                  operand *right, 
3144                                                  operand *result)
3145 {
3146         FENTRY;
3147         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3148         
3149         if(!pic14_sameRegs(AOP(result),AOP(right)))
3150                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3151         
3152         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3153         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3154         emitpcode(POC_BCF,  popGet(AOP(result),0));
3155         
3156 }
3157
3158
3159 /*-----------------------------------------------------------------*/
3160 /* genMultOneByte : 8 bit multiplication & division                        */
3161 /*-----------------------------------------------------------------*/
3162 static void genMultOneByte (operand *left,
3163                                                         operand *right,
3164                                                         operand *result)
3165 {
3166         sym_link *opetype = operandType(result);
3167         
3168         // symbol *lbl ;
3169         int size,offset;
3170         
3171         FENTRY;
3172         
3173         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3174         DEBUGpic14_AopType(__LINE__,left,right,result);
3175         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3176         
3177         /* (if two literals, the value is computed before) */
3178         /* if one literal, literal on the right */
3179         if (AOP_TYPE(left) == AOP_LIT){
3180                 operand *t = right;
3181                 right = left;
3182                 left = t;
3183         }
3184         
3185         size = AOP_SIZE(result);
3186         if(size == 1) {
3187                 
3188                 if (AOP_TYPE(right) == AOP_LIT){
3189                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3190                                 aopGet(AOP(right),0,FALSE,FALSE), 
3191                                 aopGet(AOP(left),0,FALSE,FALSE), 
3192                                 aopGet(AOP(result),0,FALSE,FALSE));
3193                         pic14_emitcode("call","genMultLit");
3194                 } else {
3195                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3196                                 aopGet(AOP(right),0,FALSE,FALSE), 
3197                                 aopGet(AOP(left),0,FALSE,FALSE), 
3198                                 aopGet(AOP(result),0,FALSE,FALSE));
3199                         pic14_emitcode("call","genMult8X8_8");
3200                         
3201                 }
3202                 genMult8X8_8 (left, right,result);
3203                 
3204                 
3205                 /* signed or unsigned */
3206                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3207                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3208                 //MOVA(l);               
3209                 //pic14_emitcode("mul","ab");
3210                 /* if result size = 1, mul signed = mul unsigned */
3211                 //aopPut(AOP(result),"a",0);
3212                 
3213         } else {        // (size > 1)
3214                 
3215                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3216                         aopGet(AOP(right),0,FALSE,FALSE), 
3217                         aopGet(AOP(left),0,FALSE,FALSE), 
3218                         aopGet(AOP(result),0,FALSE,FALSE));
3219                 
3220                 if (SPEC_USIGN(opetype)){
3221                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3222                         genUMult8X8_16 (left, right, result, NULL);
3223                         
3224                         if (size > 2) {
3225                                 /* for filling the MSBs */
3226                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3227                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3228                         }
3229                 }
3230                 else{
3231                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3232                         
3233                         pic14_emitcode("mov","a,b");
3234                         
3235                         /* adjust the MSB if left or right neg */
3236                         
3237                         /* if one literal */
3238                         if (AOP_TYPE(right) == AOP_LIT){
3239                                 pic14_emitcode("multiply ","right is a lit");
3240                                 /* AND literal negative */
3241                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3242                                         /* adjust MSB (c==0 after mul) */
3243                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3244                                 }
3245                         }
3246                         else{
3247                                 genSMult8X8_16 (left, right, result, NULL);
3248                         }
3249                         
3250                         if(size > 2){
3251                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3252                                 /* get the sign */
3253                                 pic14_emitcode("rlc","a");
3254                                 pic14_emitcode("subb","a,acc");
3255                         }
3256                 }
3257                 
3258                 size -= 2;
3259                 offset = 2;
3260                 if (size > 0)
3261                         while (size--)
3262                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3263                         //aopPut(AOP(result),"a",offset++);
3264         }
3265 }
3266
3267 /*-----------------------------------------------------------------*/
3268 /* genMult - generates code for multiplication                                     */
3269 /*-----------------------------------------------------------------*/
3270 static void genMult (iCode *ic)
3271 {
3272         operand *left = IC_LEFT(ic);
3273         operand *right = IC_RIGHT(ic);
3274         operand *result= IC_RESULT(ic); 
3275         
3276         FENTRY;
3277
3278         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3279         /* assign the amsops */
3280         aopOp (left,ic,FALSE);
3281         aopOp (right,ic,FALSE);
3282         aopOp (result,ic,TRUE);
3283         
3284         DEBUGpic14_AopType(__LINE__,left,right,result);
3285         
3286         /* special cases first */
3287         /* both are bits */
3288         if (AOP_TYPE(left) == AOP_CRY &&
3289                 AOP_TYPE(right)== AOP_CRY) {
3290                 genMultbits(left,right,result);
3291                 goto release ;
3292         }
3293         
3294         /* if both are of size == 1 */
3295         if (AOP_SIZE(left) == 1 &&
3296                 AOP_SIZE(right) == 1 ) {
3297                 genMultOneByte(left,right,result);
3298                 goto release ;
3299         }
3300         
3301         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3302         
3303         /* should have been converted to function call */
3304         //assert(0) ;
3305         
3306 release :
3307         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3308         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3309         freeAsmop(result,NULL,ic,TRUE); 
3310 }
3311
3312 /*-----------------------------------------------------------------*/
3313 /* genDivbits :- division of bits                                                                  */
3314 /*-----------------------------------------------------------------*/
3315 static void genDivbits (operand *left, 
3316                                                 operand *right, 
3317                                                 operand *result)
3318 {
3319         
3320         char *l;
3321         
3322         FENTRY;
3323
3324         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3325         /* the result must be bit */      
3326         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3327         l = aopGet(AOP(left),0,FALSE,FALSE);
3328         
3329         MOVA(l);          
3330         
3331         pic14_emitcode("div","ab");
3332         pic14_emitcode("rrc","a");
3333         aopPut(AOP(result),"c",0);
3334 }
3335
3336 /*-----------------------------------------------------------------*/
3337 /* genDivOneByte : 8 bit division                                                                  */
3338 /*-----------------------------------------------------------------*/
3339 static void genDivOneByte (operand *left,
3340                                                    operand *right,
3341                                                    operand *result)
3342 {
3343         sym_link *opetype = operandType(result);
3344         char *l ;
3345         symbol *lbl ;
3346         int size,offset;
3347         
3348         FENTRY;
3349         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3350         size = AOP_SIZE(result) - 1;
3351         offset = 1;
3352         /* signed or unsigned */
3353         if (SPEC_USIGN(opetype)) {
3354                 /* unsigned is easy */
3355                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3356                 l = aopGet(AOP(left),0,FALSE,FALSE);
3357                 MOVA(l);                
3358                 pic14_emitcode("div","ab");
3359                 aopPut(AOP(result),"a",0);
3360                 while (size--)
3361                         aopPut(AOP(result),zero,offset++);
3362                 return ;
3363         }
3364         
3365         /* signed is a little bit more difficult */
3366         
3367         /* save the signs of the operands */
3368         l = aopGet(AOP(left),0,FALSE,FALSE);      
3369         MOVA(l);          
3370         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3371         pic14_emitcode("push","acc"); /* save it on the stack */
3372         
3373         /* now sign adjust for both left & right */
3374         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3375         MOVA(l);                 
3376         lbl = newiTempLabel(NULL);
3377         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3378         pic14_emitcode("cpl","a");   
3379         pic14_emitcode("inc","a");
3380         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3381         pic14_emitcode("mov","b,a");
3382         
3383         /* sign adjust left side */
3384         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3385         MOVA(l);
3386         
3387         lbl = newiTempLabel(NULL);
3388         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3389         pic14_emitcode("cpl","a");
3390         pic14_emitcode("inc","a");
3391         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3392         
3393         /* now the division */
3394         pic14_emitcode("div","ab");
3395         /* we are interested in the lower order
3396         only */
3397         pic14_emitcode("mov","b,a");
3398         lbl = newiTempLabel(NULL);
3399         pic14_emitcode("pop","acc");     
3400         /* if there was an over flow we don't 
3401         adjust the sign of the result */
3402         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3403         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3404         CLRC;
3405         pic14_emitcode("clr","a");
3406         pic14_emitcode("subb","a,b");
3407         pic14_emitcode("mov","b,a");
3408         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3409         
3410         /* now we are done */
3411         aopPut(AOP(result),"b",0);
3412         if(size > 0){
3413                 pic14_emitcode("mov","c,b.7");
3414                 pic14_emitcode("subb","a,acc");   
3415         }
3416         while (size--)
3417                 aopPut(AOP(result),"a",offset++);
3418         
3419 }
3420
3421 /*-----------------------------------------------------------------*/
3422 /* genDiv - generates code for division                                                    */
3423 /*-----------------------------------------------------------------*/
3424 static void genDiv (iCode *ic)
3425 {
3426         operand *left = IC_LEFT(ic);
3427         operand *right = IC_RIGHT(ic);
3428         operand *result= IC_RESULT(ic); 
3429         
3430         FENTRY;
3431         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3432         /* assign the amsops */
3433         aopOp (left,ic,FALSE);
3434         aopOp (right,ic,FALSE);
3435         aopOp (result,ic,TRUE);
3436         
3437         /* special cases first */
3438         /* both are bits */
3439         if (AOP_TYPE(left) == AOP_CRY &&
3440                 AOP_TYPE(right)== AOP_CRY) {
3441                 genDivbits(left,right,result);
3442                 goto release ;
3443         }
3444         
3445         /* if both are of size == 1 */
3446         if (AOP_SIZE(left) == 1 &&
3447                 AOP_SIZE(right) == 1 ) {
3448                 genDivOneByte(left,right,result);
3449                 goto release ;
3450         }
3451         
3452         /* should have been converted to function call */
3453         assert(0);
3454 release :
3455         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3456         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3457         freeAsmop(result,NULL,ic,TRUE); 
3458 }
3459
3460 /*-----------------------------------------------------------------*/
3461 /* genModbits :- modulus of bits                                                                   */
3462 /*-----------------------------------------------------------------*/
3463 static void genModbits (operand *left, 
3464                                                 operand *right, 
3465                                                 operand *result)
3466 {
3467         
3468         char *l;
3469         
3470         FENTRY;
3471         /* the result must be bit */      
3472         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3473         l = aopGet(AOP(left),0,FALSE,FALSE);
3474         
3475         MOVA(l);
3476         
3477         pic14_emitcode("div","ab");
3478         pic14_emitcode("mov","a,b");
3479         pic14_emitcode("rrc","a");
3480         aopPut(AOP(result),"c",0);
3481 }
3482
3483 /*-----------------------------------------------------------------*/
3484 /* genModOneByte : 8 bit modulus                                                                   */
3485 /*-----------------------------------------------------------------*/
3486 static void genModOneByte (operand *left,
3487                                                    operand *right,
3488                                                    operand *result)
3489 {
3490         sym_link *opetype = operandType(result);
3491         char *l ;
3492         symbol *lbl ;
3493         
3494         FENTRY;
3495         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3496         /* signed or unsigned */
3497         if (SPEC_USIGN(opetype)) {
3498                 /* unsigned is easy */
3499                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3500                 l = aopGet(AOP(left),0,FALSE,FALSE);
3501                 MOVA(l);        
3502                 pic14_emitcode("div","ab");
3503                 aopPut(AOP(result),"b",0);
3504                 return ;
3505         }
3506         
3507         /* signed is a little bit more difficult */
3508         
3509         /* save the signs of the operands */
3510         l = aopGet(AOP(left),0,FALSE,FALSE);      
3511         MOVA(l);
3512         
3513         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3514         pic14_emitcode("push","acc"); /* save it on the stack */
3515         
3516         /* now sign adjust for both left & right */
3517         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3518         MOVA(l);
3519         
3520         lbl = newiTempLabel(NULL);
3521         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3522         pic14_emitcode("cpl","a");   
3523         pic14_emitcode("inc","a");
3524         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3525         pic14_emitcode("mov","b,a"); 
3526         
3527         /* sign adjust left side */
3528         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3529         MOVA(l);
3530         
3531         lbl = newiTempLabel(NULL);
3532         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3533         pic14_emitcode("cpl","a");   
3534         pic14_emitcode("inc","a");
3535         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3536         
3537         /* now the multiplication */
3538         pic14_emitcode("div","ab");
3539         /* we are interested in the lower order
3540         only */
3541         lbl = newiTempLabel(NULL);
3542         pic14_emitcode("pop","acc");     
3543         /* if there was an over flow we don't 
3544         adjust the sign of the result */
3545         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3546         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3547         CLRC ;
3548         pic14_emitcode("clr","a");
3549         pic14_emitcode("subb","a,b");
3550         pic14_emitcode("mov","b,a");
3551         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3552         
3553         /* now we are done */
3554         aopPut(AOP(result),"b",0);
3555         
3556 }
3557
3558 /*-----------------------------------------------------------------*/
3559 /* genMod - generates code for division                                                    */
3560 /*-----------------------------------------------------------------*/
3561 static void genMod (iCode *ic)
3562 {
3563         operand *left = IC_LEFT(ic);
3564         operand *right = IC_RIGHT(ic);
3565         operand *result= IC_RESULT(ic);  
3566         
3567         FENTRY;
3568         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3569         /* assign the amsops */
3570         aopOp (left,ic,FALSE);
3571         aopOp (right,ic,FALSE);
3572         aopOp (result,ic,TRUE);
3573         
3574         /* special cases first */
3575         /* both are bits */
3576         if (AOP_TYPE(left) == AOP_CRY &&
3577                 AOP_TYPE(right)== AOP_CRY) {
3578                 genModbits(left,right,result);
3579                 goto release ;
3580         }
3581         
3582         /* if both are of size == 1 */
3583         if (AOP_SIZE(left) == 1 &&
3584                 AOP_SIZE(right) == 1 ) {
3585                 genModOneByte(left,right,result);
3586                 goto release ;
3587         }
3588         
3589         /* should have been converted to function call */
3590         assert(0);
3591         
3592 release :
3593         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3594         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3595         freeAsmop(result,NULL,ic,TRUE); 
3596 }
3597
3598 /*-----------------------------------------------------------------*/
3599 /* genIfxJump :- will create a jump depending on the ifx                   */
3600 /*-----------------------------------------------------------------*/
3601 /*
3602 note: May need to add parameter to indicate when a variable is in bit space.
3603 */
3604 static void genIfxJump (iCode *ic, char *jval)
3605 {
3606         
3607         FENTRY;
3608         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3609         /* if true label then we jump if condition
3610         supplied is true */
3611         if ( IC_TRUE(ic) ) {
3612                 
3613                 if(strcmp(jval,"a") == 0)
3614                         emitSKPZ;
3615                 else if (strcmp(jval,"c") == 0)
3616                         emitSKPC;
3617                 else {
3618                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3619                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3620                 }
3621                 
3622                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3623                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3624                 
3625         }
3626         else {
3627                 /* false label is present */
3628                 if(strcmp(jval,"a") == 0)
3629                         emitSKPNZ;
3630                 else if (strcmp(jval,"c") == 0)
3631                         emitSKPNC;
3632                 else {
3633                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3634                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3635                 }
3636                 
3637                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3638                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3639                 
3640         }
3641         
3642         
3643         /* mark the icode as generated */
3644         ic->generated = 1;
3645 }
3646
3647 /*-----------------------------------------------------------------*/
3648 /* genSkip                                                                                                                 */
3649 /*-----------------------------------------------------------------*/
3650 static void genSkip(iCode *ifx,int status_bit)
3651 {
3652         FENTRY;
3653         if(!ifx)
3654                 return;
3655         
3656         if ( IC_TRUE(ifx) ) {
3657                 switch(status_bit) {
3658                 case 'z':
3659                         emitSKPNZ;
3660                         break;
3661                         
3662                 case 'c':
3663                         emitSKPNC;
3664                         break;
3665                         
3666                 case 'd':
3667                         emitSKPDC;
3668                         break;
3669                         
3670                 }
3671                 
3672                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3673                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3674                 
3675         } else {
3676                 
3677                 switch(status_bit) {
3678                         
3679                 case 'z':
3680                         emitSKPZ;
3681                         break;
3682                         
3683                 case 'c':
3684                         emitSKPC;
3685                         break;
3686                         
3687                 case 'd':
3688                         emitSKPDC;
3689                         break;
3690                 }
3691                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3692                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3693                 
3694         }
3695         
3696 }
3697
3698 /*-----------------------------------------------------------------*/
3699 /* genSkipc                                                                                                        */
3700 /*-----------------------------------------------------------------*/
3701 static void genSkipc(resolvedIfx *rifx)
3702 {
3703         FENTRY;
3704         if(!rifx)
3705                 return;
3706         
3707         if(rifx->condition)
3708                 emitSKPC;
3709         else
3710                 emitSKPNC;
3711         
3712         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3713         rifx->generated = 1;
3714 }
3715
3716 /*-----------------------------------------------------------------*/
3717 /* genSkipz2                                                                                                       */
3718 /*-----------------------------------------------------------------*/
3719 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3720 {
3721         FENTRY;
3722         if(!rifx)
3723                 return;
3724         
3725         if( (rifx->condition ^ invert_condition) & 1)
3726                 emitSKPZ;
3727         else
3728                 emitSKPNZ;
3729         
3730         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3731         rifx->generated = 1;
3732 }
3733
3734 /*-----------------------------------------------------------------*/
3735 /* genSkipz                                                        */
3736 /*-----------------------------------------------------------------*/
3737 static void genSkipz(iCode *ifx, int condition)
3738 {
3739         FENTRY;
3740         if(!ifx)
3741                 return;
3742         
3743         if(condition)
3744                 emitSKPNZ;
3745         else
3746                 emitSKPZ;
3747         
3748         if ( IC_TRUE(ifx) )
3749                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3750         else
3751                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3752         
3753         if ( IC_TRUE(ifx) )
3754                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3755         else
3756                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3757         
3758 }
3759 /*-----------------------------------------------------------------*/
3760 /* genSkipCond                                                     */
3761 /*-----------------------------------------------------------------*/
3762 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3763 {
3764         FENTRY;
3765         if(!rifx)
3766                 return;
3767         
3768         if(rifx->condition)
3769                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3770         else
3771                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3772         
3773         
3774         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3775         rifx->generated = 1;
3776 }
3777
3778 #if 0
3779 /*-----------------------------------------------------------------*/
3780 /* genChkZeroes :- greater or less than comparison                 */
3781 /*     For each byte in a literal that is zero, inclusive or the   */
3782 /*     the corresponding byte in the operand with W                */
3783 /*     returns true if any of the bytes are zero                   */
3784 /*-----------------------------------------------------------------*/
3785 static int genChkZeroes(operand *op, int lit,  int size)
3786 {
3787         
3788         int i;
3789         int flag =1;
3790         
3791         while(size--) {
3792                 i = (lit >> (size*8)) & 0xff;
3793                 
3794                 if(i==0) {
3795                         if(flag) 
3796                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3797                         else
3798                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3799                         flag = 0;
3800                 }
3801         }
3802         
3803         return (flag==0);
3804 }
3805 #endif
3806
3807 /*-----------------------------------------------------------------*/
3808 /* genCmp :- greater or less than comparison                       */
3809 /*-----------------------------------------------------------------*/
3810 static void genCmp (operand *left,operand *right,
3811                                         operand *result, iCode *ifx, int sign)
3812 {
3813         int size; //, offset = 0 ;
3814         unsigned long lit = 0L,i = 0;
3815         resolvedIfx rFalseIfx;
3816         //  resolvedIfx rTrueIfx;
3817         symbol *truelbl;
3818
3819         FENTRY;
3820         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3821         /*
3822         if(ifx) {
3823         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3824         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3825         }
3826         */
3827         
3828         resolveIfx(&rFalseIfx,ifx);
3829         truelbl  = newiTempLabel(NULL);
3830         size = max(AOP_SIZE(left),AOP_SIZE(right));
3831         
3832         DEBUGpic14_AopType(__LINE__,left,right,result);
3833         
3834 #define _swapp
3835         
3836         /* if literal is on the right then swap with left */
3837         if ((AOP_TYPE(right) == AOP_LIT)) {
3838                 operand *tmp = right ;
3839                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3840                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3841 #ifdef _swapp
3842                 
3843                 lit = (lit - 1) & mask;
3844                 right = left;
3845                 left = tmp;
3846                 rFalseIfx.condition ^= 1;
3847 #endif
3848                 
3849         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3850                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3851         }
3852         
3853         
3854         //if(IC_TRUE(ifx) == NULL)
3855         /* if left & right are bit variables */
3856         if (AOP_TYPE(left) == AOP_CRY &&
3857                 AOP_TYPE(right) == AOP_CRY ) {
3858                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3859                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3860         } else {
3861         /* subtract right from left if at the
3862         end the carry flag is set then we know that
3863                 left is greater than right */
3864                 
3865                 symbol *lbl  = newiTempLabel(NULL);
3866                 
3867 #ifndef _swapp
3868                 if(AOP_TYPE(right) == AOP_LIT) {
3869                         
3870                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3871                         
3872                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3873                         
3874                         /* special cases */
3875                         
3876                         if(lit == 0) {
3877                                 
3878                                 if(sign != 0) 
3879                                         genSkipCond(&rFalseIfx,left,size-1,7);
3880                                 else 
3881                                         /* no need to compare to 0...*/
3882                                         /* NOTE: this is a de-generate compare that most certainly 
3883                                         *       creates some dead code. */
3884                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3885                                 
3886                                 if(ifx) ifx->generated = 1;
3887                                 return;
3888                                 
3889                         }
3890                         size--;
3891                         
3892                         if(size == 0) {
3893                                 //i = (lit >> (size*8)) & 0xff;
3894                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3895                                 
3896                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3897                                 
3898                                 i = ((0-lit) & 0xff);
3899                                 if(sign) {
3900                                         if( i == 0x81) { 
3901                                         /* lit is 0x7f, all signed chars are less than
3902                                                 * this except for 0x7f itself */
3903                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3904                                                 genSkipz2(&rFalseIfx,0);
3905                                         } else {
3906                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3907                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3908                                                 genSkipc(&rFalseIfx);
3909                                         }
3910                                         
3911                                 } else {
3912                                         if(lit == 1) {
3913                                                 genSkipz2(&rFalseIfx,1);
3914                                         } else {
3915                                                 emitpcode(POC_ADDLW, popGetLit(i));
3916                                                 genSkipc(&rFalseIfx);
3917                                         }
3918                                 }
3919                                 
3920                                 if(ifx) ifx->generated = 1;
3921                                 return;
3922                         }
3923                         
3924                         /* chars are out of the way. now do ints and longs */
3925                         
3926                         
3927                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3928                         
3929                         /* special cases */
3930                         
3931                         if(sign) {
3932                                 
3933                                 if(lit == 0) {
3934                                         genSkipCond(&rFalseIfx,left,size,7);
3935                                         if(ifx) ifx->generated = 1;
3936                                         return;
3937                                 }
3938                                 
3939                                 if(lit <0x100) {
3940                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3941                                         
3942                                         //rFalseIfx.condition ^= 1;
3943                                         //genSkipCond(&rFalseIfx,left,size,7);
3944                                         //rFalseIfx.condition ^= 1;
3945                                         
3946                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3947                                         if(rFalseIfx.condition)
3948                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3949                                         else
3950                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3951                                         
3952                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3953                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3954                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3955                                         
3956                                         while(size > 1)
3957                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3958                                         
3959                                         if(rFalseIfx.condition) {
3960                                                 emitSKPZ;
3961                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3962                                                 
3963                                         } else {
3964                                                 emitSKPNZ;
3965                                         }
3966                                         
3967                                         genSkipc(&rFalseIfx);
3968                                         emitpLabel(truelbl->key);
3969                                         if(ifx) ifx->generated = 1;
3970                                         return;
3971                                         
3972                                 }
3973                                 
3974                                 if(size == 1) {
3975                                         
3976                                         if( (lit & 0xff) == 0) {
3977                                                 /* lower byte is zero */
3978                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3979                                                 i = ((lit >> 8) & 0xff) ^0x80;
3980                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3981                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3982                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3983                                                 genSkipc(&rFalseIfx);
3984                                                 
3985                                                 
3986                                                 if(ifx) ifx->generated = 1;
3987                                                 return;
3988                                                 
3989                                         }
3990                                 } else {
3991                                         /* Special cases for signed longs */
3992                                         if( (lit & 0xffffff) == 0) {
3993                                                 /* lower byte is zero */
3994                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3995                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3996                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3997                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3998                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3999                                                 genSkipc(&rFalseIfx);
4000                                                 
4001                                                 
4002                                                 if(ifx) ifx->generated = 1;
4003                                                 return;
4004                                                 
4005                                         }
4006                                         
4007                                 }
4008                                 
4009                                 
4010                                 if(lit & (0x80 << (size*8))) {
4011                                         /* lit is negative */
4012                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4013                                         
4014                                         //genSkipCond(&rFalseIfx,left,size,7);
4015                                         
4016                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4017                                         
4018                                         if(rFalseIfx.condition)
4019                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4020                                         else
4021                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4022                                         
4023                                         
4024                                 } else {
4025                                         /* lit is positive */
4026                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4027                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4028                                         if(rFalseIfx.condition)
4029                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4030                                         else
4031                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4032                                         
4033                                 }
4034                                 
4035                                 /* There are no more special cases, so perform a general compare */
4036                                 
4037                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4038                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4039                                 
4040                                 while(size--) {
4041                                         
4042                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4043                                         emitSKPNZ;
4044                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4045                                 }
4046                                 //rFalseIfx.condition ^= 1;
4047                                 genSkipc(&rFalseIfx);
4048                                 
4049                                 emitpLabel(truelbl->key);
4050                                 
4051                                 if(ifx) ifx->generated = 1;
4052                                 return;
4053                                 
4054                                 
4055                         }
4056
4057
4058                         /* sign is out of the way. So now do an unsigned compare */
4059                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4060
4061
4062                         /* General case - compare to an unsigned literal on the right.*/
4063
4064                         i = (lit >> (size*8)) & 0xff;
4065                         emitpcode(POC_MOVLW, popGetLit(i));
4066                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4067                         while(size--) {
4068                                 i = (lit >> (size*8)) & 0xff;
4069                                 
4070                                 if(i) {
4071                                         emitpcode(POC_MOVLW, popGetLit(i));
4072                                         emitSKPNZ;
4073                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4074                                 } else {
4075                                 /* this byte of the lit is zero, 
4076                                         *if it's not the last then OR in the variable */
4077                                         if(size)
4078                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
4079                                 }
4080                         }
4081
4082
4083                 emitpLabel(lbl->key);
4084                 //if(emitFinalCheck)
4085                 genSkipc(&rFalseIfx);
4086                 if(sign)
4087                         emitpLabel(truelbl->key);
4088
4089                 if(ifx) ifx->generated = 1;
4090                 return;
4091
4092
4093                 }
4094 #endif  // _swapp
4095
4096                 if(AOP_TYPE(left) == AOP_LIT) {
4097                         //symbol *lbl = newiTempLabel(NULL);
4098                         
4099                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4100                         
4101                         
4102                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4103                         
4104                         /* Special cases */
4105                         if((lit == 0) && (sign == 0)){
4106                                 
4107                                 size--;
4108                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4109                                 while(size) 
4110                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
4111                                 
4112                                 genSkipz2(&rFalseIfx,0);
4113                                 if(ifx) ifx->generated = 1;
4114                                 return;
4115                         }
4116                         
4117                         if(size==1) {
4118                                 /* Special cases */
4119                                 lit &= 0xff;
4120                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4121                                         /* degenerate compare can never be true */
4122                                         if(rFalseIfx.condition == 0)
4123                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4124                                         
4125                                         if(ifx) ifx->generated = 1;
4126                                         return;
4127                                 }
4128                                 
4129                                 if(sign) {
4130                                         /* signed comparisons to a literal byte */
4131                                         
4132                                         int lp1 = (lit+1) & 0xff;
4133                                         
4134                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4135                                         switch (lp1) {
4136                                         case 0:
4137                                                 rFalseIfx.condition ^= 1;
4138                                                 genSkipCond(&rFalseIfx,right,0,7);
4139                                                 break;
4140                                         case 0x7f:
4141                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4142                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
4143                                                 genSkipz2(&rFalseIfx,1);
4144                                                 break;
4145                                         default:
4146                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4147                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4148                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4149                                                 rFalseIfx.condition ^= 1;
4150                                                 genSkipc(&rFalseIfx);
4151                                                 break;
4152                                         }
4153                                         if(ifx) ifx->generated = 1;
4154                                 } else {
4155                                         /* unsigned comparisons to a literal byte */
4156                                         
4157                                         switch(lit & 0xff ) {
4158                                         case 0:
4159                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4160                                                 genSkipz2(&rFalseIfx,0);
4161                                                 if(ifx) ifx->generated = 1;
4162                                                 break;
4163                                         case 0x7f:
4164                                                 genSkipCond(&rFalseIfx,right,0,7);
4165                                                 if(ifx) ifx->generated = 1;
4166                                                 break;
4167                                                 
4168                                         default:
4169                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4170                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4171                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4172                                                 rFalseIfx.condition ^= 1;
4173                                                 if (AOP_TYPE(result) == AOP_CRY) {
4174                                                         genSkipc(&rFalseIfx);
4175                                                         if(ifx) ifx->generated = 1;
4176                                                 } else {
4177                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4178                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4179                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4180                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4181                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4182                                                 }       
4183                                                 break;
4184                                         }
4185                                 }
4186                                 
4187                                 //goto check_carry;
4188                                 return;
4189                                 
4190                         } else {
4191                                 
4192                                 /* Size is greater than 1 */
4193                                 
4194                                 if(sign) {
4195                                         int lp1 = lit+1;
4196                                         
4197                                         size--;
4198                                         
4199                                         if(lp1 == 0) {
4200                                                 /* this means lit = 0xffffffff, or -1 */
4201                                                 
4202                                                 
4203                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4204                                                 rFalseIfx.condition ^= 1;
4205                                                 genSkipCond(&rFalseIfx,right,size,7);
4206                                                 if(ifx) ifx->generated = 1;
4207                                                 return;
4208                                         }
4209                                         
4210                                         if(lit == 0) {
4211                                                 int s = size;
4212                                                 
4213                                                 if(rFalseIfx.condition) {
4214                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4215                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4216                                                 }
4217                                                 
4218                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4219                                                 while(size--)
4220                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4221                                                 
4222                                                 
4223                                                 emitSKPZ;
4224                                                 if(rFalseIfx.condition) {
4225                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4226                                                         emitpLabel(truelbl->key);
4227                                                 }else {
4228                                                         rFalseIfx.condition ^= 1;
4229                                                         genSkipCond(&rFalseIfx,right,s,7);
4230                                                 }
4231                                                 
4232                                                 if(ifx) ifx->generated = 1;
4233                                                 return;
4234                                         }
4235                                         
4236                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4237                                                 /* lower byte of signed word is zero */
4238                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4239                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4240                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4241                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4242                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4243                                                 rFalseIfx.condition ^= 1;
4244                                                 genSkipc(&rFalseIfx);
4245                                                 
4246                                                 
4247                                                 if(ifx) ifx->generated = 1;
4248                                                 return;
4249                                         }
4250                                         
4251                                         if(lit & (0x80 << (size*8))) {
4252                                                 /* Lit is less than zero */
4253                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4254                                                 //rFalseIfx.condition ^= 1;
4255                                                 //genSkipCond(&rFalseIfx,left,size,7);
4256                                                 //rFalseIfx.condition ^= 1;
4257                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4258                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4259                                                 
4260                                                 if(rFalseIfx.condition)
4261                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4262                                                 else
4263                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4264                                                 
4265                                                 
4266                                         } else {
4267                                                 /* Lit is greater than or equal to zero */
4268                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4269                                                 //rFalseIfx.condition ^= 1;
4270                                                 //genSkipCond(&rFalseIfx,right,size,7);
4271                                                 //rFalseIfx.condition ^= 1;
4272                                                 
4273                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4274                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4275                                                 
4276                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4277                                                 if(rFalseIfx.condition)
4278                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4279                                                 else
4280                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4281                                                 
4282                                         }
4283                                         
4284                                         
4285                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4286                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4287                                         
4288                                         while(size--) {
4289                                                 
4290                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4291                                                 emitSKPNZ;
4292                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4293                                         }
4294                                         rFalseIfx.condition ^= 1;
4295                                         //rFalseIfx.condition = 1;
4296                                         genSkipc(&rFalseIfx);
4297                                         
4298                                         emitpLabel(truelbl->key);
4299                                         
4300                                         if(ifx) ifx->generated = 1;
4301                                         return;
4302                                         // end of if (sign)
4303                                 } else {
4304                                         
4305                                         /* compare word or long to an unsigned literal on the right.*/
4306                                         
4307                                         
4308                                         size--;
4309                                         if(lit < 0xff) {
4310                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4311                                                 switch (lit) {
4312                                                 case 0:
4313                                                         break; /* handled above */
4314                                                 /*
4315                                                 case 0xff:
4316                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4317                                                         while(size--)
4318                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4319                                                         genSkipz2(&rFalseIfx,0);
4320                                                         break;
4321                                                 */
4322                                                 default:
4323                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4324                                                         while(--size)
4325                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4326                                                         
4327                                                         emitSKPZ;
4328                                                         if(rFalseIfx.condition)
4329                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4330                                                         else
4331                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4332                                                         
4333                                                         
4334                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4335                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4336                                                         
4337                                                         rFalseIfx.condition ^= 1;
4338                                                         genSkipc(&rFalseIfx);
4339                                                 }
4340                                                 
4341                                                 emitpLabel(truelbl->key);
4342                                                 
4343                                                 if(ifx) ifx->generated = 1;
4344                                                 return;
4345                                         }
4346                                         
4347                                         
4348                                         lit++;
4349                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4350                                         i = (lit >> (size*8)) & 0xff;
4351                                         
4352                                         emitpcode(POC_MOVLW, popGetLit(i));
4353                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4354                                         
4355                                         while(size--) {
4356                                                 i = (lit >> (size*8)) & 0xff;
4357                                                 
4358                                                 if(i) {
4359                                                         emitpcode(POC_MOVLW, popGetLit(i));
4360                                                         emitSKPNZ;
4361                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4362                                                 } else {
4363                                                 /* this byte of the lit is zero, 
4364                                                         *if it's not the last then OR in the variable */
4365                                                         if(size)
4366                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4367                                                 }
4368                                         }
4369                                         
4370                                         
4371                                         emitpLabel(lbl->key);
4372                                         
4373                                         rFalseIfx.condition ^= 1;
4374                                         genSkipc(&rFalseIfx);
4375                                 }
4376                                 
4377                                 if(sign)
4378                                         emitpLabel(truelbl->key);
4379                                 if(ifx) ifx->generated = 1;
4380                                 return;
4381                         }
4382                 }
4383                 /* Compare two variables */
4384                 
4385                 DEBUGpic14_emitcode(";sign","%d",sign);
4386                 
4387                 size--;
4388                 if(sign) {
4389                         /* Sigh. thus sucks... */
4390                         if(size) {
4391                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4392                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4393                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4394                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4395                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4396                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4397                         } else {
4398                                 /* Signed char comparison */
4399                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4400                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4401                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4402                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4403                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4404                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4405                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4406                                 
4407                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4408                                 genSkipc(&rFalseIfx);
4409                                 
4410                                 if(ifx) ifx->generated = 1;
4411                                 return;
4412                         }
4413                         
4414                 } else {
4415                         
4416                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4417                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4418                 }
4419                 
4420                 
4421                 /* The rest of the bytes of a multi-byte compare */
4422                 while (size) {
4423                         
4424                         emitSKPZ;
4425                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4426                         size--;
4427                         
4428                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4429                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4430                         
4431                         
4432                 }
4433                 
4434                 emitpLabel(lbl->key);
4435                 
4436                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4437                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4438                         (AOP_TYPE(result) == AOP_REG)) {
4439                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4440                         emitpcode(POC_RLF, popGet(AOP(result),0));
4441                 } else {
4442                         genSkipc(&rFalseIfx);
4443                 }       
4444                 //genSkipc(&rFalseIfx);
4445                 if(ifx) ifx->generated = 1;
4446                 
4447                 return;
4448                 
4449         }
4450         
4451         // check_carry:
4452         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4453                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4454                 pic14_outBitC(result);
4455         } else {
4456                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4457                 /* if the result is used in the next
4458                 ifx conditional branch then generate
4459                 code a little differently */
4460                 if (ifx )
4461                         genIfxJump (ifx,"c");
4462                 else
4463                         pic14_outBitC(result);
4464                 /* leave the result in acc */
4465         }
4466         
4467 }
4468
4469 /*-----------------------------------------------------------------*/
4470 /* genCmpGt :- greater than comparison                             */
4471 /*-----------------------------------------------------------------*/
4472 static void genCmpGt (iCode *ic, iCode *ifx)
4473 {
4474         operand *left, *right, *result;
4475         sym_link *letype , *retype;
4476         int sign ;
4477         
4478         FENTRY;
4479         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4480         left = IC_LEFT(ic);
4481         right= IC_RIGHT(ic);
4482         result = IC_RESULT(ic);
4483         
4484         letype = getSpec(operandType(left));
4485         retype =getSpec(operandType(right));
4486         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4487         /* assign the amsops */
4488         aopOp (left,ic,FALSE);
4489         aopOp (right,ic,FALSE);
4490         aopOp (result,ic,TRUE);
4491         
4492         genCmp(right, left, result, ifx, sign);
4493         
4494         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4495         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4496         freeAsmop(result,NULL,ic,TRUE); 
4497 }
4498
4499 /*-----------------------------------------------------------------*/
4500 /* genCmpLt - less than comparisons                                */
4501 /*-----------------------------------------------------------------*/
4502 static void genCmpLt (iCode *ic, iCode *ifx)
4503 {
4504         operand *left, *right, *result;
4505         sym_link *letype , *retype;
4506         int sign ;
4507         
4508         FENTRY;
4509         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4510         left = IC_LEFT(ic);
4511         right= IC_RIGHT(ic);
4512         result = IC_RESULT(ic);
4513         
4514         letype = getSpec(operandType(left));
4515         retype =getSpec(operandType(right));
4516         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4517         
4518         /* assign the amsops */
4519         aopOp (left,ic,FALSE);
4520         aopOp (right,ic,FALSE);
4521         aopOp (result,ic,TRUE);
4522         
4523         genCmp(left, right, result, ifx, sign);
4524         
4525         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4526         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4527         freeAsmop(result,NULL,ic,TRUE); 
4528 }
4529
4530 /*-----------------------------------------------------------------*/
4531 /* genc16bit2lit - compare a 16 bit value to a literal             */
4532 /*-----------------------------------------------------------------*/
4533 static void genc16bit2lit(operand *op, int lit, int offset)
4534 {
4535         int i;
4536         
4537         FENTRY;
4538         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4539         if( (lit&0xff) == 0) 
4540                 i=1;
4541         else
4542                 i=0;
4543         
4544         switch( BYTEofLONG(lit,i)) { 
4545         case 0:
4546                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4547                 break;
4548         case 1:
4549                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4550                 break;
4551         case 0xff:
4552                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4553                 break;
4554         default:
4555                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4556                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4557         }
4558         
4559         i ^= 1;
4560         
4561         switch( BYTEofLONG(lit,i)) { 
4562         case 0:
4563                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4564                 break;
4565         case 1:
4566                 emitSKPNZ;
4567                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4568                 break;
4569         case 0xff:
4570                 emitSKPNZ;
4571                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4572                 break;
4573         default:
4574                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4575                 emitSKPNZ;
4576                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4577                 
4578         }
4579         
4580 }
4581
4582 /*-----------------------------------------------------------------*/
4583 /* gencjneshort - compare and jump if not equal                    */
4584 /*-----------------------------------------------------------------*/
4585 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4586 {
4587         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4588         int offset = 0;
4589         int res_offset = 0;  /* the result may be a different size then left or right */
4590         int res_size = AOP_SIZE(result);
4591         resolvedIfx rIfx;
4592         symbol *lbl;
4593         
4594         unsigned long lit = 0L;
4595         FENTRY;
4596         if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
4597           emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
4598           return;
4599         }
4600         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4601         DEBUGpic14_AopType(__LINE__,left,right,result);
4602         if(result)
4603                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4604         resolveIfx(&rIfx,ifx);
4605         lbl =  newiTempLabel(NULL);
4606         
4607         
4608         /* if the left side is a literal or 
4609         if the right is in a pointer register and left 
4610         is not */
4611         if ((AOP_TYPE(left) == AOP_LIT) || 
4612                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4613                 operand *t = right;
4614                 right = left;
4615                 left = t;
4616         }
4617         if(AOP_TYPE(right) == AOP_LIT)
4618                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4619         
4620         /* if the right side is a literal then anything goes */
4621         if (AOP_TYPE(right) == AOP_LIT &&
4622                 AOP_TYPE(left) != AOP_DIR ) {
4623                 switch(size) {
4624                 case 2:
4625                         genc16bit2lit(left, lit, 0);
4626                         emitSKPNZ;
4627                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4628                         break;
4629                 default:
4630                         while (size--) {
4631                                 if(lit & 0xff) {
4632                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4633                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4634                                 } else {
4635                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4636                                 }
4637                                 
4638                                 emitSKPNZ;
4639                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4640                                 offset++;
4641                                 if(res_offset < res_size-1)
4642                                         res_offset++;
4643                                 lit >>= 8;
4644                         }
4645                         break;
4646                 }
4647         }
4648         
4649         /* if the right side is in a register or in direct space or
4650         if the left is a pointer register & right is not */    
4651         else if (AOP_TYPE(right) == AOP_REG ||
4652                 AOP_TYPE(right) == AOP_DIR || 
4653                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4654                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4655                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4656                 int lbl_key = lbl->key;
4657                 
4658                 if(result) {
4659                         if (AOP_TYPE(result) != AOP_CRY)
4660                                 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4661                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4662                 }else {
4663                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4664                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4665                                 __FUNCTION__,__LINE__);
4666                         return;
4667                 }
4668                 
4669                 /*     switch(size) { */
4670                 /*     case 2: */
4671                 /*       genc16bit2lit(left, lit, 0); */
4672                 /*       emitSKPNZ; */
4673                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4674                 /*       break; */
4675                 /*     default: */
4676                 while (size--) {
4677                         int emit_skip=1;
4678                         if((AOP_TYPE(left) == AOP_DIR) && 
4679                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4680                                 
4681                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4682                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4683                                 
4684                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4685                                 
4686                                 switch (lit & 0xff) {
4687                                 case 0:
4688                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4689                                         break;
4690                                 case 1:
4691                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4692                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4693                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4694                                         emit_skip=0;
4695                                         break;
4696                                 case 0xff:
4697                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4698                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4699                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4700                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4701                                         emit_skip=0;
4702                                         break;
4703                                 default:
4704                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4705                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4706                                 }
4707                                 lit >>= 8;
4708                                 
4709                         } else {
4710                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4711                         }
4712                         if(emit_skip) {
4713                                 if(AOP_TYPE(result) == AOP_CRY) {
4714                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4715                                         if(rIfx.condition)
4716                                                 emitSKPNZ;
4717                                         else
4718                                                 emitSKPZ;
4719                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4720                                 } else {
4721                                         /* fix me. probably need to check result size too */
4722                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4723                                         if(rIfx.condition)
4724                                                 emitSKPZ;
4725                                         else
4726                                                 emitSKPNZ;
4727                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4728                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4729                                 }
4730                                 if(ifx)
4731                                         ifx->generated=1;
4732                         }
4733                         emit_skip++;
4734                         offset++;
4735                         if(res_offset < res_size-1)
4736                                 res_offset++;
4737                 }
4738                 /*       break; */
4739                 /*     } */
4740         } else if(AOP_TYPE(right) == AOP_REG &&
4741                 AOP_TYPE(left) != AOP_DIR){
4742                 
4743                 while(size--) {
4744                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4745                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4746                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4747                         if(rIfx.condition)
4748                                 emitSKPNZ;
4749                         else
4750                                 emitSKPZ;
4751                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4752                         offset++;
4753                         if(res_offset < res_size-1)
4754                                 res_offset++;
4755                 }
4756                 
4757         }else{
4758                 /* right is a pointer reg need both a & b */
4759                 while(size--) {
4760                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4761                         if(strcmp(l,"b"))
4762                                 pic14_emitcode("mov","b,%s",l);
4763                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4764                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4765                         offset++;
4766                 }
4767         }
4768         
4769         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4770         if(!rIfx.condition)
4771                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4772         
4773         emitpLabel(lbl->key);
4774         
4775         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4776         
4777         if(ifx)
4778                 ifx->generated = 1;
4779 }
4780
4781 #if 0
4782 /*-----------------------------------------------------------------*/
4783 /* gencjne - compare and jump if not equal                         */
4784 /*-----------------------------------------------------------------*/
4785 static void gencjne(operand *left, operand *right, iCode *ifx)
4786 {
4787         symbol *tlbl  = newiTempLabel(NULL);
4788         
4789         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4790         gencjneshort(left, right, lbl);
4791         
4792         pic14_emitcode("mov","a,%s",one);
4793         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4794         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4795         pic14_emitcode("clr","a");
4796         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4797         
4798         emitpLabel(lbl->key);
4799         emitpLabel(tlbl->key);
4800         
4801 }
4802 #endif
4803
4804 /*-----------------------------------------------------------------*/
4805 /* genCmpEq - generates code for equal to                          */
4806 /*-----------------------------------------------------------------*/
4807 static void genCmpEq (iCode *ic, iCode *ifx)
4808 {
4809         operand *left, *right, *result;
4810         unsigned long lit = 0L;
4811         int size,offset=0;
4812         
4813         FENTRY;
4814         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4815         
4816         if(ifx)
4817                 DEBUGpic14_emitcode ("; ifx is non-null","");
4818         else
4819                 DEBUGpic14_emitcode ("; ifx is null","");
4820         
4821         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4822         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4823         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4824         
4825         size = max(AOP_SIZE(left),AOP_SIZE(right));
4826         
4827         DEBUGpic14_AopType(__LINE__,left,right,result);
4828         
4829         /* if literal, literal on the right or 
4830         if the right is in a pointer register and left 
4831         is not */
4832         if (aop_isLitLike (AOP(IC_LEFT(ic)))
4833                         || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4834                 operand *tmp = right ;
4835                 right = left;
4836                 left = tmp;
4837         }
4838         
4839         
4840         if(ifx && !AOP_SIZE(result)){
4841                 symbol *tlbl;
4842                 /* if they are both bit variables */
4843                 if (AOP_TYPE(left) == AOP_CRY &&
4844                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4845                         if(AOP_TYPE(right) == AOP_LIT){
4846                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4847                                 if(lit == 0L){
4848                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4849                                         pic14_emitcode("cpl","c");
4850                                 } else if(lit == 1L) {
4851                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4852                                 } else {
4853                                         pic14_emitcode("clr","c");
4854                                 }
4855                                 /* AOP_TYPE(right) == AOP_CRY */
4856                         } else {
4857                                 symbol *lbl = newiTempLabel(NULL);
4858                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4859                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4860                                 pic14_emitcode("cpl","c");
4861                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4862                         }
4863                         /* if true label then we jump if condition
4864                         supplied is true */
4865                         tlbl = newiTempLabel(NULL);
4866                         if ( IC_TRUE(ifx) ) {
4867                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4868                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4869                         } else {
4870                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4871                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4872                         }
4873                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4874                         
4875                         {
4876                                 /* left and right are both bit variables, result is carry */
4877                                 resolvedIfx rIfx;
4878                                 
4879                                 resolveIfx(&rIfx,ifx);
4880                                 
4881                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4882                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4883                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4884                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4885                                 genSkipz2(&rIfx,0);
4886                         }
4887                 } else {
4888                         
4889                         /* They're not both bit variables. Is the right a literal? */
4890                         if(AOP_TYPE(right) == AOP_LIT) {
4891                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4892                                 
4893                                 switch(size) {
4894                                         
4895                                 case 1:
4896                                         switch(lit & 0xff) {
4897                                         case 1:
4898                                                 if ( IC_TRUE(ifx) ) {
4899                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4900                                                         emitSKPNZ;
4901                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4902                                                 } else {
4903                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4904                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4905                                                 }
4906                                                 break;
4907                                         case 0xff:
4908                                                 if ( IC_TRUE(ifx) ) {
4909                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4910                                                         emitSKPNZ;
4911                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4912                                                 } else {
4913                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4914                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4915                                                 }
4916                                                 break;
4917                                         default:
4918                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4919                                                 if(lit)
4920                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4921                                                 genSkip(ifx,'z');
4922                                         }
4923                                         
4924                                         
4925                                         /* end of size == 1 */
4926                                         break;
4927                                         
4928                                         case 2:
4929                                                 genc16bit2lit(left,lit,offset);
4930                                                 genSkip(ifx,'z');
4931                                                 break;
4932                                                 /* end of size == 2 */
4933                                                 
4934                                         default:
4935                                                 /* size is 4 */
4936                                                 if(lit==0) {
4937                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4938                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4939                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4940                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4941                                                         
4942                                                 } else {
4943                                                         
4944                                                         /* search for patterns that can be optimized */
4945                                                         
4946                                                         genc16bit2lit(left,lit,0);
4947                                                         lit >>= 16;
4948                                                         if(lit) {
4949                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4950                                                                 //genSkip(ifx,'z');
4951                                                                 genc16bit2lit(left,lit,2);
4952                                                         } else {
4953                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4954                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4955                                                                 
4956                                                         }
4957                                                         
4958                                                 }
4959                                                 
4960                                                 genSkip(ifx,'z');
4961                                 }
4962                                 
4963                                 ifx->generated = 1;
4964                                 goto release ;
4965                                 
4966                                 
4967                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4968                                 /* we know the left is not a bit, but that the right is */
4969                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4970                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4971                                         popGet(AOP(right),offset));
4972                                 emitpcode(POC_XORLW,popGetLit(1));
4973                                 
4974                                 /* if the two are equal, then W will be 0 and the Z bit is set
4975                                 * we could test Z now, or go ahead and check the high order bytes if
4976                                 * the variable we're comparing is larger than a byte. */
4977                                 
4978                                 while(--size)
4979                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4980                                 
4981                                 if ( IC_TRUE(ifx) ) {
4982                                         emitSKPNZ;
4983                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4984                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4985                                 } else {
4986                                         emitSKPZ;
4987                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4988                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4989                                 }
4990                                 
4991                         } else {
4992                                 /* They're both variables that are larger than bits */
4993                                 int s = size;
4994                                 
4995                                 tlbl = newiTempLabel(NULL);
4996                                 
4997                                 while(size--) {
4998                                         mov2w (AOP(right),offset); /* right might be litLike() */
4999                                         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5000                                         
5001                                         if ( IC_TRUE(ifx) ) {
5002                                                 if(size) {
5003                                                         emitSKPZ;
5004                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
5005                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5006                                                 } else {
5007                                                         emitSKPNZ;
5008                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
5009                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5010                                                 }
5011                                         } else {
5012                                                 emitSKPZ;
5013                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
5014                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5015                                         }
5016                                         offset++;
5017                                 }
5018                                 if(s>1 && IC_TRUE(ifx)) {
5019                                         emitpLabel(tlbl->key);
5020                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
5021                                 }
5022                         }
5023                 }
5024                 /* mark the icode as generated */
5025                 ifx->generated = 1;
5026                 goto release ;
5027         }
5028   
5029   /* if they are both bit variables */
5030   if (AOP_TYPE(left) == AOP_CRY &&
5031           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5032           if(AOP_TYPE(right) == AOP_LIT){
5033                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5034                   if(lit == 0L){
5035                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5036                           pic14_emitcode("cpl","c");
5037                   } else if(lit == 1L) {
5038                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5039                   } else {
5040                           pic14_emitcode("clr","c");
5041                   }
5042                   /* AOP_TYPE(right) == AOP_CRY */
5043           } else {
5044                   symbol *lbl = newiTempLabel(NULL);
5045                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5046                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5047                   pic14_emitcode("cpl","c");
5048                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
5049           }
5050           /* c = 1 if egal */
5051           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5052                   pic14_outBitC(result);
5053                   goto release ;
5054           }
5055           if (ifx) {
5056                   genIfxJump (ifx,"c");
5057                   goto release ;
5058           }
5059           /* if the result is used in an arithmetic operation
5060           then put the result in place */
5061           pic14_outBitC(result);
5062   } else {
5063           
5064           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5065           gencjne(left,right,result,ifx);
5066           /*
5067           if(ifx) 
5068           gencjne(left,right,newiTempLabel(NULL));
5069           else {
5070           if(IC_TRUE(ifx)->key)
5071           gencjne(left,right,IC_TRUE(ifx)->key);
5072           else
5073           gencjne(left,right,IC_FALSE(ifx)->key);
5074           ifx->generated = 1;
5075           goto release ;
5076           }
5077           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5078           aopPut(AOP(result),"a",0);
5079           goto release ;
5080           }
5081           
5082                 if (ifx) {
5083                 genIfxJump (ifx,"a");
5084                 goto release ;
5085                 }
5086           */
5087           /* if the result is used in an arithmetic operation
5088           then put the result in place */
5089           /*
5090           if (AOP_TYPE(result) != AOP_CRY) 
5091           pic14_outAcc(result);
5092           */
5093           /* leave the result in acc */
5094   }
5095   
5096 release:
5097   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5098   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5099   freeAsmop(result,NULL,ic,TRUE);
5100 }
5101
5102 /*-----------------------------------------------------------------*/
5103 /* ifxForOp - returns the icode containing the ifx for operand     */
5104 /*-----------------------------------------------------------------*/
5105 static iCode *ifxForOp ( operand *op, iCode *ic )
5106 {
5107         FENTRY;
5108         /* if true symbol then needs to be assigned */
5109         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5110         if (IS_TRUE_SYMOP(op))
5111                 return NULL ;
5112         
5113         /* if this has register type condition and
5114         the next instruction is ifx with the same operand
5115         and live to of the operand is upto the ifx only then */
5116         if (ic->next &&
5117                 ic->next->op == IFX &&
5118                 IC_COND(ic->next)->key == op->key &&
5119                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5120                 return ic->next;
5121         
5122         if (ic->next &&
5123                 ic->next->op == IFX &&
5124                 IC_COND(ic->next)->key == op->key) {
5125                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5126                 return ic->next;
5127         }
5128         
5129         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5130         if (ic->next &&
5131                 ic->next->op == IFX)
5132                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5133         
5134         if (ic->next &&
5135                 ic->next->op == IFX &&
5136                 IC_COND(ic->next)->key == op->key) {
5137                 DEBUGpic14_emitcode ("; "," key is okay");
5138                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5139                         OP_SYMBOL(op)->liveTo,
5140                         ic->next->seq);
5141         }
5142         
5143         
5144         return NULL;
5145 }
5146 /*-----------------------------------------------------------------*/
5147 /* genAndOp - for && operation                                     */
5148 /*-----------------------------------------------------------------*/
5149 static void genAndOp (iCode *ic)
5150 {
5151         operand *left,*right, *result;
5152         /*     symbol *tlbl; */
5153         
5154         FENTRY;
5155         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5156         /* note here that && operations that are in an
5157         if statement are taken away by backPatchLabels
5158         only those used in arthmetic operations remain */
5159         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5160         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5161         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5162         
5163         DEBUGpic14_AopType(__LINE__,left,right,result);
5164         
5165         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5166         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5167         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5168         
5169         /* if both are bit variables */
5170         /*     if (AOP_TYPE(left) == AOP_CRY && */
5171         /*         AOP_TYPE(right) == AOP_CRY ) { */
5172         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5173         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5174         /*         pic14_outBitC(result); */
5175         /*     } else { */
5176         /*         tlbl = newiTempLabel(NULL); */
5177         /*         pic14_toBoolean(left);     */
5178         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5179         /*         pic14_toBoolean(right); */
5180         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5181         /*         pic14_outBitAcc(result); */
5182         /*     } */
5183         
5184         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5185         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5186         freeAsmop(result,NULL,ic,TRUE);
5187 }
5188
5189
5190 /*-----------------------------------------------------------------*/
5191 /* genOrOp - for || operation                                      */
5192 /*-----------------------------------------------------------------*/
5193 /*
5194 tsd pic port -
5195 modified this code, but it doesn't appear to ever get called
5196 */
5197
5198 static void genOrOp (iCode *ic)
5199 {
5200         operand *left,*right, *result;
5201         symbol *tlbl;
5202         
5203         /* note here that || operations that are in an
5204         if statement are taken away by backPatchLabels
5205         only those used in arthmetic operations remain */
5206         FENTRY;
5207         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5208         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5209         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5210         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5211         
5212         DEBUGpic14_AopType(__LINE__,left,right,result);
5213         
5214         /* if both are bit variables */
5215         if (AOP_TYPE(left) == AOP_CRY &&
5216                 AOP_TYPE(right) == AOP_CRY ) {
5217                 pic14_emitcode("clrc","");
5218                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5219                         AOP(left)->aopu.aop_dir,
5220                         AOP(left)->aopu.aop_dir);
5221                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5222                         AOP(right)->aopu.aop_dir,
5223                         AOP(right)->aopu.aop_dir);
5224                 pic14_emitcode("setc","");
5225                 
5226         } else {
5227                 tlbl = newiTempLabel(NULL);
5228                 pic14_toBoolean(left);
5229                 emitSKPZ;
5230                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5231                 pic14_toBoolean(right);
5232                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5233                 
5234                 pic14_outBitAcc(result);
5235         }
5236         
5237         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5238         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5239         freeAsmop(result,NULL,ic,TRUE);            
5240 }
5241
5242 /*-----------------------------------------------------------------*/
5243 /* isLiteralBit - test if lit == 2^n                               */
5244 /*-----------------------------------------------------------------*/
5245 static int isLiteralBit(unsigned long lit)
5246 {
5247         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5248                 0x100L,0x200L,0x400L,0x800L,
5249                 0x1000L,0x2000L,0x4000L,0x8000L,
5250                 0x10000L,0x20000L,0x40000L,0x80000L,
5251                 0x100000L,0x200000L,0x400000L,0x800000L,
5252                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5253                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5254         int idx;
5255         
5256         FENTRY;
5257         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5258         for(idx = 0; idx < 32; idx++)
5259                 if(lit == pw[idx])
5260                         return idx+1;
5261                 return 0;
5262 }
5263
5264 /*-----------------------------------------------------------------*/
5265 /* continueIfTrue -                                                */
5266 /*-----------------------------------------------------------------*/
5267 static void continueIfTrue (iCode *ic)
5268 {
5269         FENTRY;
5270         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5271         if(IC_TRUE(ic))
5272                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5273         ic->generated = 1;
5274 }
5275
5276 /*-----------------------------------------------------------------*/
5277 /* jmpIfTrue -                                                     */
5278 /*-----------------------------------------------------------------*/
5279 static void jumpIfTrue (iCode *ic)
5280 {
5281         FENTRY;
5282         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5283         if(!IC_TRUE(ic))
5284                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5285         ic->generated = 1;
5286 }
5287
5288 /*-----------------------------------------------------------------*/
5289 /* jmpTrueOrFalse -                                                */
5290 /*-----------------------------------------------------------------*/
5291 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5292 {
5293         FENTRY;
5294         // ugly but optimized by peephole
5295         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5296         if(IC_TRUE(ic)){
5297                 symbol *nlbl = newiTempLabel(NULL);
5298                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5299                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5300                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5301                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5302         }
5303         else{
5304                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5305                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5306         }
5307         ic->generated = 1;
5308 }
5309
5310 /*-----------------------------------------------------------------*/
5311 /* genAnd  - code for and                                          */
5312 /*-----------------------------------------------------------------*/
5313 static void genAnd (iCode *ic, iCode *ifx)
5314 {
5315         operand *left, *right, *result;
5316         int size, offset=0;  
5317         unsigned long lit = 0L;
5318         int bytelit = 0;
5319         resolvedIfx rIfx;
5320         
5321         FENTRY;
5322         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5323         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5324         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5325         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5326         
5327         resolveIfx(&rIfx,ifx);
5328         
5329         /* if left is a literal & right is not then exchange them */
5330         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5331                 AOP_NEEDSACC(left)) {
5332                 operand *tmp = right ;
5333                 right = left;
5334                 left = tmp;
5335         }
5336         
5337         /* if result = right then exchange them */
5338         if(pic14_sameRegs(AOP(result),AOP(right))){
5339                 operand *tmp = right ;
5340                 right = left;
5341                 left = tmp;
5342         }
5343         
5344         /* if right is bit then exchange them */
5345         if (AOP_TYPE(right) == AOP_CRY &&
5346                 AOP_TYPE(left) != AOP_CRY){
5347                 operand *tmp = right ;
5348                 right = left;
5349                 left = tmp;
5350         }
5351         if(AOP_TYPE(right) == AOP_LIT)
5352                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5353         
5354         size = AOP_SIZE(result);
5355         
5356         DEBUGpic14_AopType(__LINE__,left,right,result);
5357         
5358         // if(bit & yy)
5359         // result = bit & yy;
5360         if (AOP_TYPE(left) == AOP_CRY){
5361                 // c = bit & literal;
5362                 if(AOP_TYPE(right) == AOP_LIT){
5363                         if(lit & 1) {
5364                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5365                                         // no change
5366                                         goto release;
5367                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5368                         } else {
5369                                 // bit(result) = 0;
5370                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5371                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5372                                         goto release;
5373                                 }
5374                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5375                                         jumpIfTrue(ifx);
5376                                         goto release;
5377                                 }
5378                                 pic14_emitcode("clr","c");
5379                         }
5380                 } else {
5381                         if (AOP_TYPE(right) == AOP_CRY){
5382                                 // c = bit & bit;
5383                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5384                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5385                         } else {
5386                                 // c = bit & val;
5387                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5388                                 // c = lsb
5389                                 pic14_emitcode("rrc","a");
5390                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5391                         }
5392                 }
5393                 // bit = c
5394                 // val = c
5395                 if(size)
5396                         pic14_outBitC(result);
5397                 // if(bit & ...)
5398                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5399                         genIfxJump(ifx, "c");           
5400                 goto release ;
5401         }
5402         
5403         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5404         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5405         if((AOP_TYPE(right) == AOP_LIT) &&
5406                 (AOP_TYPE(result) == AOP_CRY) &&
5407                 (AOP_TYPE(left) != AOP_CRY)){
5408                 int posbit = isLiteralBit(lit);
5409                 /* left &  2^n */
5410                 if(posbit){
5411                         posbit--;
5412                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5413                         // bit = left & 2^n
5414                         if(size)
5415                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5416                         // if(left &  2^n)
5417                         else{
5418                                 if(ifx){
5419                                         int offset = 0;
5420                                         while (posbit > 7) {
5421                                                 posbit -= 8;
5422                                                 offset++;
5423                                         }
5424                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5425                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5426                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5427                                         
5428                                         ifx->generated = 1;
5429                                 }
5430                                 goto release;
5431                         }
5432                 } else {
5433                         symbol *tlbl = newiTempLabel(NULL);
5434                         int sizel = AOP_SIZE(left);
5435                         if(size)
5436                                 pic14_emitcode("setb","c");
5437                         while(sizel--){
5438                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5439                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5440                                         // byte ==  2^n ?
5441                                         if((posbit = isLiteralBit(bytelit)) != 0)
5442                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5443                                         else{
5444                                                 if(bytelit != 0x0FFL)
5445                                                         pic14_emitcode("anl","a,%s",
5446                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5447                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5448                                         }
5449                                 }
5450                                 offset++;
5451                         }
5452                         // bit = left & literal
5453                         if(size){
5454                                 pic14_emitcode("clr","c");
5455                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5456                         }
5457                         // if(left & literal)
5458                         else{
5459                                 if(ifx)
5460                                         jmpTrueOrFalse(ifx, tlbl);
5461                                 goto release ;
5462                         }
5463                 }
5464                 pic14_outBitC(result);
5465                 goto release ;
5466         }
5467         
5468         /* if left is same as result */
5469         if(pic14_sameRegs(AOP(result),AOP(left))){
5470                 int know_W = -1;
5471                 for(;size--; offset++,lit>>=8) {
5472                         if(AOP_TYPE(right) == AOP_LIT){
5473                                 switch(lit & 0xff) {
5474                                 case 0x00:
5475                                         /*  and'ing with 0 has clears the result */
5476                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5477                                         break;
5478                                 case 0xff:
5479                                         /* and'ing with 0xff is a nop when the result and left are the same */
5480                                         break;
5481                                         
5482                                 default:
5483                                         {
5484                                                 int p = my_powof2( (~lit) & 0xff );
5485                                                 if(p>=0) {
5486                                                         /* only one bit is set in the literal, so use a bcf instruction */
5487                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5488                                                         
5489                                                 } else {
5490                                                         if(know_W != (int)(lit&0xff))
5491                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5492                                                         know_W = lit &0xff;
5493                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5494                                                 }
5495                                         }    
5496                                 }
5497                         } else {
5498                                 if (AOP_TYPE(left) == AOP_ACC) {
5499                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5500                                 } else {        
5501                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5502                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5503                                         
5504                                 }
5505                         }
5506                 }
5507                 
5508         } else {
5509                 // left & result in different registers
5510                 if(AOP_TYPE(result) == AOP_CRY){
5511                         // result = bit
5512                         // if(size), result in bit
5513                         // if(!size && ifx), conditional oper: if(left & right)
5514                         symbol *tlbl = newiTempLabel(NULL);
5515                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5516                         if(size)
5517                                 pic14_emitcode("setb","c");
5518                         while(sizer--){
5519                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5520                                 pic14_emitcode("anl","a,%s",
5521                                         aopGet(AOP(left),offset,FALSE,FALSE));
5522                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5523                                 offset++;
5524                         }
5525                         if(size){
5526                                 CLRC;
5527                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5528                                 pic14_outBitC(result);
5529                         } else if(ifx)
5530                                 jmpTrueOrFalse(ifx, tlbl);
5531                 } else {
5532                         for(;(size--);offset++) {
5533                                 // normal case
5534                                 // result = left & right
5535                                 if(AOP_TYPE(right) == AOP_LIT){
5536                                         int t = (lit >> (offset*8)) & 0x0FFL;
5537                                         switch(t) { 
5538                                         case 0x00:
5539                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5540                                                 break;
5541                                         case 0xff:
5542                                                 if(AOP_TYPE(left) != AOP_ACC) {
5543                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5544                                                 }
5545                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5546                                                 break;
5547                                         default:
5548                                                 if(AOP_TYPE(left) == AOP_ACC) {
5549                                                         emitpcode(POC_ANDLW, popGetLit(t));
5550                                                 } else {
5551                                                         emitpcode(POC_MOVLW, popGetLit(t));
5552                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5553                                                 }
5554                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5555                                         }
5556                                         continue;
5557                                 }
5558                                 
5559                                 if (AOP_TYPE(left) == AOP_ACC) {
5560                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5561                                 } else {
5562                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5563                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5564                                 }
5565                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5566                         }
5567                 }
5568         }
5569         
5570 release :
5571         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5572         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5573         freeAsmop(result,NULL,ic,TRUE);     
5574 }
5575
5576 /*-----------------------------------------------------------------*/
5577 /* genOr  - code for or                                            */
5578 /*-----------------------------------------------------------------*/
5579 static void genOr (iCode *ic, iCode *ifx)
5580 {
5581         operand *left, *right, *result;
5582         int size, offset=0;
5583         unsigned long lit = 0L;
5584         
5585         FENTRY;
5586         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5587         
5588         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5589         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5590         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5591         
5592         DEBUGpic14_AopType(__LINE__,left,right,result);
5593         
5594         /* if left is a literal & right is not then exchange them */
5595         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5596                 AOP_NEEDSACC(left)) {
5597                 operand *tmp = right ;
5598                 right = left;
5599                 left = tmp;
5600         }
5601         
5602         /* if result = right then exchange them */
5603         if(pic14_sameRegs(AOP(result),AOP(right))){
5604                 operand *tmp = right ;
5605                 right = left;
5606                 left = tmp;
5607         }
5608         
5609         /* if right is bit then exchange them */
5610         if (AOP_TYPE(right) == AOP_CRY &&
5611                 AOP_TYPE(left) != AOP_CRY){
5612                 operand *tmp = right ;
5613                 right = left;
5614                 left = tmp;
5615         }
5616         
5617         DEBUGpic14_AopType(__LINE__,left,right,result);
5618         
5619         if(AOP_TYPE(right) == AOP_LIT)
5620                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5621         
5622         size = AOP_SIZE(result);
5623         
5624         // if(bit | yy)
5625         // xx = bit | yy;
5626         if (AOP_TYPE(left) == AOP_CRY){
5627                 if(AOP_TYPE(right) == AOP_LIT){
5628                         // c = bit & literal;
5629                         if(lit){
5630                                 // lit != 0 => result = 1
5631                                 if(AOP_TYPE(result) == AOP_CRY){
5632                                         if(size)
5633                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5634                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635                                         //   AOP(result)->aopu.aop_dir,
5636                                         //   AOP(result)->aopu.aop_dir);
5637                                         else if(ifx)
5638                                                 continueIfTrue(ifx);
5639                                         goto release;
5640                                 }
5641                         } else {
5642                                 // lit == 0 => result = left
5643                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5644                                         goto release;
5645                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5646                         }
5647                 } else {
5648                         if (AOP_TYPE(right) == AOP_CRY){
5649                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5650                                         // c = bit | bit;
5651                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5652                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5653                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5654                                         
5655                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5656                                                 AOP(result)->aopu.aop_dir,
5657                                                 AOP(result)->aopu.aop_dir);
5658                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5659                                                 AOP(right)->aopu.aop_dir,
5660                                                 AOP(right)->aopu.aop_dir);
5661                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5662                                                 AOP(result)->aopu.aop_dir,
5663                                                 AOP(result)->aopu.aop_dir);
5664                                 } else {
5665                                         if( AOP_TYPE(result) == AOP_ACC) {
5666                                                 emitpcode(POC_MOVLW, popGetLit(0));
5667                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5668                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5669                                                 emitpcode(POC_MOVLW, popGetLit(1));
5670                                                 
5671                                         } else {
5672                                                 
5673                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5674                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5675                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5676                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5677                                                 
5678                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5679                                                         AOP(result)->aopu.aop_dir,
5680                                                         AOP(result)->aopu.aop_dir);
5681                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5682                                                         AOP(right)->aopu.aop_dir,
5683                                                         AOP(right)->aopu.aop_dir);
5684                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5685                                                         AOP(left)->aopu.aop_dir,
5686                                                         AOP(left)->aopu.aop_dir);
5687                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5688                                                         AOP(result)->aopu.aop_dir,
5689                                                         AOP(result)->aopu.aop_dir);
5690                                         }
5691                                 }
5692                         } else {
5693                                 // c = bit | val;
5694                                 symbol *tlbl = newiTempLabel(NULL);
5695                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696                                 
5697                                 
5698                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5699                                 if( AOP_TYPE(right) == AOP_ACC) {
5700                                         emitpcode(POC_IORLW, popGetLit(0));
5701                                         emitSKPNZ;
5702                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5703                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5704                                 }
5705                                 
5706                                 
5707                                 
5708                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5709                                         pic14_emitcode(";XXX setb","c");
5710                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5711                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5712                                 pic14_toBoolean(right);
5713                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5714                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5715                                         jmpTrueOrFalse(ifx, tlbl);
5716                                         goto release;
5717                                 } else {
5718                                         CLRC;
5719                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5720                                 }
5721                         }
5722                 }
5723                 // bit = c
5724                 // val = c
5725                 if(size)
5726                         pic14_outBitC(result);
5727                 // if(bit | ...)
5728                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5729                         genIfxJump(ifx, "c");           
5730                 goto release ;
5731         }
5732
5733         // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5734         // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5735         if((AOP_TYPE(right) == AOP_LIT) &&
5736           (AOP_TYPE(result) == AOP_CRY) &&
5737           (AOP_TYPE(left) != AOP_CRY)){
5738                 if(lit){
5739                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5740                         // result = 1
5741                         if(size)
5742                                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5743                         else 
5744                                 continueIfTrue(ifx);
5745                         goto release;
5746                 } else {
5747                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5748                         // lit = 0, result = boolean(left)
5749                         if(size)
5750                                 pic14_emitcode(";XXX setb","c");
5751                         pic14_toBoolean(right);
5752                         if(size){
5753                                 symbol *tlbl = newiTempLabel(NULL);
5754                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5755                                 CLRC;
5756                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5757                         } else {
5758                                 genIfxJump (ifx,"a");
5759                                 goto release;
5760                         }
5761                 }
5762                 pic14_outBitC(result);
5763                 goto release ;
5764         }
5765
5766         /* if left is same as result */
5767         if(pic14_sameRegs(AOP(result),AOP(left))){
5768                 int know_W = -1;
5769                 for(;size--; offset++,lit>>=8) {
5770                         if(AOP_TYPE(right) == AOP_LIT){
5771                                 if((lit & 0xff) == 0)
5772                                         /*  or'ing with 0 has no effect */
5773                                         continue;
5774                                 else {
5775                                         int p = my_powof2(lit & 0xff);
5776                                         if(p>=0) {
5777                                                 /* only one bit is set in the literal, so use a bsf instruction */
5778                                                 emitpcode(POC_BSF,
5779                                                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5780                                         } else {
5781                                                 if(know_W != (int)(lit & 0xff))
5782                                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5783                                                 know_W = lit & 0xff;
5784                                                 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5785                                         }
5786                                         
5787                                 }
5788                         } else {
5789                                 if (AOP_TYPE(left) == AOP_ACC) {
5790                                         emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5791                                         pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5792                                 } else {        
5793                                         emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5794                                         emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5795                                         
5796                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5797                                         pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5798                                         
5799                                 }
5800                         }
5801                 }
5802         } else {
5803                 // left & result in different registers
5804                 if(AOP_TYPE(result) == AOP_CRY){
5805                         // result = bit
5806                         // if(size), result in bit
5807                         // if(!size && ifx), conditional oper: if(left | right)
5808                         symbol *tlbl = newiTempLabel(NULL);
5809                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5810                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5811                         
5812                         
5813                         if(size)
5814                                 pic14_emitcode(";XXX setb","c");
5815                         while(sizer--){
5816                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5817                                 pic14_emitcode(";XXX orl","a,%s",
5818                                         aopGet(AOP(left),offset,FALSE,FALSE));
5819                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5820                                 offset++;
5821                         }
5822                         if(size){
5823                                 CLRC;
5824                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5825                                 pic14_outBitC(result);
5826                         } else if(ifx)
5827                                 jmpTrueOrFalse(ifx, tlbl);
5828                 } else for(;(size--);offset++){
5829                         // normal case
5830                         // result = left | right
5831                         if(AOP_TYPE(right) == AOP_LIT){
5832                                 int t = (lit >> (offset*8)) & 0x0FFL;
5833                                 switch(t) { 
5834                                 case 0x00:
5835                                         if (AOP_TYPE(left) != AOP_ACC) {
5836                                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5837                                         }
5838                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5839                                         
5840                                         break;
5841                                 default:
5842                                         if (AOP_TYPE(left) == AOP_ACC) {
5843                                                 emitpcode(POC_IORLW,  popGetLit(t));
5844                                         } else {
5845                                                 emitpcode(POC_MOVLW,  popGetLit(t));
5846                                                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5847                                         }
5848                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5849                                 }
5850                                 continue;
5851                         }
5852                         
5853                         // faster than result <- left, anl result,right
5854                         // and better if result is SFR
5855                         if (AOP_TYPE(left) == AOP_ACC) {
5856                                 emitpcode(POC_IORFW,popGet(AOP(right),offset));
5857                         } else {
5858                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5859                                 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5860                         }
5861                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5862                 }
5863         }
5864
5865 release :
5866         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5867         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5868         freeAsmop(result,NULL,ic,TRUE);     
5869 }
5870
5871 /*-----------------------------------------------------------------*/
5872 /* genXor - code for xclusive or                                   */
5873 /*-----------------------------------------------------------------*/
5874 static void genXor (iCode *ic, iCode *ifx)
5875 {
5876         operand *left, *right, *result;
5877         int size, offset=0;
5878         unsigned long lit = 0L;
5879         
5880         FENTRY;
5881         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5882         
5883         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5884         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5885         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5886         
5887         /* if left is a literal & right is not ||
5888         if left needs acc & right does not */
5889         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5890                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5891                 operand *tmp = right ;
5892                 right = left;
5893                 left = tmp;
5894         }
5895         
5896         /* if result = right then exchange them */
5897         if(pic14_sameRegs(AOP(result),AOP(right))){
5898                 operand *tmp = right ;
5899                 right = left;
5900                 left = tmp;
5901         }
5902         
5903         /* if right is bit then exchange them */
5904         if (AOP_TYPE(right) == AOP_CRY &&
5905                 AOP_TYPE(left) != AOP_CRY){
5906                 operand *tmp = right ;
5907                 right = left;
5908                 left = tmp;
5909         }
5910         if(AOP_TYPE(right) == AOP_LIT)
5911                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5912         
5913         size = AOP_SIZE(result);
5914         
5915         // if(bit ^ yy)
5916         // xx = bit ^ yy;
5917         if (AOP_TYPE(left) == AOP_CRY){
5918                 if(AOP_TYPE(right) == AOP_LIT){
5919                         // c = bit & literal;
5920                         if(lit>>1){
5921                                 // lit>>1  != 0 => result = 1
5922                                 if(AOP_TYPE(result) == AOP_CRY){
5923                                         if(size)
5924                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5925                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5926                                         else if(ifx)
5927                                                 continueIfTrue(ifx);
5928                                         goto release;
5929                                 }
5930                                 pic14_emitcode("setb","c");
5931                         } else{
5932                                 // lit == (0 or 1)
5933                                 if(lit == 0){
5934                                         // lit == 0, result = left
5935                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5936                                                 goto release;
5937                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5938                                 } else{
5939                                         // lit == 1, result = not(left)
5940                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5941                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5942                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5943                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5944                                                 goto release;
5945                                         } else {
5946                                                 assert ( !"incomplete genXor" );
5947                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5948                                                 pic14_emitcode("cpl","c");
5949                                         }
5950                                 }
5951                         }
5952                         
5953                 } else {
5954                         // right != literal
5955                         symbol *tlbl = newiTempLabel(NULL);
5956                         if (AOP_TYPE(right) == AOP_CRY){
5957                                 // c = bit ^ bit;
5958                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5959                         }
5960                         else{
5961                                 int sizer = AOP_SIZE(right);
5962                                 // c = bit ^ val
5963                                 // if val>>1 != 0, result = 1
5964                                 pic14_emitcode("setb","c");
5965                                 while(sizer){
5966                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5967                                         if(sizer == 1)
5968                                                 // test the msb of the lsb
5969                                                 pic14_emitcode("anl","a,#0xfe");
5970                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5971                                         sizer--;
5972                                 }
5973                                 // val = (0,1)
5974                                 pic14_emitcode("rrc","a");
5975                         }
5976                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5977                         pic14_emitcode("cpl","c");
5978                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5979                 }
5980                 // bit = c
5981                 // val = c
5982                 if(size)
5983                         pic14_outBitC(result);
5984                 // if(bit | ...)
5985                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5986                         genIfxJump(ifx, "c");           
5987                 goto release ;
5988         }
5989         
5990         if(pic14_sameRegs(AOP(result),AOP(left))){
5991                 /* if left is same as result */
5992                 for(;size--; offset++) {
5993                         if(AOP_TYPE(right) == AOP_LIT){
5994                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5995                                 if(t == 0x00L)
5996                                         continue;
5997                                 else
5998                                         if (IS_AOP_PREG(left)) {
5999                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6000                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
6001                                                 aopPut(AOP(result),"a",offset);
6002                                         } else {
6003                                                 emitpcode(POC_MOVLW, popGetLit(t));
6004                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
6005                                                 pic14_emitcode("xrl","%s,%s",
6006                                                         aopGet(AOP(left),offset,FALSE,TRUE),
6007                                                         aopGet(AOP(right),offset,FALSE,FALSE));
6008                                         }
6009                         } else {
6010                                 if (AOP_TYPE(left) == AOP_ACC)
6011                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
6012                                 else {
6013                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6014                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
6015                                         /*
6016                                         if (IS_AOP_PREG(left)) {
6017                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
6018                                         aopPut(AOP(result),"a",offset);
6019                                         } else
6020                                         pic14_emitcode("xrl","%s,a",
6021                                         aopGet(AOP(left),offset,FALSE,TRUE));
6022                                         */
6023                                 }
6024                         }
6025                 }
6026         } else {
6027                 // left & result in different registers
6028                 if(AOP_TYPE(result) == AOP_CRY){
6029                         // result = bit
6030                         // if(size), result in bit
6031                         // if(!size && ifx), conditional oper: if(left ^ right)
6032                         symbol *tlbl = newiTempLabel(NULL);
6033                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6034                         if(size)
6035                                 pic14_emitcode("setb","c");
6036                         while(sizer--){
6037                                 if((AOP_TYPE(right) == AOP_LIT) &&
6038                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6039                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
6040                                 } else {
6041                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6042                                         pic14_emitcode("xrl","a,%s",
6043                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6044                                 }
6045                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6046                                 offset++;
6047                         }
6048                         if(size){
6049                                 CLRC;
6050                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6051                                 pic14_outBitC(result);
6052                         } else if(ifx)
6053                                 jmpTrueOrFalse(ifx, tlbl);
6054                 } else for(;(size--);offset++){
6055                         // normal case
6056                         // result = left & right
6057                         if(AOP_TYPE(right) == AOP_LIT){
6058                                 int t = (lit >> (offset*8)) & 0x0FFL;
6059                                 switch(t) { 
6060                                 case 0x00:
6061                                         if (AOP_TYPE(left) != AOP_ACC) {
6062                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6063                                         }
6064                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6065                                         pic14_emitcode("movf","%s,w",
6066                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6067                                         pic14_emitcode("movwf","%s",
6068                                                 aopGet(AOP(result),offset,FALSE,FALSE));
6069                                         break;
6070                                 case 0xff:
6071                                         if (AOP_TYPE(left) == AOP_ACC) {
6072                                                 emitpcode(POC_XORLW, popGetLit(t));
6073                                         } else {
6074                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6075                                         }
6076                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6077                                         break;
6078                                 default:
6079                                         if (AOP_TYPE(left) == AOP_ACC) {
6080                                                 emitpcode(POC_XORLW, popGetLit(t));
6081                                         } else {
6082                                                 emitpcode(POC_MOVLW, popGetLit(t));
6083                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6084                                         }
6085                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6086                                         pic14_emitcode("movlw","0x%x",t);
6087                                         pic14_emitcode("xorwf","%s,w",
6088                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6089                                         pic14_emitcode("movwf","%s",
6090                                                 aopGet(AOP(result),offset,FALSE,FALSE));
6091                                         
6092                                 }
6093                                 continue;
6094                         }
6095                         
6096                         // faster than result <- left, anl result,right
6097                         // and better if result is SFR
6098                         if (AOP_TYPE(left) == AOP_ACC) {
6099                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6100                         } else {
6101                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6102                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6103                         }
6104                         if ( AOP_TYPE(result) != AOP_ACC){
6105                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6106                         }
6107                 }
6108         }
6109         
6110 release :
6111         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6112         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6113         freeAsmop(result,NULL,ic,TRUE);     
6114 }
6115
6116 /*-----------------------------------------------------------------*/
6117 /* genInline - write the inline code out                           */
6118 /*-----------------------------------------------------------------*/
6119 static void genInline (iCode *ic)
6120 {
6121   char *buffer, *bp, *bp1;
6122
6123   FENTRY;
6124   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6125
6126   _G.inLine += (!options.asmpeep);
6127
6128   buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6129   strcpy(buffer,IC_INLINE(ic));
6130
6131   /* emit each line as a code */
6132   while (*bp) {
6133     if (*bp == '\n') {
6134       *bp++ = '\0';
6135       
6136       if(*bp1)
6137         addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6138       bp1 = bp;
6139     } else {
6140       if (*bp == ':') {
6141         bp++;
6142         *bp = '\0';
6143         bp++;
6144
6145         /* print label, use this special format with NULL directive
6146          * to denote that the argument should not be indented with tab */
6147         addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
6148
6149         bp1 = bp;
6150       } else
6151         bp++;
6152     }
6153   }
6154   if ((bp1 != bp) && *bp1)
6155     addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6156
6157   Safe_free(buffer);
6158
6159   _G.inLine -= (!options.asmpeep);
6160 }
6161
6162 /*-----------------------------------------------------------------*/
6163 /* genRRC - rotate right with carry                                */
6164 /*-----------------------------------------------------------------*/
6165 static void genRRC (iCode *ic)
6166 {
6167         operand *left , *result ;
6168         int size, offset = 0, same;
6169         
6170         FENTRY;
6171         /* rotate right with carry */
6172         left = IC_LEFT(ic);
6173         result=IC_RESULT(ic);
6174         aopOp (left,ic,FALSE);
6175         aopOp (result,ic,FALSE);
6176         
6177         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6178         
6179         same = pic14_sameRegs(AOP(result),AOP(left));
6180         
6181         size = AOP_SIZE(result);    
6182         
6183         /* get the lsb and put it into the carry */
6184         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6185         
6186         offset = 0 ;
6187         
6188         while(size--) {
6189                 
6190                 if(same) {
6191                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6192                 } else {
6193                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6194                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6195                 }
6196                 
6197                 offset++;
6198         }
6199         
6200         freeAsmop(left,NULL,ic,TRUE);
6201         freeAsmop(result,NULL,ic,TRUE);
6202 }
6203
6204 /*-----------------------------------------------------------------*/
6205 /* genRLC - generate code for rotate left with carry               */
6206 /*-----------------------------------------------------------------*/
6207 static void genRLC (iCode *ic)
6208 {    
6209         operand *left , *result ;
6210         int size, offset = 0;
6211         int same;
6212         
6213         FENTRY;
6214         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6215         /* rotate right with carry */
6216         left = IC_LEFT(ic);
6217         result=IC_RESULT(ic);
6218         aopOp (left,ic,FALSE);
6219         aopOp (result,ic,FALSE);
6220         
6221         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6222         
6223         same = pic14_sameRegs(AOP(result),AOP(left));
6224         
6225         /* move it to the result */
6226         size = AOP_SIZE(result);    
6227         
6228         /* get the msb and put it into the carry */
6229         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6230         
6231         offset = 0 ;
6232         
6233         while(size--) {
6234                 
6235                 if(same) {
6236                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6237                 } else {
6238                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6239                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6240                 }
6241                 
6242                 offset++;
6243         }
6244         
6245         
6246         freeAsmop(left,NULL,ic,TRUE);
6247         freeAsmop(result,NULL,ic,TRUE);
6248 }
6249
6250 /*-----------------------------------------------------------------*/
6251 /* genGetHbit - generates code get highest order bit               */
6252 /*-----------------------------------------------------------------*/
6253 static void genGetHbit (iCode *ic)
6254 {
6255         operand *left, *result;
6256         left = IC_LEFT(ic);
6257         result=IC_RESULT(ic);
6258         aopOp (left,ic,FALSE);
6259         aopOp (result,ic,FALSE);
6260         
6261         FENTRY;
6262         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6263         /* get the highest order byte into a */
6264         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6265         if(AOP_TYPE(result) == AOP_CRY){
6266                 pic14_emitcode("rlc","a");
6267                 pic14_outBitC(result);
6268         }
6269         else{
6270                 pic14_emitcode("rl","a");
6271                 pic14_emitcode("anl","a,#0x01");
6272                 pic14_outAcc(result);
6273         }
6274         
6275         
6276         freeAsmop(left,NULL,ic,TRUE);
6277         freeAsmop(result,NULL,ic,TRUE);
6278 }
6279
6280 /*-----------------------------------------------------------------*/
6281 /* AccRol - rotate left accumulator by known count                 */
6282 /*-----------------------------------------------------------------*/
6283 static void AccRol (operand *op,int offset,int shCount)
6284 {
6285         FENTRY;
6286         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6287         shCount &= 0x0007;              // shCount : 0..7
6288         switch(shCount){
6289         case 0 :
6290                 break;
6291         case 1 :
6292                 pic14_emitcode("rl","a");
6293                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6294                 break;
6295         case 2 :
6296                 pic14_emitcode("rl","a");
6297                 pic14_emitcode("rl","a");
6298                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6299                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6300                 break;
6301         case 3 :
6302                 pic14_emitcode("swap","a");
6303                 pic14_emitcode("rr","a");
6304                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6305                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6306                 break;
6307         case 4 :
6308                 pic14_emitcode("swap","a");
6309                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6310                 break;
6311         case 5 :
6312                 pic14_emitcode("swap","a");
6313                 pic14_emitcode("rl","a");
6314                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6315                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6316                 break;
6317         case 6 :
6318                 pic14_emitcode("rr","a");
6319                 pic14_emitcode("rr","a");
6320                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6321                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6322                 break;
6323         case 7 :
6324                 pic14_emitcode("rr","a");
6325                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6326                 break;
6327         }
6328 }
6329
6330 /*-----------------------------------------------------------------*/
6331 /* AccLsh - left shift accumulator by known count                  */
6332 /*-----------------------------------------------------------------*/
6333 static void AccLsh (operand *op,int offset,int shCount)
6334 {
6335         FENTRY;
6336         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6337         if(shCount != 0) {
6338                 if (shCount == 1)
6339                 {
6340                         emitCLRC;
6341                         emitpcode (POC_RLF, popGet (AOP(op), 0));
6342                 } else {
6343                         /* rotate left accumulator */
6344                         AccRol(op,offset,shCount);
6345                         /* and kill the lower order bits */
6346                         emitpcode(POC_MOVLW,popGetLit(SLMask[shCount]));
6347                         emitpcode (POC_ANDWF, popGet (AOP(op),0));
6348                 }
6349         }
6350 }
6351
6352 /*-----------------------------------------------------------------*/
6353 /* AccRsh - right shift accumulator by known count                 */
6354 /*-----------------------------------------------------------------*/
6355 static void AccRsh (operand *op,int offset,int shCount)
6356 {
6357         FENTRY;
6358         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6359         if(shCount != 0){
6360                 if(shCount == 1){
6361                         emitCLRC;
6362                         emitpcode (POC_RRF, popGet (AOP(op), 0));
6363                 } else {
6364                         /* rotate right accumulator */
6365                         AccRol(op,offset,8 - shCount);
6366                         /* and kill the higher order bits */
6367                         emitpcode (POC_MOVLW, popGetLit (SRMask[shCount]));
6368                         emitpcode (POC_ANDWF, popGet (AOP(op),0));
6369                 }
6370         }
6371 }
6372
6373 #if 0
6374 /*-----------------------------------------------------------------*/
6375 /* AccSRsh - signed right shift accumulator by known count                 */
6376 /*-----------------------------------------------------------------*/
6377 static void AccSRsh (int shCount)
6378 {
6379         symbol *tlbl ;
6380         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6381         if(shCount != 0){
6382                 if(shCount == 1){
6383                         pic14_emitcode("mov","c,acc.7");
6384                         pic14_emitcode("rrc","a");
6385                 } else if(shCount == 2){
6386                         pic14_emitcode("mov","c,acc.7");
6387                         pic14_emitcode("rrc","a");
6388                         pic14_emitcode("mov","c,acc.7");
6389                         pic14_emitcode("rrc","a");
6390                 } else {
6391                         tlbl = newiTempLabel(NULL);
6392                         /* rotate right accumulator */
6393                         AccRol(8 - shCount);
6394                         /* and kill the higher order bits */
6395                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6396                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6397                         pic14_emitcode("orl","a,#0x%02x",
6398                                 (unsigned char)~SRMask[shCount]);
6399                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6400                 }
6401         }
6402 }
6403
6404 /*-----------------------------------------------------------------*/
6405 /* shiftR1Left2Result - shift right one byte from left to result   */
6406 /*-----------------------------------------------------------------*/
6407 static void shiftR1Left2ResultSigned (operand *left, int offl,
6408                                                                           operand *result, int offr,
6409                                                                           int shCount)
6410 {
6411         int same;
6412         
6413         FENTRY;
6414         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6415         
6416         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6417         
6418         switch(shCount) {
6419         case 1:
6420                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6421                 if(same) 
6422                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6423                 else {
6424                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6425                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6426                 }
6427                 
6428                 break;
6429         case 2:
6430                 
6431                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6432                 if(same) 
6433                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6434                 else {
6435                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6436                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437                 }
6438                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6439                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6440                 
6441                 break;
6442                 
6443         case 3:
6444                 if(same)
6445                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6446                 else {
6447                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6448                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6449                 }
6450                 
6451                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6452                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6453                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6454                 
6455                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6456                 emitpcode(POC_IORLW, popGetLit(0xe0));
6457                 
6458                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6459                 break;
6460                 
6461         case 4:
6462                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6463                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6464                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6465                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6466                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6467                 break;
6468         case 5:
6469                 if(same) {
6470                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6471                 } else {
6472                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6473                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6474                 }
6475                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6476                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6477                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6478                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6479                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6480                 break;
6481                 
6482         case 6:
6483                 if(same) {
6484                         emitpcode(POC_MOVLW, popGetLit(0x00));
6485                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6486                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6487                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6488                         emitpcode(POC_IORLW, popGetLit(0x01));
6489                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6490                 } else {
6491                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6492                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6493                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6494                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6495                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6496                 }
6497                 break;
6498                 
6499         case 7:
6500                 if(same) {
6501                         emitpcode(POC_MOVLW, popGetLit(0x00));
6502                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6503                         emitpcode(POC_MOVLW, popGetLit(0xff));
6504                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505                 } else {
6506                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6507                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6508                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6509                 }
6510                 
6511         default:
6512                 break;
6513         }
6514 }
6515
6516 /*-----------------------------------------------------------------*/
6517 /* shiftR1Left2Result - shift right one byte from left to result   */
6518 /*-----------------------------------------------------------------*/
6519 static void shiftR1Left2Result (operand *left, int offl,
6520                                                                 operand *result, int offr,
6521                                                                 int shCount, int sign)
6522 {
6523         int same;
6524         
6525         FENTRY;
6526         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6527         
6528         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6529         
6530         /* Copy the msb into the carry if signed. */
6531         if(sign) {
6532                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6533                 return;
6534         }
6535         
6536         
6537         
6538         switch(shCount) {
6539         case 1:
6540                 emitCLRC;
6541                 if(same) 
6542                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6543                 else {
6544                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6545                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6546                 }
6547                 break;
6548         case 2:
6549                 emitCLRC;
6550                 if(same) {
6551                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6552                 } else {
6553                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6554                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6555                 }
6556                 emitCLRC;
6557                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6558                 
6559                 break;
6560         case 3:
6561                 if(same)
6562                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6563                 else {
6564                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6565                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6566                 }
6567                 
6568                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6569                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6570                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6571                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6572                 break;
6573                 
6574         case 4:
6575                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6576                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6577                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6578                 break;
6579                 
6580         case 5:
6581                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6582                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6583                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6584                 emitCLRC;
6585                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6586                 
6587                 break;
6588         case 6:
6589                 
6590                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6591                 emitpcode(POC_ANDLW, popGetLit(0x80));
6592                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6593                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6594                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6595                 break;
6596                 
6597         case 7:
6598                 
6599                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6600                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6601                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6602                 
6603                 break;
6604                 
6605         default:
6606                 break;
6607         }
6608 }
6609
6610 /*-----------------------------------------------------------------*/
6611 /* shiftL1Left2Result - shift left one byte from left to result    */
6612 /*-----------------------------------------------------------------*/
6613 static void shiftL1Left2Result (operand *left, int offl,
6614                                                                 operand *result, int offr, int shCount)
6615 {
6616         int same;
6617         
6618         //    char *l;
6619         FENTRY;
6620         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6621         
6622         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6623         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6624         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6625         //    MOVA(l);
6626         /* shift left accumulator */
6627         //AccLsh(shCount); // don't comment out just yet...
6628         //    aopPut(AOP(result),"a",offr);
6629         
6630         switch(shCount) {
6631         case 1:
6632                 /* Shift left 1 bit position */
6633                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6634                 if(same) {
6635                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6636                 } else {
6637                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6638                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6639                 }
6640                 break;
6641         case 2:
6642                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6643                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6644                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6645                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6646                 break;
6647         case 3:
6648                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6649                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6650                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6651                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6652                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6653                 break;
6654         case 4:
6655                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6656                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6657                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6658                 break;
6659         case 5:
6660                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6661                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6662                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6663                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6664                 break;
6665         case 6:
6666                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6667                 emitpcode(POC_ANDLW, popGetLit(0x30));
6668                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6669                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6670                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6671                 break;
6672         case 7:
6673                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6674                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6675                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6676                 break;
6677                 
6678         default:
6679                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6680         }
6681         
6682 }
6683 #endif
6684
6685 /*-----------------------------------------------------------------*/
6686 /* movLeft2Result - move byte from left to result                  */
6687 /*-----------------------------------------------------------------*/
6688 static void movLeft2Result (operand *left, int offl,
6689                                                         operand *result, int offr)
6690 {
6691         char *l;
6692         FENTRY;
6693         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6694         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6695                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6696                 
6697                 if (*l == '@' && (IS_AOP_PREG(result))) {
6698                         pic14_emitcode("mov","a,%s",l);
6699                         aopPut(AOP(result),"a",offr);
6700                 } else {
6701                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6702                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6703                 }
6704         }
6705 }
6706
6707 /*-----------------------------------------------------------------*/
6708 /* shiftLeft_Left2ResultLit - shift left by known count            */
6709 /*-----------------------------------------------------------------*/
6710
6711 static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
6712 {
6713         int size, same, offr, i;
6714
6715         size = AOP_SIZE(left);
6716         if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
6717         
6718         same = pic14_sameRegs (AOP(left), AOP(result));
6719         
6720         offr = shCount / 8;
6721         shCount = shCount & 0x07;
6722
6723         size -= offr;
6724
6725         switch (shCount)
6726         {
6727         case 0: /* takes 0 or 2N cycles (for offr==0) */
6728                 if (!same || offr) {
6729                         for (i=size-1; i >= 0; i--)
6730                                 movLeft2Result (left, i, result, offr + i);
6731                 } // if
6732                 break;
6733                 
6734         case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
6735                 if (same && offr) {
6736                         shiftLeft_Left2ResultLit (left, result, 8 * offr);
6737                         shiftLeft_Left2ResultLit (result, result, shCount);
6738                         return; /* prevent clearing result again */
6739                 } else {
6740                         emitCLRC;
6741                         for (i=0; i < size; i++) {
6742                                 if (same && !offr) {
6743                                         emitpcode (POC_RLF, popGet (AOP(left), i));
6744                                 } else {
6745                                         emitpcode (POC_RLFW, popGet (AOP(left), i));
6746                                         emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
6747                                 } // if
6748                         } // for
6749                 } // if (offr)
6750                 break;
6751                 
6752         case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
6753                 /* works in-place/with offr as well */
6754                 emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
6755                 emitpcode (POC_ANDLW, popGetLit (0xF0));
6756                 emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
6757
6758                 for (i = size - 2; i >= 0; i--)
6759                 {
6760                         emitpcode (POC_SWAPFW, popGet (AOP(left), i));
6761                         emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
6762                         emitpcode (POC_ANDLW, popGetLit (0x0F));
6763                         emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
6764                         emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
6765                 } // for i
6766                 break;
6767                 
6768         case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
6769                 /* works in-place/with offr as well */
6770                 emitpcode (POC_RRFW, popGet (AOP(left), size-1));
6771                 for (i = size-2; i >= 0; i--) {
6772                         emitpcode (POC_RRFW, popGet (AOP(left), i));
6773                         emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
6774                 } // for i
6775                 emitpcode (POC_CLRF, popGet (AOP(result), offr));
6776                 emitpcode (POC_RRF, popGet (AOP(result), offr));
6777                 break;
6778         
6779         default:
6780                 shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
6781                 shiftLeft_Left2ResultLit (result, result, 1);
6782                 return; /* prevent clearing result again */
6783                 break;
6784         } // switch
6785
6786         while (0 < offr--)
6787         {
6788                 emitpcode (POC_CLRF, popGet (AOP(result), offr));
6789         } // while
6790 }
6791
6792 /*-----------------------------------------------------------------*/
6793 /* shiftRight_Left2ResultLit - shift right by known count          */
6794 /*-----------------------------------------------------------------*/
6795
6796 static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
6797 {
6798         int size, same, offr, i;
6799
6800         size = AOP_SIZE(left);
6801         if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
6802         
6803         same = pic14_sameRegs (AOP(left), AOP(result));
6804         
6805         offr = shCount / 8;
6806         shCount = shCount & 0x07;
6807
6808         size -= offr;
6809
6810         if (size)
6811         {
6812                 switch (shCount)
6813                 {
6814                 case 0: /* takes 0 or 2N cycles (for offr==0) */
6815                         if (!same || offr) {
6816                                 for (i=0; i < size; i++)
6817                                         movLeft2Result (left, i + offr, result, i);
6818                         } // if
6819                         break;
6820                         
6821                 case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
6822                         emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
6823                         if (same && offr) {
6824                                 shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
6825                                 shiftRight_Left2ResultLit (result, result, shCount, sign);
6826                                 return; /* prevent sign-extending result again */
6827                         } else {
6828                                 emitCLRC;
6829                                 if (sign) {
6830                                         emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
6831                                         emitSETC;
6832                                 }
6833                                 for (i = size-1; i >= 0; i--) {
6834                                         if (same && !offr) {
6835                                                 emitpcode (POC_RRF, popGet (AOP(left), i));
6836                                         } else {
6837                                                 emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
6838                                                 emitpcode (POC_MOVWF, popGet (AOP(result), i));
6839                                         }
6840                                 } // for i
6841                         } // if (offr)
6842                         break;
6843                         
6844                 case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
6845                         /* works in-place/with offr as well */
6846                         emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
6847                         emitpcode (POC_ANDLW, popGetLit (0x0F));
6848                         emitpcode (POC_MOVWF, popGet(AOP(result), 0));
6849
6850                         for (i = 1; i < size; i++)
6851                         {
6852                                 emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
6853                                 emitpcode (POC_MOVWF, popGet (AOP(result), i));
6854                                 emitpcode (POC_ANDLW, popGetLit (0xF0));
6855                                 emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
6856                                 emitpcode (POC_XORWF, popGet (AOP(result), i));
6857                         } // for i
6858
6859                         if (sign)
6860                         {
6861                                 emitpcode (POC_MOVLW, popGetLit (0xF0));
6862                                 emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
6863                                 emitpcode (POC_IORWF, popGet (AOP(result), size-1));
6864                         } // if
6865                         break;
6866                         
6867                 case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
6868                         /* works in-place/with offr as well */
6869                         emitpcode (POC_RLFW, popGet (AOP(left), offr));
6870                         for (i = 0; i < size-1; i++) {
6871                                 emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
6872                                 emitpcode (POC_MOVWF, popGet (AOP(result), i));
6873                         } // for i
6874                         emitpcode (POC_CLRF, popGet (AOP(result), size-1));
6875                         if (!sign) {
6876                                 emitpcode (POC_RLF, popGet (AOP(result), size-1));
6877                         } else {
6878                                 emitSKPNC;
6879                                 emitpcode (POC_DECF, popGet (AOP(result), size-1));
6880                         }
6881                         break;
6882                 
6883                 default:
6884                         shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
6885                         shiftRight_Left2ResultLit (result, result, 1, sign);
6886                         return; /* prevent sign extending result again */
6887                         break;
6888                 } // switch
6889         } // if
6890
6891         addSign (result, size, sign);
6892 }
6893
6894 #if 0
6895 /*-----------------------------------------------------------------*/
6896 /* shiftL2Left2Result - shift left two bytes from left to result   */
6897 /*-----------------------------------------------------------------*/
6898 static void shiftL2Left2Result (operand *left, int offl,
6899                                                                 operand *result, int offr, int shCount)
6900 {
6901         FENTRY;
6902         
6903         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6904         
6905         if(pic14_sameRegs(AOP(result), AOP(left))) {
6906                 switch(shCount) {
6907                 case 0:
6908                         break;
6909                 case 1:
6910                 case 2:
6911                 case 3:
6912                         
6913                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6914                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6915                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6916                         
6917                         while(--shCount) {
6918                                 emitCLRC;
6919                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6920                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6921                         }
6922                         
6923                         break;
6924                 case 4:
6925                 case 5:
6926                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6927                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6928                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6929                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6930                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6931                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6932                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6933                         if(shCount >=5) {
6934                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6935                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6936                         }
6937                         break;
6938                 case 6:
6939                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6940                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6941                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6942                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6943                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6944                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6945                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6946                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6947                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6948                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6949                         break;
6950                 case 7:
6951                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6952                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6953                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6954                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6955                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6956                 }
6957                 
6958         } else {
6959                 switch(shCount) {
6960                 case 0:
6961                         break;
6962                 case 1:
6963                 case 2:
6964                 case 3:
6965                 /* note, use a mov/add for the shift since the mov has a
6966                         chance of getting optimized out */
6967                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6968                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6969                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6970                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6971                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6972                         
6973                         while(--shCount) {
6974                                 emitCLRC;
6975                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6976                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6977                         }
6978                         break;
6979                         
6980                 case 4:
6981                 case 5:
6982                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6983                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6984                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6985                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6986                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6987                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6988                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6989                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6990                         
6991                         
6992                         if(shCount == 5) {
6993                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6994                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6995                         }
6996                         break;
6997                 case 6:
6998                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6999                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7000                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
7001                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
7002                         
7003                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
7004                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
7005                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
7006                         emitpcode(POC_ANDLW,popGetLit(0xc0));
7007                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
7008                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
7009                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
7010                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7011                         break;
7012                 case 7:
7013                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
7014                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
7015                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7016                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
7017                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
7018                 }
7019         }
7020         
7021 }
7022
7023 /*-----------------------------------------------------------------*/
7024 /* shiftR2Left2Result - shift right two bytes from left to result  */
7025 /*-----------------------------------------------------------------*/
7026 static void shiftR2Left2Result (operand *left, int offl,
7027                                                                 operand *result, int offr,
7028                                                                 int shCount, int sign)
7029 {
7030         int same=0;
7031         
7032         FENTRY;
7033         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7034         same = pic14_sameRegs(AOP(result), AOP(left));
7035         
7036         if(same && ((offl + MSB16) == offr)){
7037                 same=1;
7038                 /* don't crash result[offr] */
7039                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
7040                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7041         }
7042         /* else {
7043         movLeft2Result(left,offl, result, offr);
7044         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7045         }
7046         */
7047         /* a:x >> shCount (x = lsb(result))*/
7048         /*
7049         if(sign)
7050         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7051         else {
7052         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7053         */
7054         switch(shCount) {
7055         case 0:
7056                 break;
7057         case 1:
7058         case 2:
7059         case 3:
7060                 if(sign)
7061                         emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
7062                 else
7063                         emitCLRC;
7064                 
7065                 if(same) {
7066                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
7067                         emitpcode(POC_RRF,popGet(AOP(result),offr));
7068                 } else {
7069                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
7070                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7071                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
7072                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
7073                 }
7074                 
7075                 while(--shCount) {
7076                         if(sign)
7077                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
7078                         else
7079                                 emitCLRC;
7080                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
7081                         emitpcode(POC_RRF,popGet(AOP(result),offr));
7082                 }
7083                 break;
7084         case 4:
7085         case 5:
7086                 if(same) {
7087                         
7088                         emitpcode(POC_MOVLW, popGetLit(0xf0));
7089                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
7090                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
7091                         
7092                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
7093                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
7094                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
7095                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
7096                 } else {
7097                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
7098                         emitpcode(POC_ANDLW, popGetLit(0x0f));
7099                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
7100                         
7101                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
7102                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
7103                         emitpcode(POC_ANDLW, popGetLit(0xf0));
7104                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
7105                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
7106                 }
7107                 
7108                 if(shCount >=5) {
7109                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
7110                         emitpcode(POC_RRF, popGet(AOP(result),offr));
7111                 }
7112                 
7113                 if(sign) {
7114                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
7115                         emitpcode(POC_BTFSC, 
7116                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7117                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
7118                 }
7119                 
7120                 break;
7121                 
7122         case 6:
7123                 if(same) {
7124                         
7125                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
7126                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
7127                         
7128                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
7129                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
7130                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
7131                         emitpcode(POC_ANDLW,popGetLit(0x03));
7132                         if(sign) {
7133                                 emitpcode(POC_BTFSC, 
7134                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7135                                 emitpcode(POC_IORLW,popGetLit(0xfc));
7136                         }
7137                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
7138                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
7139                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
7140                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
7141                 } else {
7142                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
7143                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7144                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
7145                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
7146                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
7147                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
7148                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
7149                         emitpcode(POC_ANDLW,popGetLit(0x03));
7150                         if(sign) {
7151                                 emitpcode(POC_BTFSC, 
7152                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7153                                 emitpcode(POC_IORLW,popGetLit(0xfc));
7154                         }
7155                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
7156                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
7157                         
7158                         
7159                 }
7160                 
7161                 break;
7162         case 7:
7163                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
7164                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
7165                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
7166                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
7167                 if(sign) {
7168                         emitSKPNC;
7169                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
7170                 } else 
7171                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
7172   }
7173 }
7174
7175 /*-----------------------------------------------------------------*/
7176 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7177 /*-----------------------------------------------------------------*/
7178 static void shiftLLeftOrResult (operand *left, int offl,
7179                                                                 operand *result, int offr, int shCount)
7180 {
7181         FENTRY;
7182         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7183         
7184         /* shift left accumulator */
7185         AccLsh(left,offl,shCount);
7186         /* or with result */
7187         emitpcode (POC_IORWF, popGet (AOP(result), offr));
7188         assert ( !"broken (modifies left, fails for left==result))" );
7189 }
7190
7191 /*-----------------------------------------------------------------*/
7192 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7193 /*-----------------------------------------------------------------*/
7194 static void shiftRLeftOrResult (operand *left, int offl,
7195                                                                 operand *result, int offr, int shCount)
7196 {
7197         FENTRY;
7198         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7199         
7200         /* shift right accumulator */
7201         AccRsh(left,offl,shCount);
7202         /* or with result */
7203         emitpcode (POC_IORWF, popGet (AOP(result), offr));
7204         assert ( !"broken (modifies left, fails for left==result))" );
7205 }
7206
7207 /*-----------------------------------------------------------------*/
7208 /* genlshOne - left shift a one byte quantity by known count       */
7209 /*-----------------------------------------------------------------*/
7210 static void genlshOne (operand *result, operand *left, int shCount)
7211 {       
7212         FENTRY;
7213         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7214         shiftL1Left2Result(left, LSB, result, LSB, shCount);
7215 }
7216
7217 /*-----------------------------------------------------------------*/
7218 /* genlshTwo - left shift two bytes by known amount != 0           */
7219 /*-----------------------------------------------------------------*/
7220 static void genlshTwo (operand *result,operand *left, int shCount)
7221 {
7222         int size;
7223         
7224         FENTRY;
7225         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7226         size = pic14_getDataSize(result);
7227         
7228         /* if shCount >= 8 */
7229         if (shCount >= 8) {
7230                 shCount -= 8 ;
7231                 
7232                 if (size > 1){
7233                         if (shCount)
7234                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7235                         else 
7236                                 movLeft2Result(left, LSB, result, MSB16);
7237                 }
7238                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
7239         }
7240         
7241         /*  1 <= shCount <= 7 */
7242         else {  
7243                 if(size == 1)
7244                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
7245                 else 
7246                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7247         }
7248 }
7249
7250 /*-----------------------------------------------------------------*/
7251 /* shiftLLong - shift left one long from left to result            */
7252 /* offl = LSB or MSB16                                             */
7253 /*-----------------------------------------------------------------*/
7254 static void shiftLLong (operand *left, operand *result, int offr )
7255 {
7256         char *l;
7257         int size = AOP_SIZE(result);
7258         
7259         FENTRY;
7260         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7261         if(size >= LSB+offr){
7262                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7263                 MOVA(l);
7264                 pic14_emitcode("add","a,acc");
7265                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7266                         size >= MSB16+offr && offr != LSB )
7267                         pic14_emitcode("xch","a,%s",
7268                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7269                 else      
7270                         aopPut(AOP(result),"a",LSB+offr);
7271         }
7272         
7273         if(size >= MSB16+offr){
7274                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7275                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7276                         MOVA(l);
7277                 }
7278                 pic14_emitcode("rlc","a");
7279                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7280                         size >= MSB24+offr && offr != LSB)
7281                         pic14_emitcode("xch","a,%s",
7282                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7283                 else      
7284                         aopPut(AOP(result),"a",MSB16+offr);
7285         }
7286         
7287         if(size >= MSB24+offr){
7288                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7289                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7290                         MOVA(l);
7291                 }
7292                 pic14_emitcode("rlc","a");
7293                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7294                         size >= MSB32+offr && offr != LSB )
7295                         pic14_emitcode("xch","a,%s",
7296                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7297                 else      
7298                         aopPut(AOP(result),"a",MSB24+offr);
7299         }
7300         
7301         if(size > MSB32+offr){
7302                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7303                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7304                         MOVA(l);  
7305                 }
7306                 pic14_emitcode("rlc","a");
7307                 aopPut(AOP(result),"a",MSB32+offr);
7308         }
7309         if(offr != LSB)
7310                 aopPut(AOP(result),zero,LSB);       
7311 }
7312
7313 /*-----------------------------------------------------------------*/
7314 /* genlshFour - shift four byte by a known amount != 0             */
7315 /*-----------------------------------------------------------------*/
7316 static void genlshFour (operand *result, operand *left, int shCount)
7317 {
7318         int size;
7319         
7320         FENTRY;
7321         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7322         size = AOP_SIZE(result);
7323         
7324         /* if shifting more that 3 bytes */
7325         if (shCount >= 24 ) {
7326                 shCount -= 24;
7327                 if (shCount)
7328                 /* lowest order of left goes to the highest
7329                 order of the destination */
7330                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7331                 else
7332                         movLeft2Result(left, LSB, result, MSB32);
7333                 aopPut(AOP(result),zero,LSB);
7334                 aopPut(AOP(result),zero,MSB16);
7335                 aopPut(AOP(result),zero,MSB32);
7336                 return;
7337         }
7338         
7339         /* more than two bytes */
7340         else if ( shCount >= 16 ) {
7341                 /* lower order two bytes goes to higher order two bytes */
7342                 shCount -= 16;
7343                 /* if some more remaining */
7344                 if (shCount)
7345                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7346                 else {
7347                         movLeft2Result(left, MSB16, result, MSB32);
7348                         movLeft2Result(left, LSB, result, MSB24);
7349                 }
7350                 aopPut(AOP(result),zero,MSB16);
7351                 aopPut(AOP(result),zero,LSB);
7352                 return;
7353         }    
7354         
7355         /* if more than 1 byte */
7356         else if ( shCount >= 8 ) {
7357                 /* lower order three bytes goes to higher order  three bytes */
7358                 shCount -= 8;
7359                 if(size == 2){
7360                         if(shCount)
7361                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7362                         else
7363                                 movLeft2Result(left, LSB, result, MSB16);
7364                 }
7365                 else{   /* size = 4 */
7366                         if(shCount == 0){
7367                                 movLeft2Result(left, MSB24, result, MSB32);
7368                                 movLeft2Result(left, MSB16, result, MSB24);
7369                                 movLeft2Result(left, LSB, result, MSB16);
7370                                 aopPut(AOP(result),zero,LSB);
7371                         }
7372                         else if(shCount == 1)
7373                                 shiftLLong(left, result, MSB16);
7374                         else{
7375                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7376                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7377                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7378                                 aopPut(AOP(result),zero,LSB);
7379                         }
7380                 }
7381         }
7382         
7383         /* 1 <= shCount <= 7 */
7384         else if(shCount <= 2){
7385                 shiftLLong(left, result, LSB);
7386                 if(shCount == 2)
7387                         shiftLLong(result, result, LSB);
7388         }
7389         /* 3 <= shCount <= 7, optimize */
7390         else{
7391                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7392                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7393                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7394         }
7395 }
7396 #endif
7397
7398 #if 0
7399 /*-----------------------------------------------------------------*/
7400 /* genLeftShiftLiteral - left shifting by known count              */
7401 /*-----------------------------------------------------------------*/
7402 static void genLeftShiftLiteral (operand *left,
7403                                                                  operand *right,
7404                                                                  operand *result,
7405                                                                  iCode *ic)
7406 {    
7407         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7408         //int size;
7409         
7410         FENTRY;
7411         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7412         freeAsmop(right,NULL,ic,TRUE);
7413         
7414         aopOp(left,ic,FALSE);
7415         aopOp(result,ic,FALSE);
7416
7417         size = getSize(operandType(result));
7418         
7419 #if VIEW_SIZE
7420         pic14_emitcode("; shift left ","result %d, left %d",size,
7421                 AOP_SIZE(left));
7422 #endif
7423         
7424         /* I suppose that the left size >= result size */
7425         if(shCount == 0){
7426                 while(size--){
7427                         movLeft2Result(left, size, result, size);
7428                 }
7429         }
7430         
7431         else if(shCount >= (size * 8))
7432                 while(size--)
7433                         aopPut(AOP(result),zero,size);
7434                 else{
7435                         switch (size) {
7436                         case 1:
7437                                 genlshOne (result,left,shCount);
7438                                 break;
7439                                 
7440                         case 2:
7441                         case 3:
7442                                 genlshTwo (result,left,shCount);
7443                                 break;
7444                                 
7445                         case 4:
7446                                 genlshFour (result,left,shCount);
7447                                 break;
7448                         }
7449                 }
7450                 freeAsmop(left,NULL,ic,TRUE);
7451                 freeAsmop(result,NULL,ic,TRUE);
7452 }
7453 #endif
7454
7455 /*-----------------------------------------------------------------*
7456 * genMultiAsm - repeat assembly instruction for size of register.
7457 * if endian == 1, then the high byte (i.e base address + size of 
7458 * register) is used first else the low byte is used first;
7459 *-----------------------------------------------------------------*/
7460 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7461 {
7462         
7463         int offset = 0;
7464         
7465         FENTRY;
7466         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7467         
7468         if(!reg)
7469                 return;
7470         
7471         if(!endian) {
7472                 endian = 1;
7473         } else {
7474                 endian = -1;
7475                 offset = size-1;
7476         }
7477         
7478         while(size--) {
7479                 emitpcode(poc,    popGet(AOP(reg),offset));
7480                 offset += endian;
7481         }
7482         
7483 }
7484 /*-----------------------------------------------------------------*/
7485 /* genLeftShift - generates code for left shifting                 */
7486 /*-----------------------------------------------------------------*/
7487 static void genLeftShift (iCode *ic)
7488 {
7489         operand *left,*right, *result;
7490         int size, offset;
7491         unsigned long lit = 0L;
7492         char *l;
7493         symbol *tlbl , *tlbl1;
7494         pCodeOp *pctemp;
7495         
7496         FENTRY;
7497         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7498         
7499         right = IC_RIGHT(ic);
7500         left  = IC_LEFT(ic);
7501         result = IC_RESULT(ic);
7502         
7503         aopOp(right,ic,FALSE);
7504         aopOp(left,ic,FALSE);
7505         aopOp(result,ic,FALSE);
7506         
7507         
7508         /* if the shift count is known then do it 
7509         as efficiently as possible */
7510         if (AOP_TYPE(right) == AOP_LIT) {
7511                 shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
7512                 return ;
7513         }
7514         
7515         /* shift count is unknown then we have to form 
7516         a loop get the loop count in B : Note: we take
7517         only the lower order byte since shifting
7518         more that 32 bits make no sense anyway, ( the
7519         largest size of an object can be only 32 bits ) */  
7520         
7521         
7522         /* now move the left to the result if they are not the
7523         same */
7524         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7525                 AOP_SIZE(result) > 1) {
7526                 
7527                 size = AOP_SIZE(result);
7528                 offset=0;
7529                 while (size--) {
7530                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7531                         if (*l == '@' && (IS_AOP_PREG(result))) {
7532                                 
7533                                 pic14_emitcode("mov","a,%s",l);
7534                                 aopPut(AOP(result),"a",offset);
7535                         } else {
7536                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7537                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7538                                 //aopPut(AOP(result),l,offset);
7539                         }
7540                         offset++;
7541                 }
7542         }
7543         
7544         if(AOP_TYPE(left) == AOP_LIT)
7545                 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7546
7547         size = AOP_SIZE(result);
7548         
7549         /* if it is only one byte then */
7550         if (size == 1) {
7551                 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7552                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7553                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7554                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7555                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7556                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7557                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7558                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7559                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7560                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7561                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7562                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7563                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7564                 } else {
7565                         
7566                         tlbl = newiTempLabel(NULL);
7567                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7568                                 if (AOP_TYPE(left) == AOP_LIT)
7569                                         emitpcode(POC_MOVLW,  popGetLit(lit));
7570                                 else
7571                                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7572                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7573                         }
7574                         
7575                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7576                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7577                         emitpLabel(tlbl->key);
7578                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7579                         emitpcode(POC_ADDLW,  popGetLit(1));
7580                         emitSKPC;
7581                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7582                 }
7583                 goto release ;
7584         }
7585         
7586         if (pic14_sameRegs(AOP(left),AOP(result))) {
7587                 
7588                 tlbl = newiTempLabel(NULL);
7589                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7590                 genMultiAsm(POC_RRF, result, size,1);
7591                 emitpLabel(tlbl->key);
7592                 genMultiAsm(POC_RLF, result, size,0);
7593                 emitpcode(POC_ADDLW,  popGetLit(1));
7594                 emitSKPC;
7595                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7596                 goto release;
7597         }
7598         
7599         //tlbl = newiTempLabel(NULL);
7600         //offset = 0 ;   
7601         //tlbl1 = newiTempLabel(NULL);
7602         
7603         //reAdjustPreg(AOP(result));    
7604         
7605         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7606         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7607         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7608         //MOVA(l);
7609         //pic14_emitcode("add","a,acc");         
7610         //aopPut(AOP(result),"a",offset++);
7611         //while (--size) {
7612         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7613         //  MOVA(l);
7614         //  pic14_emitcode("rlc","a");         
7615         //  aopPut(AOP(result),"a",offset++);
7616         //}
7617         //reAdjustPreg(AOP(result));
7618         
7619         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7620         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7621         
7622         
7623         tlbl = newiTempLabel(NULL);
7624         tlbl1= newiTempLabel(NULL);
7625         
7626         size = AOP_SIZE(result);
7627         offset = 1;
7628         
7629         pctemp = popGetTempReg();  /* grab a temporary working register. */
7630         
7631         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7632         
7633         /* offset should be 0, 1 or 3 */
7634         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7635         emitSKPNZ;
7636         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7637         
7638         emitpcode(POC_MOVWF, pctemp);
7639         
7640         
7641         emitpLabel(tlbl->key);
7642         
7643         emitCLRC;
7644         emitpcode(POC_RLF,  popGet(AOP(result),0));
7645         while(--size)
7646                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7647         
7648         emitpcode(POC_DECFSZ,  pctemp);
7649         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7650         emitpLabel(tlbl1->key);
7651         
7652         popReleaseTempReg(pctemp);
7653         
7654         
7655 release:
7656         freeAsmop (right,NULL,ic,TRUE);
7657         freeAsmop(left,NULL,ic,TRUE);
7658         freeAsmop(result,NULL,ic,TRUE);
7659 }
7660
7661 #if 0
7662 /*-----------------------------------------------------------------*/
7663 /* genrshOne - right shift a one byte quantity by known count      */
7664 /*-----------------------------------------------------------------*/
7665 static void genrshOne (operand *result, operand *left,
7666                                            int shCount, int sign)
7667 {
7668         FENTRY;
7669         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7670         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7671 }
7672
7673 /*-----------------------------------------------------------------*/
7674 /* genrshTwo - right shift two bytes by known amount != 0          */
7675 /*-----------------------------------------------------------------*/
7676 static void genrshTwo (operand *result,operand *left,
7677                                            int shCount, int sign)
7678 {
7679         FENTRY;
7680         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7681         /* if shCount >= 8 */
7682         if (shCount >= 8) {
7683                 shCount -= 8 ;
7684                 if (shCount)
7685                         shiftR1Left2Result(left, MSB16, result, LSB,
7686                         shCount, sign);
7687                 else
7688                         movLeft2Result(left, MSB16, result, LSB);
7689                 
7690                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7691                 
7692                 if(sign) {
7693                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7694                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7695                 }
7696         }
7697         
7698         /*  1 <= shCount <= 7 */
7699         else
7700                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7701 }
7702
7703 /*-----------------------------------------------------------------*/
7704 /* shiftRLong - shift right one long from left to result           */
7705 /* offl = LSB or MSB16                                             */
7706 /*-----------------------------------------------------------------*/
7707 static void shiftRLong (operand *left, int offl,
7708                                                 operand *result, int sign)
7709 {
7710         int size, same;
7711         
7712         FENTRY;
7713         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7714         
7715         size = AOP_SIZE(left);
7716         if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
7717         
7718         if (sign)
7719                 emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
7720         else
7721                 emitCLRC;
7722
7723         assert (offl >= 0 && offl < size);
7724
7725         same = pic14_sameRegs (AOP(left), AOP(result));
7726
7727         /* perform the shift */
7728         while (size--)
7729         {
7730                 if (same && !offl) {
7731                         emitpcode (POC_RRF, popGet (AOP(result), size));
7732                 } else {
7733                         emitpcode (POC_RRFW, popGet (AOP(left), size));
7734                         emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
7735                 }
7736         } // while
7737
7738         addSign (result, AOP_SIZE(left) - offl, sign);
7739 }
7740
7741 /*-----------------------------------------------------------------*/
7742 /* genrshFour - shift four byte by a known amount != 0             */
7743 /*-----------------------------------------------------------------*/
7744 static void genrshFour (operand *result, operand *left,
7745                                                 int shCount, int sign)
7746 {
7747         FENTRY;
7748         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7749         /* if shifting more that 3 bytes */
7750         if(shCount >= 24 ) {
7751                 shCount -= 24;
7752                 if(shCount)
7753                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7754                 else
7755                         movLeft2Result(left, MSB32, result, LSB);
7756                 
7757                 addSign(result, MSB16, sign);
7758         }
7759         else if(shCount >= 16){
7760                 shCount -= 16;
7761                 if(shCount)
7762                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7763                 else{
7764                         movLeft2Result(left, MSB24, result, LSB);
7765                         movLeft2Result(left, MSB32, result, MSB16);
7766                 }
7767                 addSign(result, MSB24, sign);
7768         }
7769         else if(shCount >= 8){
7770                 shCount -= 8;
7771                 if(shCount == 1)
7772                         shiftRLong(left, MSB16, result, sign);
7773                 else if(shCount == 0){
7774                         movLeft2Result(left, MSB16, result, LSB);
7775                         movLeft2Result(left, MSB24, result, MSB16);
7776                         movLeft2Result(left, MSB32, result, MSB24);
7777                         addSign(result, MSB32, sign);
7778                 }
7779                 else{
7780                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7781                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7782                         /* the last shift is signed */
7783                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7784                         addSign(result, MSB32, sign);
7785                 }
7786         }
7787         else{   /* 1 <= shCount <= 7 */
7788                 if(shCount <= 2){
7789                         shiftRLong(left, LSB, result, sign);
7790                         if(shCount == 2)
7791                                 shiftRLong(result, LSB, result, sign);
7792                 }
7793                 else{
7794                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7795                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7796                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7797                 }
7798         }
7799 }
7800
7801 /*-----------------------------------------------------------------*/
7802 /* genRightShiftLiteral - right shifting by known count            */
7803 /*-----------------------------------------------------------------*/
7804 static void genRightShiftLiteral (operand *left,
7805                                                                   operand *right,
7806                                                                   operand *result,
7807                                                                   iCode *ic,
7808                                                                   int sign)
7809 {    
7810         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7811         int lsize,res_size;
7812         
7813         FENTRY;
7814         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7815         freeAsmop(right,NULL,ic,TRUE);
7816         
7817         aopOp(left,ic,FALSE);
7818         aopOp(result,ic,FALSE);
7819         
7820 #if VIEW_SIZE
7821         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7822                 AOP_SIZE(left));
7823 #endif
7824         
7825         lsize = pic14_getDataSize(left);
7826         res_size = pic14_getDataSize(result);
7827         /* test the LEFT size !!! */
7828         
7829         /* I suppose that the left size >= result size */
7830         if(shCount == 0){
7831                 while(res_size--)
7832                         movLeft2Result(left, res_size, result, res_size);
7833         }
7834         
7835         else if(shCount >= (lsize * 8)){
7836                 
7837                 if(res_size == 1) {
7838                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7839                         if(sign) {
7840                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7841                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7842                         }
7843                 } else {
7844                         
7845                         if(sign) {
7846                                 emitpcode(POC_MOVLW, popGetLit(0));
7847                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7848                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7849                                 while(res_size--)
7850                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7851                                 
7852                         } else {
7853                                 
7854                                 while(res_size--)
7855                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7856                         }
7857                 }
7858         } else {
7859                 
7860                 switch (res_size) {
7861                 case 1:
7862                         genrshOne (result,left,shCount,sign);
7863                         break;
7864                         
7865                 case 2:
7866                         genrshTwo (result,left,shCount,sign);
7867                         break;
7868                         
7869                 case 4:
7870                         genrshFour (result,left,shCount,sign);
7871                         break;
7872                 default :
7873                         break;
7874                 }
7875                 
7876         }
7877
7878         freeAsmop(left,NULL,ic,TRUE);
7879         freeAsmop(result,NULL,ic,TRUE);
7880 }
7881 #endif
7882
7883 /*-----------------------------------------------------------------*/
7884 /* genSignedRightShift - right shift of signed number              */
7885 /*-----------------------------------------------------------------*/
7886 static void genSignedRightShift (iCode *ic)
7887 {
7888         operand *right, *left, *result;
7889         int size, offset;
7890         //  char *l;
7891         symbol *tlbl, *tlbl1 ;
7892         pCodeOp *pctemp;
7893         
7894         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7895         
7896         /* we do it the hard way put the shift count in b
7897         and loop thru preserving the sign */
7898         FENTRY;
7899         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7900         
7901         right = IC_RIGHT(ic);
7902         left  = IC_LEFT(ic);
7903         result = IC_RESULT(ic);
7904         
7905         aopOp(right,ic,FALSE);  
7906         aopOp(left,ic,FALSE);
7907         aopOp(result,ic,FALSE);
7908         
7909         
7910         if ( AOP_TYPE(right) == AOP_LIT) {
7911                 shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
7912                 //genRightShiftLiteral (left,right,result,ic,1);
7913                 return ;
7914         }
7915         /* shift count is unknown then we have to form 
7916         a loop get the loop count in B : Note: we take
7917         only the lower order byte since shifting
7918         more that 32 bits make no sense anyway, ( the
7919         largest size of an object can be only 32 bits ) */  
7920         
7921         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7922         //pic14_emitcode("inc","b");
7923         //freeAsmop (right,NULL,ic,TRUE);
7924         //aopOp(left,ic,FALSE);
7925         //aopOp(result,ic,FALSE);
7926         
7927         /* now move the left to the result if they are not the
7928         same */
7929         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7930                 AOP_SIZE(result) > 1) {
7931                 
7932                 size = AOP_SIZE(result);
7933                 offset=0;
7934                 while (size--) { 
7935                         /*
7936                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7937                         if (*l == '@' && IS_AOP_PREG(result)) {
7938                                 pic14_emitcode("mov","a,%s",l);
7939                                 aopPut(AOP(result),"a",offset);
7940                         } else
7941                         aopPut(AOP(result),l,offset);
7942                         */
7943                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7944                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7945                         
7946                         offset++;
7947                 }
7948         }
7949         
7950         /* mov the highest order bit to OVR */    
7951         tlbl = newiTempLabel(NULL);
7952         tlbl1= newiTempLabel(NULL);
7953         
7954         size = AOP_SIZE(result);
7955         offset = size - 1;
7956         
7957         pctemp = popGetTempReg();  /* grab a temporary working register. */
7958         
7959         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7960         
7961         /* offset should be 0, 1 or 3 */
7962         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7963         emitSKPNZ;
7964         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7965         
7966         emitpcode(POC_MOVWF, pctemp);
7967         
7968         
7969         emitpLabel(tlbl->key);
7970         
7971         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7972         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7973         
7974         while(--size) {
7975                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7976         }
7977         
7978         emitpcode(POC_DECFSZ,  pctemp);
7979         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7980         emitpLabel(tlbl1->key);
7981         
7982         popReleaseTempReg(pctemp);
7983 #if 0
7984         size = AOP_SIZE(result);
7985         offset = size - 1;
7986         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7987         pic14_emitcode("rlc","a");
7988         pic14_emitcode("mov","ov,c");
7989         /* if it is only one byte then */
7990         if (size == 1) {
7991                 l = aopGet(AOP(left),0,FALSE,FALSE);
7992                 MOVA(l);
7993                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7994                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7995                 pic14_emitcode("mov","c,ov");
7996                 pic14_emitcode("rrc","a");
7997                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7998                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7999                 aopPut(AOP(result),"a",0);
8000                 goto release ;
8001         }
8002         
8003         reAdjustPreg(AOP(result));
8004         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8005         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
8006         pic14_emitcode("mov","c,ov");
8007         while (size--) {
8008                 l = aopGet(AOP(result),offset,FALSE,FALSE);
8009                 MOVA(l);
8010                 pic14_emitcode("rrc","a");         
8011                 aopPut(AOP(result),"a",offset--);
8012         }
8013         reAdjustPreg(AOP(result));
8014         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
8015         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8016         
8017 release:
8018 #endif
8019         
8020         freeAsmop(left,NULL,ic,TRUE);
8021         freeAsmop(result,NULL,ic,TRUE);
8022         freeAsmop(right,NULL,ic,TRUE);
8023 }
8024
8025 /*-----------------------------------------------------------------*/
8026 /* genRightShift - generate code for right shifting                */
8027 /*-----------------------------------------------------------------*/
8028 static void genRightShift (iCode *ic)
8029 {
8030         operand *right, *left, *result;
8031         sym_link *retype ;
8032         int size, offset;
8033         char *l;
8034         symbol *tlbl, *tlbl1 ;
8035         
8036         FENTRY;
8037         /* if signed then we do it the hard way preserve the
8038         sign bit moving it inwards */
8039         retype = getSpec(operandType(IC_RESULT(ic)));
8040         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8041         
8042         if (!SPEC_USIGN(retype)) {
8043                 genSignedRightShift (ic);
8044                 return ;
8045         }
8046         
8047         /* signed & unsigned types are treated the same : i.e. the
8048         signed is NOT propagated inwards : quoting from the
8049         ANSI - standard : "for E1 >> E2, is equivalent to division
8050         by 2**E2 if unsigned or if it has a non-negative value,
8051         otherwise the result is implementation defined ", MY definition
8052         is that the sign does not get propagated */
8053         
8054         right = IC_RIGHT(ic);
8055         left  = IC_LEFT(ic);
8056         result = IC_RESULT(ic);
8057         
8058         aopOp(right,ic,FALSE);
8059         aopOp(left,ic,FALSE);
8060         aopOp(result,ic,FALSE);
8061         
8062         /* if the shift count is known then do it 
8063         as efficiently as possible */
8064         if (AOP_TYPE(right) == AOP_LIT) {
8065                 shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0);
8066                 //genRightShiftLiteral (left,right,result,ic, 0);
8067                 return ;
8068         }
8069         
8070         /* shift count is unknown then we have to form 
8071         a loop get the loop count in B : Note: we take
8072         only the lower order byte since shifting
8073         more that 32 bits make no sense anyway, ( the
8074         largest size of an object can be only 32 bits ) */  
8075         
8076         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
8077         pic14_emitcode("inc","b");
8078         
8079         /* now move the left to the result if they are not the
8080         same */
8081         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
8082                 AOP_SIZE(result) > 1) {
8083                 
8084                 size = AOP_SIZE(result);
8085                 offset=0;
8086                 while (size--) {
8087                         l = aopGet(AOP(left),offset,FALSE,TRUE);
8088                         if (*l == '@' && IS_AOP_PREG(result)) {
8089                                 
8090                                 pic14_emitcode("mov","a,%s",l);
8091                                 aopPut(AOP(result),"a",offset);
8092                         } else
8093                                 aopPut(AOP(result),l,offset);
8094                         offset++;
8095                 }
8096         }
8097         
8098         tlbl = newiTempLabel(NULL);
8099         tlbl1= newiTempLabel(NULL);
8100         size = AOP_SIZE(result);
8101         offset = size - 1;
8102         
8103         /* if it is only one byte then */
8104         if (size == 1) {
8105                 
8106                 tlbl = newiTempLabel(NULL);
8107                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
8108                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
8109                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
8110                 }
8111                 
8112                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
8113                 emitpcode(POC_RLF,    popGet(AOP(result),0));
8114                 emitpLabel(tlbl->key);
8115                 emitpcode(POC_RRF,    popGet(AOP(result),0));
8116                 emitpcode(POC_ADDLW,  popGetLit(1));
8117                 emitSKPC;
8118                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
8119                 
8120                 goto release ;
8121         }
8122         
8123         reAdjustPreg(AOP(result));
8124         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8125         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
8126         CLRC;
8127         while (size--) {
8128                 l = aopGet(AOP(result),offset,FALSE,FALSE);
8129                 MOVA(l);
8130                 pic14_emitcode("rrc","a");         
8131                 aopPut(AOP(result),"a",offset--);
8132         }
8133         reAdjustPreg(AOP(result));
8134         
8135         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
8136         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8137         
8138 release:
8139         freeAsmop(left,NULL,ic,TRUE);
8140         freeAsmop (right,NULL,ic,TRUE);
8141         freeAsmop(result,NULL,ic,TRUE);
8142 }
8143
8144 /*-----------------------------------------------------------------*/
8145 /* genUnpackBits - generates code for unpacking bits               */
8146 /*-----------------------------------------------------------------*/
8147 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
8148 {    
8149         int shCnt;
8150         int offset = 0;       /* result byte offset */
8151         int rsize;            /* result size */
8152         int rlen = 0;         /* remaining bitfield length */
8153         sym_link *etype;      /* bitfield type information */
8154         int blen;             /* bitfield length */
8155         int bstr;             /* bitfield starting bit within byte */
8156
8157         FENTRY;
8158         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8159         etype = getSpec(operandType(result));
8160         rsize = getSize (operandType (result));
8161         blen = SPEC_BLEN (etype);
8162         bstr = SPEC_BSTR (etype);
8163         
8164         /* single bit field case */
8165         if (blen == 1) {
8166                 if (ifx) { /* that is for an if statement */
8167                         pCodeOp *pcop;
8168                         resolvedIfx rIfx;
8169                         resolveIfx(&rIfx,ifx);
8170                         if (ptype == -1) /* direct */
8171                                 pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
8172                         else
8173                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
8174                         emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
8175                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
8176                         ifx->generated=1;
8177                 } else {
8178                         pCodeOp *pcop;
8179                         
8180                         if (ptype == -1) /* direct */
8181                                 pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
8182                         else
8183                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
8184                         emitpcode(POC_BTFSC,pcop);
8185                         emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result), 0,FALSE,FALSE),bstr,0));
8186                         if (ptype == -1) /* direct */
8187                                 pcop = newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),bstr,0);
8188                         else
8189                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
8190                         emitpcode(POC_BTFSS,pcop);
8191                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0));
8192                 }
8193                 return;
8194         }
8195
8196         {
8197           static int has_warned=0;
8198           if (!has_warned)
8199           {
8200             fprintf (stderr, "%s: bitfields with more than 1 bit are probably broken...", __FUNCTION__);
8201             has_warned=1;
8202           }
8203         }
8204
8205         /* read the first byte  */
8206         switch (ptype) {
8207                 
8208         case POINTER:
8209         case IPOINTER:
8210 //              pic14_emitcode("mov","a,@%s",rname);
8211                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8212                 break;
8213                 
8214         case PPOINTER:
8215                 pic14_emitcode("movx","a,@%s",rname);
8216                 break;
8217                 
8218         case FPOINTER:
8219                 pic14_emitcode("movx","a,@dptr");
8220                 break;
8221                 
8222         case CPOINTER:
8223                 pic14_emitcode("clr","a");
8224                 pic14_emitcode("movc","a","@a+dptr");
8225                 break;
8226                 
8227         case GPOINTER:
8228                 pic14_emitcode("lcall","__gptrget");
8229                 break;
8230         }
8231
8232         /* if we have bitdisplacement then it fits   */
8233         /* into this byte completely or if length is */
8234         /* less than a byte                          */
8235         if ((shCnt = SPEC_BSTR(etype)) || blen <= 8)  {
8236                 
8237                 /* shift right acc */
8238                 AccRsh(left,0,shCnt);
8239                 
8240                 pic14_emitcode("anl","a,#0x%02x",
8241                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8242                 aopPut(AOP(result),"a",offset);
8243                 return ;
8244         }
8245         
8246         /* bit field did not fit in a byte  */
8247         rlen = SPEC_BLEN(etype) - 8;
8248         aopPut(AOP(result),"a",offset++);
8249         
8250         while (1)  {
8251                 
8252                 switch (ptype) {
8253                 case POINTER:
8254                 case IPOINTER:
8255                         pic14_emitcode("inc","%s",rname);
8256                         pic14_emitcode("mov","a,@%s",rname);
8257                         break;
8258                         
8259                 case PPOINTER:
8260                         pic14_emitcode("inc","%s",rname);
8261                         pic14_emitcode("movx","a,@%s",rname);
8262                         break;
8263                         
8264                 case FPOINTER:
8265                         pic14_emitcode("inc","dptr");
8266                         pic14_emitcode("movx","a,@dptr");
8267                         break;
8268                         
8269                 case CPOINTER:
8270                         pic14_emitcode("clr","a");
8271                         pic14_emitcode("inc","dptr");
8272                         pic14_emitcode("movc","a","@a+dptr");
8273                         break;
8274                         
8275                 case GPOINTER:
8276                         pic14_emitcode("inc","dptr");
8277                         pic14_emitcode("lcall","__gptrget");
8278                         break;
8279                 }
8280                 
8281                 rlen -= 8;            
8282                 /* if we are done */
8283                 if ( rlen <= 0 )
8284                         break ;
8285                 
8286                 aopPut(AOP(result),"a",offset++);
8287                 
8288         }
8289         
8290         if (rlen) {
8291                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8292                 aopPut(AOP(result),"a",offset);        
8293         }
8294         
8295         return ;
8296 }
8297
8298 #if 1
8299 /*-----------------------------------------------------------------*/
8300 /* genDataPointerGet - generates code when ptr offset is known     */
8301 /*-----------------------------------------------------------------*/
8302 static void genDataPointerGet (operand *left, 
8303         operand *result, 
8304         iCode *ic)
8305 {
8306         int size , offset = 0;
8307                 
8308         FENTRY;
8309         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8310         
8311         
8312         /* optimization - most of the time, left and result are the same
8313         * address, but different types. for the pic code, we could omit
8314         * the following
8315         */
8316         aopOp(result,ic,TRUE);
8317         
8318         if (pic14_sameRegs (AOP(left), AOP(result)))
8319                 return;
8320         
8321         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8322         
8323         //emitpcode(POC_MOVFW, popGet(AOP(left),0));
8324         
8325         size = AOP_SIZE(result);
8326         if (size > AOP_SIZE(left)) size = AOP_SIZE(left);
8327         
8328         while (size--) {
8329                 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
8330                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8331                 offset++;
8332         }
8333         
8334         freeAsmop(left,NULL,ic,TRUE);
8335         freeAsmop(result,NULL,ic,TRUE);
8336 }
8337 #endif
8338 /*-----------------------------------------------------------------*/
8339 /* genNearPointerGet - pic14_emitcode for near pointer fetch       */
8340 /*-----------------------------------------------------------------*/
8341 static void genNearPointerGet (operand *left, 
8342                                                            operand *result, 
8343                                                            iCode *ic)
8344 {
8345         asmop *aop = NULL;
8346         sym_link *ltype = operandType(left);
8347         sym_link *rtype = operandType(result);
8348         sym_link *retype= getSpec(rtype);      /* bitfield type information */
8349         int direct = 0;
8350
8351         FENTRY;
8352         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8353         
8354         
8355         aopOp(left,ic,FALSE);
8356         
8357         /* if left is rematerialisable and
8358         result is not bit variable type and
8359         the left is pointer to data space i.e
8360         lower 128 bytes of space */
8361         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8362                 !IS_BITVAR(retype)         &&
8363                 DCL_TYPE(ltype) == POINTER) {
8364                 genDataPointerGet (left,result,ic);
8365                 return ;
8366         }
8367         
8368         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8369         aopOp (result,ic,FALSE);
8370         
8371         /* Check if can access directly instead of via a pointer */
8372         if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
8373                 direct = 1;
8374         }
8375
8376         /* If the pointer value is not in a the FSR then need to put it in */
8377         if (!AOP_INPREG(AOP(left)) && !direct) {
8378                 /* otherwise get a free pointer register */
8379                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8380                 if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */ 
8381                         emitpcode(POC_MOVLW, popGet(AOP(left),0));
8382                 else
8383                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
8384                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8385         }
8386         
8387         
8388 //      sym_link *etype;
8389         /* if bitfield then unpack the bits */
8390         if (IS_BITFIELD(retype)) 
8391                 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8392         else {
8393                 /* we have can just get the values */
8394                 int size = AOP_SIZE(result);
8395                 int offset = 0 ;  
8396                 
8397                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8398                 
8399                 while(size--) {
8400                         if (direct)
8401                                 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8402                         else
8403                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8404                         if (AOP_TYPE(result) == AOP_LIT) {
8405                                 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8406                         } else {
8407                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8408                         }
8409                         if (size && !direct)
8410                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8411                         offset++;
8412                 }
8413         }
8414         
8415         /* now some housekeeping stuff */
8416         if (aop) {
8417                 /* we had to allocate for this iCode */
8418                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8419                 freeAsmop(NULL,aop,ic,TRUE);
8420         } else { 
8421                 /* we did not allocate which means left
8422                 already in a pointer register, then
8423                 if size > 0 && this could be used again
8424                 we have to point it back to where it 
8425                 belongs */
8426                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8427                 if (AOP_SIZE(result) > 1 &&
8428                         !OP_SYMBOL(left)->remat &&
8429                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8430                         ic->depth )) {
8431                         int size = AOP_SIZE(result) - 1;
8432                         while (size--)
8433                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8434                 }
8435         }
8436         
8437         /* done */
8438         freeAsmop(left,NULL,ic,TRUE);
8439         freeAsmop(result,NULL,ic,TRUE);
8440
8441 }
8442
8443 /*-----------------------------------------------------------------*/
8444 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8445 /*-----------------------------------------------------------------*/
8446 static void genPagedPointerGet (operand *left, 
8447                                                                 operand *result, 
8448                                                                 iCode *ic)
8449 {
8450         asmop *aop = NULL;
8451         regs *preg = NULL ;
8452         char *rname ;
8453         sym_link *rtype, *retype;    
8454         
8455         FENTRY;
8456         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8457         
8458         rtype = operandType(result);
8459         retype= getSpec(rtype);
8460         
8461         aopOp(left,ic,FALSE);
8462         
8463         /* if the value is already in a pointer register
8464         then don't need anything more */
8465         if (!AOP_INPREG(AOP(left))) {
8466                 /* otherwise get a free pointer register */
8467                 aop = newAsmop(0);
8468                 preg = getFreePtr(ic,&aop,FALSE);
8469                 pic14_emitcode("mov","%s,%s",
8470                         preg->name,
8471                         aopGet(AOP(left),0,FALSE,TRUE));
8472                 rname = preg->name ;
8473         } else
8474                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8475         
8476         freeAsmop(left,NULL,ic,TRUE);
8477         aopOp (result,ic,FALSE);
8478         
8479         /* if bitfield then unpack the bits */
8480         if (IS_BITFIELD(retype)) 
8481                 genUnpackBits (result,left,rname,PPOINTER,0);
8482         else {
8483                 /* we have can just get the values */
8484                 int size = AOP_SIZE(result);
8485                 int offset = 0 ;  
8486                 
8487                 while (size--) {
8488                         
8489                         pic14_emitcode("movx","a,@%s",rname);
8490                         aopPut(AOP(result),"a",offset);
8491                         
8492                         offset++ ;
8493                         
8494                         if (size)
8495                                 pic14_emitcode("inc","%s",rname);
8496                 }
8497         }
8498         
8499         /* now some housekeeping stuff */
8500         if (aop) {
8501                 /* we had to allocate for this iCode */
8502                 freeAsmop(NULL,aop,ic,TRUE);
8503         } else { 
8504         /* we did not allocate which means left
8505         already in a pointer register, then
8506         if size > 0 && this could be used again
8507         we have to point it back to where it 
8508                 belongs */
8509                 if (AOP_SIZE(result) > 1 &&
8510                         !OP_SYMBOL(left)->remat &&
8511                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8512                         ic->depth )) {
8513                         int size = AOP_SIZE(result) - 1;
8514                         while (size--)
8515                                 pic14_emitcode("dec","%s",rname);
8516                 }
8517         }
8518         
8519         /* done */
8520         freeAsmop(result,NULL,ic,TRUE);
8521         
8522         
8523 }
8524
8525 /*-----------------------------------------------------------------*/
8526 /* genFarPointerGet - gget value from far space                    */
8527 /*-----------------------------------------------------------------*/
8528 static void genFarPointerGet (operand *left,
8529                                                           operand *result, iCode *ic)
8530 {
8531         int size, offset ;
8532         sym_link *retype = getSpec(operandType(result));
8533         
8534         FENTRY;
8535         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8536         
8537         aopOp(left,ic,FALSE);
8538         
8539         /* if the operand is already in dptr 
8540         then we do nothing else we move the value to dptr */
8541         if (AOP_TYPE(left) != AOP_STR) {
8542                 /* if this is remateriazable */
8543                 if (AOP_TYPE(left) == AOP_IMMD)
8544                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8545                 else { /* we need to get it byte by byte */
8546                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8547                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8548                         if (options.model == MODEL_FLAT24)
8549                         {
8550                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8551                         }
8552                 }
8553         }
8554         /* so dptr know contains the address */
8555         freeAsmop(left,NULL,ic,TRUE);
8556         aopOp(result,ic,FALSE);
8557         
8558         /* if bit then unpack */
8559         if (IS_BITFIELD(retype)) 
8560                 genUnpackBits(result,left,"dptr",FPOINTER,0);
8561         else {
8562                 size = AOP_SIZE(result);
8563                 offset = 0 ;
8564                 
8565                 while (size--) {
8566                         pic14_emitcode("movx","a,@dptr");
8567                         aopPut(AOP(result),"a",offset++);
8568                         if (size)
8569                                 pic14_emitcode("inc","dptr");
8570                 }
8571         }
8572         
8573         freeAsmop(result,NULL,ic,TRUE);
8574 }
8575 #if 0
8576 /*-----------------------------------------------------------------*/
8577 /* genCodePointerGet - get value from code space                  */
8578 /*-----------------------------------------------------------------*/
8579 static void genCodePointerGet (operand *left,
8580                                                            operand *result, iCode *ic)
8581 {
8582         int size, offset ;
8583         sym_link *retype = getSpec(operandType(result));
8584         
8585         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8586         
8587         aopOp(left,ic,FALSE);
8588         
8589         /* if the operand is already in dptr 
8590         then we do nothing else we move the value to dptr */
8591         if (AOP_TYPE(left) != AOP_STR) {
8592                 /* if this is remateriazable */
8593                 if (AOP_TYPE(left) == AOP_IMMD)
8594                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8595                 else { /* we need to get it byte by byte */
8596                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8597                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8598                         if (options.model == MODEL_FLAT24)
8599                         {
8600                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8601                         }
8602                 }
8603         }
8604         /* so dptr know contains the address */
8605         freeAsmop(left,NULL,ic,TRUE);
8606         aopOp(result,ic,FALSE);
8607         
8608         /* if bit then unpack */
8609         if (IS_BITFIELD(retype)) 
8610                 genUnpackBits(result,left,"dptr",CPOINTER,0);
8611         else {
8612                 size = AOP_SIZE(result);
8613                 offset = 0 ;
8614                 
8615                 while (size--) {
8616                         pic14_emitcode("clr","a");
8617                         pic14_emitcode("movc","a,@a+dptr");
8618                         aopPut(AOP(result),"a",offset++);
8619                         if (size)
8620                                 pic14_emitcode("inc","dptr");
8621                 }
8622         }
8623         
8624         freeAsmop(result,NULL,ic,TRUE);
8625 }
8626 #endif
8627 /*-----------------------------------------------------------------*/
8628 /* genGenPointerGet - gget value from generic pointer space        */
8629 /*-----------------------------------------------------------------*/
8630 static void genGenPointerGet (operand *left,
8631                                                           operand *result, iCode *ic)
8632 {
8633         int size, offset ;
8634         sym_link *retype = getSpec(operandType(result));
8635         
8636         FENTRY;
8637         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8638         aopOp(left,ic,FALSE);
8639         aopOp(result,ic,FALSE);
8640         
8641         
8642         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8643         
8644         /* if the operand is already in dptr 
8645         then we do nothing else we move the value to dptr */
8646         //  if (AOP_TYPE(left) != AOP_STR) {
8647         /* if this is remateriazable */
8648         if (AOP_TYPE(left) == AOP_IMMD) {
8649                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8650                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8651         }
8652         else { /* we need to get it byte by byte */
8653                 
8654                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8655                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8656                 
8657                 size = AOP_SIZE(result);
8658                 offset = 0 ;
8659                 
8660                 while(size--) {
8661                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8662                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8663                         if(size)
8664                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8665                 }
8666                 goto release;
8667         }
8668         //}
8669         /* so dptr know contains the address */
8670         
8671         /* if bit then unpack */
8672         //if (IS_BITFIELD(retype)) 
8673         //  genUnpackBits(result,"dptr",GPOINTER);
8674         
8675 release:
8676         freeAsmop(left,NULL,ic,TRUE);
8677         freeAsmop(result,NULL,ic,TRUE);
8678         
8679 }
8680
8681 /*-----------------------------------------------------------------*/
8682 /* genConstPointerGet - get value from const generic pointer space */
8683 /*-----------------------------------------------------------------*/
8684 static void genConstPointerGet (operand *left,
8685                                                                 operand *result, iCode *ic)
8686 {
8687         //sym_link *retype = getSpec(operandType(result));
8688         symbol *albl, *blbl;//, *clbl;
8689         PIC_OPCODE poc;
8690         int i, size, lit;
8691         pCodeOp *pcop;
8692         
8693         FENTRY;
8694         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8695         aopOp(left,ic,FALSE);
8696         aopOp(result,ic,FALSE);
8697         
8698         size = AOP_SIZE(result);
8699         
8700         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8701         
8702         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8703
8704         lit = aop_isLitLike (AOP(left));
8705         poc = lit ? POC_MOVLW : POC_MOVFW;
8706
8707         if (lit)
8708         {
8709                 for (i = 0; i < size; i++)
8710                 {
8711                         albl = newiTempLabel(NULL);
8712                         blbl = newiTempLabel(NULL);
8713                         
8714                         emitpcode(POC_CALL,popGetLabel(albl->key));
8715                         pcop = popGetLabel(blbl->key);
8716                         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8717                         emitpcode(POC_GOTO,pcop);
8718                         
8719                         emitpLabel(albl->key);
8720                         emitpcode(poc,popGetAddr(AOP(left),1,i));
8721                         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8722                         emitpcode(poc,popGetAddr(AOP(left),0,i));
8723                         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8724                 
8725                         emitpLabel(blbl->key);
8726                         emitpcode(POC_MOVWF,popGet(AOP(result),i));
8727                 } // for
8728         } else {
8729                 albl = newiTempLabel(NULL);
8730                 blbl = newiTempLabel(NULL);
8731                 //clbl = newiTempLabel(NULL);
8732
8733                 emitpcode (POC_GOTO, popGetLabel (blbl->key));
8734                 
8735                 emitpLabel(albl->key);
8736                 emitpcode(poc,popGet(AOP(left),1));
8737                 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8738                 emitpcode(poc,popGet(AOP(left),0));
8739                 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8740                 
8741                 emitpLabel(blbl->key);
8742                 
8743                 for (i = 0; i < size; i++)
8744                 {
8745                         emitpcode(POC_CALL,popGetLabel(albl->key));
8746                         /* the next two instructions (plus clbl) might be useless... */
8747                         //pcop = popGetLabel(clbl->key);
8748                         //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8749                         //emitpcode(POC_GOTO,pcop);
8750                         //emitpLabel(clbl->key);
8751
8752                         if (i+1 < size) {
8753                                 emitpcode (POC_INCF, popGet (AOP(left), 0));
8754                                 emitSKPNZ;
8755                                 emitpcode (POC_INCF, popGet (AOP(left), 1));
8756                         }
8757                         emitpcode(POC_MOVWF,popGet(AOP(result),i));
8758                 } // for
8759                 if (size > 1) {
8760                         /* restore left's value */
8761                         emitpcode (POC_MOVLW, popGetLit (size-1));
8762                         emitpcode (POC_SUBWF, popGet (AOP(left), 0));
8763                         emitSKPC;
8764                         emitpcode (POC_DECF, popGet (AOP(left), 1));
8765                 } // if
8766         } // if (lit)
8767         
8768         freeAsmop(left,NULL,ic,TRUE);
8769         freeAsmop(result,NULL,ic,TRUE);
8770         
8771 }
8772 /*-----------------------------------------------------------------*/
8773 /* genPointerGet - generate code for pointer get                   */
8774 /*-----------------------------------------------------------------*/
8775 static void genPointerGet (iCode *ic)
8776 {
8777         operand *left, *result ;
8778         sym_link *type, *etype;
8779         int p_type = -1;
8780         
8781         FENTRY;
8782         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8783         
8784         left = IC_LEFT(ic);
8785         result = IC_RESULT(ic) ;
8786         
8787         /* depending on the type of pointer we need to
8788         move it to the correct pointer register */
8789         type = operandType(left);
8790         etype = getSpec(type);
8791         
8792         if (IS_PTR_CONST(type))
8793                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8794         
8795         /* if left is of type of pointer then it is simple */
8796         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8797                 p_type = DCL_TYPE(type);
8798         else {
8799                 /* we have to go by the storage class */
8800                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8801                 
8802                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8803                 
8804                 if (SPEC_OCLS(etype)->codesp ) {
8805                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8806                         //p_type = CPOINTER ; 
8807                 }
8808                 else
8809                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8810                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8811                         /*p_type = FPOINTER ;*/ 
8812                         else
8813                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8814                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8815                                 /*        p_type = PPOINTER; */
8816                                 else
8817                                         if (SPEC_OCLS(etype) == idata )
8818                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8819                                         /*      p_type = IPOINTER; */
8820                                         else
8821                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8822                                         /*      p_type = POINTER ; */
8823         }
8824         
8825         /* now that we have the pointer type we assign
8826         the pointer values */
8827         switch (p_type) {
8828                 
8829         case POINTER: 
8830         case IPOINTER:
8831                 genNearPointerGet (left,result,ic);
8832                 break;
8833                 
8834         case PPOINTER:
8835                 genPagedPointerGet(left,result,ic);
8836                 break;
8837                 
8838         case FPOINTER:
8839                 genFarPointerGet (left,result,ic);
8840                 break;
8841                 
8842         case CPOINTER:
8843                 genConstPointerGet (left,result,ic);
8844                 //pic14_emitcodePointerGet (left,result,ic);
8845                 break;
8846                 
8847         case GPOINTER:
8848                 if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype))
8849                         genConstPointerGet (left,result,ic);
8850                 else
8851                         genGenPointerGet (left,result,ic);
8852                 break;
8853         default:
8854                 assert ( !"unhandled pointer type" );
8855                 break;
8856         }
8857         
8858 }
8859
8860 /*-----------------------------------------------------------------*/
8861 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into  */
8862 /* A through a pointer register (R0, R1, or DPTR). The original    */
8863 /* value of A can be preserved in B.                               */
8864 /* PIC has to use INDF register.                                   */
8865 /*-----------------------------------------------------------------*/
8866 static void
8867 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8868 {
8869     FENTRY;
8870     switch (p_type)
8871     {
8872     case IPOINTER:
8873     case POINTER:
8874                 if (preserveAinB)
8875                         pic14_emitcode ("mov", "b,a");
8876 //              pic14_emitcode ("mov", "a,@%s", rname);
8877                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8878                 break;
8879                 
8880     case PPOINTER:
8881                 if (preserveAinB)
8882                         pic14_emitcode ("mov", "b,a");
8883                 pic14_emitcode ("movx", "a,@%s", rname);
8884                 break;
8885                 
8886     case FPOINTER:
8887                 if (preserveAinB)
8888                         pic14_emitcode ("mov", "b,a");
8889                 pic14_emitcode ("movx", "a,@dptr");
8890                 break;
8891                 
8892     case CPOINTER:
8893                 if (preserveAinB)
8894                         pic14_emitcode ("mov", "b,a");
8895                 pic14_emitcode ("clr", "a");
8896                 pic14_emitcode ("movc", "a,@a+dptr");
8897                 break;
8898                 
8899     case GPOINTER:
8900                 if (preserveAinB)
8901         {
8902                         pic14_emitcode ("push", "b");
8903                         pic14_emitcode ("push", "acc");
8904         }
8905                 pic14_emitcode ("lcall", "__gptrget");
8906                 if (preserveAinB)
8907                         pic14_emitcode ("pop", "b");
8908                 break;
8909     }
8910 }
8911
8912 /*-----------------------------------------------------------------*/
8913 /* emitPtrByteSet - emits code to set a byte from src through a    */
8914 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR).       */
8915 /*-----------------------------------------------------------------*/
8916 static void
8917 emitPtrByteSet (char *rname, int p_type, char *src)
8918 {
8919     FENTRY;
8920     switch (p_type)
8921     {
8922     case IPOINTER:
8923     case POINTER:
8924                 if (*src=='@')
8925         {
8926                         MOVA (src);
8927                         pic14_emitcode ("mov", "@%s,a", rname);
8928         }
8929                 else
8930 //                      pic14_emitcode ("mov", "@%s,%s", rname, src);
8931                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8932                 break;
8933                 
8934     case PPOINTER:
8935                 MOVA (src);
8936                 pic14_emitcode ("movx", "@%s,a", rname);
8937                 break;
8938                 
8939     case FPOINTER:
8940                 MOVA (src);
8941                 pic14_emitcode ("movx", "@dptr,a");
8942                 break;
8943                 
8944     case GPOINTER:
8945                 MOVA (src);
8946                 pic14_emitcode ("lcall", "__gptrput");
8947                 break;
8948     }
8949 }
8950
8951 /*-----------------------------------------------------------------*/
8952 /* genPackBits - generates code for packed bit storage             */
8953 /*-----------------------------------------------------------------*/
8954 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8955 {
8956         int offset = 0;       /* source byte offset */
8957         int rlen = 0;         /* remaining bitfield length */
8958         int blen;             /* bitfield length */
8959         int bstr;             /* bitfield starting bit within byte */
8960         int litval;           /* source literal value (if AOP_LIT) */
8961         unsigned char mask;   /* bitmask within current byte */
8962
8963         FENTRY;
8964         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8965         
8966         blen = SPEC_BLEN (etype);
8967         bstr = SPEC_BSTR (etype);
8968         
8969         /* If the bitfield length is less than a byte */
8970         if (blen < 8)
8971     {
8972                 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8973                         (unsigned char) (0xFF >> (8 - bstr)));
8974                 
8975                 if (AOP_TYPE (right) == AOP_LIT)
8976         {
8977                         /* Case with a bitfield length <8 and literal source
8978                         */
8979                         int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8980                         if (blen == 1) {
8981                                 if (p_type == -1) {
8982                                         pCodeOp *pcop;
8983                                         if (AOP(result)->type == AOP_PCODE)
8984                                                 pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
8985                                         else
8986                                                 pcop = popGet(AOP(result),0);
8987                                         emitpcode(lit?POC_BSF:POC_BCF,pcop);
8988                                 } else {
8989                                         emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8990                                 }
8991                                 return;
8992                         } else {
8993                                 litval = lit << bstr;
8994                                 litval &= (~mask) & 0xff;
8995                                 if (p_type == -1)
8996                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8997                                 else
8998                                         emitPtrByteGet (rname, p_type, FALSE);
8999                                 if ((mask|litval)!=0xff)
9000                                         emitpcode(POC_ANDLW,popGetLit(mask));
9001                                 if (litval)
9002                                         emitpcode(POC_IORLW,popGetLit(litval));
9003                         }
9004         }
9005                 else
9006         {
9007                         if (blen==1) {
9008                                 if (p_type == -1) {
9009                                         /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
9010                                         emitpcode(POC_RLF,popGet(AOP(right),0));
9011                                         emitSKPC;
9012                                         emitpcode(POC_BCF,popGet(AOP(result),0));
9013                                         emitSKPNC;
9014                                         emitpcode(POC_BSF,popGet(AOP(result),0));
9015                                 } else if (p_type!=GPOINTER) {
9016                                         /* Case with a bitfield length == 1 and no generic pointer
9017                                         */
9018                                         if (AOP_TYPE (right) == AOP_CRY)
9019                                                 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
9020                                         else
9021                                         {
9022                                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
9023                                                 pic14_emitcode ("rrc","a");
9024                                         }
9025                                         emitPtrByteGet (rname, p_type, FALSE);
9026                                         pic14_emitcode ("mov","acc.%d,c",bstr);
9027                                 }
9028             }
9029                         else
9030             {
9031                                 //bool pushedB;
9032                                 /* Case with a bitfield length < 8 and arbitrary source
9033                                 */
9034                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
9035                                 /* shift and mask source value */
9036                                 AccLsh (right,0,bstr);
9037                                 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
9038                                 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
9039                                 
9040                                 //pushedB = pushB ();
9041                                 if (p_type == -1)
9042                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
9043                                 else
9044                                         emitPtrByteGet (rname, p_type, TRUE);
9045                                 
9046                                 pic14_emitcode ("anl", "a,#0x%02x", mask);
9047                                 pic14_emitcode ("orl", "a,b");
9048                                 emitpcode(POC_ANDLW,popGetLit(mask));
9049                                 emitpcode(POC_IORFW,popGet(AOP(right),0));
9050                                 if (p_type == GPOINTER)
9051                                         pic14_emitcode ("pop", "b");
9052                                 
9053                                 //popB (pushedB);
9054                         }
9055         }
9056                 
9057                 if (p_type == -1)
9058                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
9059                 else
9060                         emitPtrByteSet (rname, p_type, "a");
9061                 return;
9062     }
9063         
9064         /* Bit length is greater than 7 bits. In this case, copy  */
9065         /* all except the partial byte at the end                 */
9066         for (rlen=blen;rlen>=8;rlen-=8)
9067     {
9068                 emitPtrByteSet (rname, p_type,
9069                         aopGet (AOP (right), offset++, FALSE, TRUE) );
9070                 if (rlen>8)
9071                         pic14_emitcode ("inc", "%s", rname);
9072     }
9073         
9074         /* If there was a partial byte at the end */
9075         if (rlen)
9076     {
9077                 mask = (((unsigned char) -1 << rlen) & 0xff);
9078                 
9079                 if (AOP_TYPE (right) == AOP_LIT)
9080         {
9081                 /* Case with partial byte and literal source
9082                         */
9083                         litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
9084                         litval >>= (blen-rlen);
9085                         litval &= (~mask) & 0xff;
9086                         emitPtrByteGet (rname, p_type, FALSE);
9087                         if ((mask|litval)!=0xff)
9088                                 pic14_emitcode ("anl","a,#0x%02x", mask);
9089                         if (litval)
9090                                 pic14_emitcode ("orl","a,#0x%02x", litval);
9091         }
9092                 else
9093         {
9094                         //bool pushedB;
9095                         /* Case with partial byte and arbitrary source
9096                         */
9097                         MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
9098                         pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
9099                         
9100                         //pushedB = pushB ();
9101                         /* transfer A to B and get next byte */
9102                         emitPtrByteGet (rname, p_type, TRUE);
9103                         
9104                         pic14_emitcode ("anl", "a,#0x%02x", mask);
9105                         pic14_emitcode ("orl", "a,b");
9106                         if (p_type == GPOINTER)
9107                                 pic14_emitcode ("pop", "b");
9108                         
9109                         //popB (pushedB);
9110         }
9111                 emitPtrByteSet (rname, p_type, "a");
9112     }
9113         
9114 }
9115
9116 /*-----------------------------------------------------------------*/
9117 /* SetIrp - Set IRP bit                                            */
9118 /*-----------------------------------------------------------------*/
9119 void SetIrp(operand *result) {
9120         FENTRY;
9121         if (AOP_TYPE(result) == AOP_LIT) {
9122                 unsigned lit = (unsigned)operandLitValue(result);
9123                 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9124         } else {
9125                 if (PCOP(AOP(result))->type == PO_LITERAL) {
9126                         int addrs = PCOL(AOP(result))->lit;
9127                         emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9128                 } else {
9129                         emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
9130                         if(AOP_SIZE(result) > 1) {
9131                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
9132                                 emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9133                         }
9134                 }
9135         }
9136 }
9137
9138 /*-----------------------------------------------------------------*/
9139 /* genDataPointerSet - remat pointer to data space                 */
9140 /*-----------------------------------------------------------------*/
9141 static void genDataPointerSet(operand *right,
9142         operand *result,
9143         iCode *ic)
9144 {
9145         int size, offset = 0 ;
9146         
9147         FENTRY;
9148         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9149         aopOp(right,ic,FALSE);
9150         aopOp(result,ic,FALSE);
9151         
9152         size = AOP_SIZE(right);
9153         /*
9154         if ( AOP_TYPE(result) == AOP_PCODE) {
9155         fprintf(stderr,"genDataPointerSet   %s, %d\n",
9156         AOP(result)->aopu.pcop->name,
9157         PCOI(AOP(result)->aopu.pcop)->offset);
9158         }
9159         */
9160         
9161         // tsd, was l+1 - the underline `_' prefix was being stripped
9162         while (size--) {
9163                 emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
9164                 
9165                 if (AOP_TYPE(right) == AOP_LIT) {
9166                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9167                         lit = lit >> (8*offset);
9168                         if(lit&0xff) {
9169                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
9170                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9171                         } else {
9172                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9173                         }
9174                 } else {
9175                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9176                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9177                 }
9178                 
9179                 offset++;
9180         }
9181         
9182         freeAsmop(right,NULL,ic,TRUE);
9183         freeAsmop(result,NULL,ic,TRUE);
9184 }
9185
9186 /*-----------------------------------------------------------------*/
9187 /* genNearPointerSet - pic14_emitcode for near pointer put         */
9188 /*-----------------------------------------------------------------*/
9189 static void genNearPointerSet (operand *right,
9190                                                            operand *result, 
9191                                                            iCode *ic)
9192 {
9193         asmop *aop = NULL;
9194         sym_link *ptype = operandType(result);
9195         sym_link *retype = getSpec(operandType(right));
9196         sym_link *letype = getSpec(ptype);
9197         int direct = 0;
9198         
9199         
9200         FENTRY;
9201         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9202         aopOp(result,ic,FALSE);
9203         
9204         
9205         /* if the result is rematerializable &
9206         in data space & not a bit variable */
9207         //if (AOP_TYPE(result) == AOP_IMMD &&
9208         if (AOP_TYPE(result) == AOP_PCODE &&
9209                 DCL_TYPE(ptype) == POINTER   &&
9210                 !IS_BITVAR (retype) &&
9211                 !IS_BITVAR (letype)) {
9212                 genDataPointerSet (right,result,ic);
9213                 freeAsmop(result,NULL,ic,TRUE);
9214                 return;
9215         }
9216
9217         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9218         aopOp(right,ic,FALSE);
9219         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9220         
9221         /* Check if can access directly instead of via a pointer */
9222         if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
9223                 direct = 1;
9224         }
9225
9226         /* If the pointer value is not in a the FSR then need to put it in */
9227         if (!AOP_INPREG(AOP(result)) && !direct) {
9228                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9229                 if (PCOP(AOP(result))->type == PO_LITERAL) 
9230                         emitpcode(POC_MOVLW, popGet(AOP(result),0));
9231                 else
9232                         emitpcode(POC_MOVFW, popGet(AOP(result),0));
9233                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
9234         }
9235
9236         /* Must set/reset IRP bit for use with FSR. */
9237         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9238         if (!direct)
9239                 SetIrp(result);
9240
9241         /* if bitfield then unpack the bits */
9242         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9243                 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
9244         } else {
9245                 /* we have can just get the values */
9246                 int size = AOP_SIZE(right);
9247                 int offset = 0 ;    
9248                 
9249                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9250                 while (size--) {
9251                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9252                         if (*l == '@' ) {
9253                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9254                         } else {
9255                                 if (AOP_TYPE(right) == AOP_LIT) {
9256                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9257                                 } else {
9258                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9259                                 }
9260                                 if (direct)
9261                                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
9262                                 else
9263                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9264                         }
9265                         if (size && !direct)
9266                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9267                         offset++;
9268                 }
9269         }
9270         
9271         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9272         /* now some housekeeping stuff */
9273         if (aop) {
9274                 /* we had to allocate for this iCode */
9275                 freeAsmop(NULL,aop,ic,TRUE);
9276         } else { 
9277                 /* we did not allocate which means left
9278                 already in a pointer register, then
9279                 if size > 0 && this could be used again
9280                 we have to point it back to where it 
9281                 belongs */
9282                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9283                 if (AOP_SIZE(right) > 1 &&
9284                         !OP_SYMBOL(result)->remat &&
9285                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
9286                         ic->depth )) {
9287                         int size = AOP_SIZE(right) - 1;
9288                         while (size--)
9289                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
9290                 }
9291         }
9292         
9293         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9294         /* done */
9295
9296         freeAsmop(right,NULL,ic,TRUE);
9297         freeAsmop(result,NULL,ic,TRUE);
9298 }
9299
9300 /*-----------------------------------------------------------------*/
9301 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
9302 /*-----------------------------------------------------------------*/
9303 static void genPagedPointerSet (operand *right,
9304                                                                 operand *result, 
9305                                                                 iCode *ic)
9306 {
9307         asmop *aop = NULL;
9308         regs *preg = NULL ;
9309         char *rname , *l;
9310         sym_link *retype;
9311         
9312         FENTRY;
9313         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9314         
9315         retype= getSpec(operandType(right));
9316         
9317         aopOp(result,ic,FALSE);
9318         
9319         /* if the value is already in a pointer register
9320         then don't need anything more */
9321         if (!AOP_INPREG(AOP(result))) {
9322                 /* otherwise get a free pointer register */
9323                 aop = newAsmop(0);
9324                 preg = getFreePtr(ic,&aop,FALSE);
9325                 pic14_emitcode("mov","%s,%s",
9326                         preg->name,
9327                         aopGet(AOP(result),0,FALSE,TRUE));
9328                 rname = preg->name ;
9329         } else
9330                 rname = aopGet(AOP(result),0,FALSE,FALSE);
9331         
9332         freeAsmop(result,NULL,ic,TRUE);
9333         aopOp (right,ic,FALSE);
9334         
9335         /* if bitfield then unpack the bits */
9336         if (IS_BITFIELD(retype)) 
9337                 genPackBits (retype,result,right,rname,PPOINTER);
9338         else {
9339                 /* we have can just get the values */
9340                 int size = AOP_SIZE(right);
9341                 int offset = 0 ;  
9342                 
9343                 while (size--) {
9344                         l = aopGet(AOP(right),offset,FALSE,TRUE);
9345                         
9346                         MOVA(l);
9347                         pic14_emitcode("movx","@%s,a",rname);
9348                         
9349                         if (size)
9350                                 pic14_emitcode("inc","%s",rname);
9351                         
9352                         offset++;
9353                 }
9354         }
9355         
9356         /* now some housekeeping stuff */
9357         if (aop) {
9358                 /* we had to allocate for this iCode */
9359                 freeAsmop(NULL,aop,ic,TRUE);
9360         } else { 
9361         /* we did not allocate which means left
9362         already in a pointer register, then
9363         if size > 0 && this could be used again
9364         we have to point it back to where it 
9365                 belongs */
9366                 if (AOP_SIZE(right) > 1 &&
9367                         !OP_SYMBOL(result)->remat &&
9368                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
9369                         ic->depth )) {
9370                         int size = AOP_SIZE(right) - 1;
9371                         while (size--)
9372                                 pic14_emitcode("dec","%s",rname);
9373                 }
9374         }
9375         
9376         /* done */
9377         freeAsmop(right,NULL,ic,TRUE);
9378         
9379         
9380 }
9381
9382 /*-----------------------------------------------------------------*/
9383 /* genFarPointerSet - set value from far space                     */
9384 /*-----------------------------------------------------------------*/
9385 static void genFarPointerSet (operand *right,
9386                                                           operand *result, iCode *ic)
9387 {
9388         int size, offset ;
9389         sym_link *retype = getSpec(operandType(right));
9390         
9391         FENTRY;
9392         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9393         aopOp(result,ic,FALSE);
9394         
9395         /* if the operand is already in dptr 
9396         then we do nothing else we move the value to dptr */
9397         if (AOP_TYPE(result) != AOP_STR) {
9398                 /* if this is remateriazable */
9399                 if (AOP_TYPE(result) == AOP_IMMD)
9400                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9401                 else { /* we need to get it byte by byte */
9402                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
9403                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
9404                         if (options.model == MODEL_FLAT24)
9405                         {
9406                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
9407                         }
9408                 }
9409         }
9410         /* so dptr know contains the address */
9411         freeAsmop(result,NULL,ic,TRUE);
9412         aopOp(right,ic,FALSE);
9413         
9414         /* if bit then unpack */
9415         if (IS_BITFIELD(retype)) 
9416                 genPackBits(retype,result,right,"dptr",FPOINTER);
9417         else {
9418                 size = AOP_SIZE(right);
9419                 offset = 0 ;
9420                 
9421                 while (size--) {
9422                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
9423                         MOVA(l);
9424                         pic14_emitcode("movx","@dptr,a");
9425                         if (size)
9426                                 pic14_emitcode("inc","dptr");
9427                 }
9428         }
9429         
9430         freeAsmop(right,NULL,ic,TRUE);
9431 }
9432
9433 /*-----------------------------------------------------------------*/
9434 /* genGenPointerSet - set value from generic pointer space         */
9435 /*-----------------------------------------------------------------*/
9436 static void genGenPointerSet (operand *right,
9437                                                           operand *result, iCode *ic)
9438 {
9439         sym_link *ptype = operandType(result);
9440         sym_link *retype = getSpec(operandType(right));
9441         sym_link *letype = getSpec (ptype);
9442         
9443         FENTRY;
9444         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9445         
9446         aopOp(result,ic,FALSE);
9447         aopOp(right,ic,FALSE);
9448         
9449         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9450         
9451         /* if the operand is already in dptr 
9452         then we do nothing else we move the value to dptr */
9453         if (AOP_TYPE(result) != AOP_STR) {
9454                 /* if this is remateriazable */
9455                 if (AOP_TYPE(result) == AOP_IMMD) {
9456                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9457                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9458                 }
9459                 else {
9460                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
9461                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9462
9463                         /* Must set/reset IRP bit for use with FSR. */
9464                         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9465                         SetIrp(result);
9466                 }
9467         }
9468
9469         /* if bitfield then unpack the bits */
9470         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9471                 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9472         } else {
9473                 /* we have can just get the values */
9474                 int size = AOP_SIZE(right);
9475                 int offset = 0 ;    
9476                 
9477                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9478                 while (size--) {
9479                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9480                         if (*l == '@' ) {
9481                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9482                         } else {
9483                                 if (AOP_TYPE(right) == AOP_LIT) {
9484                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9485                                 } else {
9486                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9487                                 }
9488                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9489                         }
9490                         if (size)
9491                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9492                         offset++;
9493                 }
9494         }
9495         
9496         freeAsmop(right,NULL,ic,TRUE);
9497         freeAsmop(result,NULL,ic,TRUE);
9498 }
9499
9500 /*-----------------------------------------------------------------*/
9501 /* genPointerSet - stores the value into a pointer location        */
9502 /*-----------------------------------------------------------------*/
9503 static void genPointerSet (iCode *ic)
9504 {    
9505         operand *right, *result ;
9506         sym_link *type, *etype;
9507         int p_type;
9508         
9509         FENTRY;
9510         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9511         
9512         right = IC_RIGHT(ic);
9513         result = IC_RESULT(ic) ;
9514         
9515         /* depending on the type of pointer we need to
9516         move it to the correct pointer register */
9517         type = operandType(result);
9518         etype = getSpec(type);
9519         /* if left is of type of pointer then it is simple */
9520         if (IS_PTR(type) && !IS_FUNC(type->next)) {
9521                 p_type = DCL_TYPE(type);
9522         }
9523         else {
9524                 /* we have to go by the storage class */
9525                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9526                 
9527                 /*  if (SPEC_OCLS(etype)->codesp ) { */
9528                 /*      p_type = CPOINTER ;  */
9529                 /*  } */
9530                 /*  else */
9531                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9532                 /*    p_type = FPOINTER ; */
9533                 /*      else */
9534                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9535                 /*        p_type = PPOINTER ; */
9536                 /*    else */
9537                 /*        if (SPEC_OCLS(etype) == idata ) */
9538                 /*      p_type = IPOINTER ; */
9539                 /*        else */
9540                 /*      p_type = POINTER ; */
9541         }
9542         
9543         /* now that we have the pointer type we assign
9544         the pointer values */
9545         switch (p_type) {
9546                 
9547         case POINTER:
9548         case IPOINTER:
9549                 genNearPointerSet (right,result,ic);
9550                 break;
9551                 
9552         case PPOINTER:
9553                 genPagedPointerSet (right,result,ic);
9554                 break;
9555                 
9556         case FPOINTER:
9557                 genFarPointerSet (right,result,ic);
9558                 break;
9559                 
9560         case GPOINTER:
9561                 genGenPointerSet (right,result,ic);
9562                 break;
9563                 
9564         default:
9565                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9566                         "genPointerSet: illegal pointer type");
9567         }
9568 }
9569
9570 /*-----------------------------------------------------------------*/
9571 /* genIfx - generate code for Ifx statement                        */
9572 /*-----------------------------------------------------------------*/
9573 static void genIfx (iCode *ic, iCode *popIc)
9574 {
9575         operand *cond = IC_COND(ic);
9576         int isbit =0;
9577         
9578         FENTRY;
9579         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9580         
9581         aopOp(cond,ic,FALSE);
9582         
9583         /* get the value into acc */
9584         if (AOP_TYPE(cond) != AOP_CRY)
9585                 pic14_toBoolean(cond);
9586         else
9587                 isbit = 1;
9588         /* the result is now in the accumulator */
9589         freeAsmop(cond,NULL,ic,TRUE);
9590         
9591         /* if there was something to be popped then do it */
9592         if (popIc)
9593                 genIpop(popIc);
9594         
9595         /* if the condition is  a bit variable */
9596         if (isbit && IS_ITEMP(cond) && 
9597                 SPIL_LOC(cond)) {
9598                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9599                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9600         }
9601         else {
9602                 if (isbit && !IS_ITEMP(cond))
9603                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9604                 else
9605                         genIfxJump(ic,"a");
9606         }
9607         ic->generated = 1;
9608         
9609 }
9610
9611 /*-----------------------------------------------------------------*/
9612 /* genAddrOf - generates code for address of                       */
9613 /*-----------------------------------------------------------------*/
9614 static void genAddrOf (iCode *ic)
9615 {
9616         operand *right, *result, *left;
9617         int size, offset ;
9618         
9619         FENTRY;
9620         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9621         
9622         
9623         //aopOp(IC_RESULT(ic),ic,FALSE);
9624         
9625         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9626         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9627         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9628         
9629         DEBUGpic14_AopType(__LINE__,left,right,result);
9630         assert (IS_SYMOP (left));
9631         
9632         /* sanity check: generic pointers to code space are not yet supported,
9633          * pionters to codespace must not be assigned addresses of __data values. */
9634  #if 0
9635         fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
9636         fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
9637         fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
9638         fprintf (stderr, "left->type   : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
9639         fprintf (stderr, "left->etype  : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
9640 #endif
9641
9642         if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
9643           fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
9644                 IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
9645                 OP_SYMBOL(left)->name);
9646         } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
9647           fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
9648                 IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
9649                 OP_SYMBOL(left)->name);
9650         }
9651         
9652         size = AOP_SIZE(IC_RESULT(ic));
9653         offset = 0;
9654         
9655         while (size--) {
9656                 /* fixing bug #863624, reported from (errolv) */
9657                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9658                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9659                 
9660 #if 0
9661                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9662                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9663 #endif
9664                 offset++;
9665         }
9666         
9667         freeAsmop(left,NULL,ic,FALSE);
9668         freeAsmop(result,NULL,ic,TRUE);
9669         
9670 }
9671
9672 #if 0
9673 /*-----------------------------------------------------------------*/
9674 /* genFarFarAssign - assignment when both are in far space         */
9675 /*-----------------------------------------------------------------*/
9676 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9677 {
9678         int size = AOP_SIZE(right);
9679         int offset = 0;
9680         char *l ;
9681         /* first push the right side on to the stack */
9682         while (size--) {
9683                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9684                 MOVA(l);
9685                 pic14_emitcode ("push","acc");
9686         }
9687         
9688         freeAsmop(right,NULL,ic,FALSE);
9689         /* now assign DPTR to result */
9690         aopOp(result,ic,FALSE);
9691         size = AOP_SIZE(result);
9692         while (size--) {
9693                 pic14_emitcode ("pop","acc");
9694                 aopPut(AOP(result),"a",--offset);
9695         }
9696         freeAsmop(result,NULL,ic,FALSE);
9697         
9698 }
9699 #endif
9700
9701 /*-----------------------------------------------------------------*/
9702 /* genAssign - generate code for assignment                        */
9703 /*-----------------------------------------------------------------*/
9704 static void genAssign (iCode *ic)
9705 {
9706         operand *result, *right;
9707         int size, offset,know_W;
9708         unsigned long lit = 0L;
9709         
9710         result = IC_RESULT(ic);
9711         right  = IC_RIGHT(ic) ;
9712         
9713         FENTRY;
9714         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9715         
9716         /* if they are the same */
9717         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9718                 return ;
9719         
9720         aopOp(right,ic,FALSE);
9721         aopOp(result,ic,TRUE);
9722         
9723         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9724         
9725         /* if they are the same registers */
9726         if (pic14_sameRegs(AOP(right),AOP(result)))
9727                 goto release;
9728
9729         /* special case: assign from __code */
9730         if (!IS_ITEMP(right)                            /* --> iTemps never reside in __code */
9731                 && IS_SYMOP (right)                     /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
9732                 && !IS_FUNC(OP_SYM_TYPE(right))         /* --> we would want its address instead of the first instruction */
9733                 && !IS_CODEPTR(OP_SYM_TYPE(right))      /* --> get symbols address instread */
9734                 && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
9735         {
9736           emitpComment ("genAssign from CODESPACE");
9737           genConstPointerGet (right, result, ic);
9738           goto release;
9739         }
9740         
9741         /* just for symmetry reasons... */
9742         if (!IS_ITEMP(result)
9743                 && IS_SYMOP (result)
9744                 && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
9745         {
9746           assert ( !"cannot write to CODESPACE" );
9747         }
9748
9749         /* if the result is a bit */
9750         if (AOP_TYPE(result) == AOP_CRY) {
9751                 
9752         /* if the right size is a literal then
9753                 we know what the value is */
9754                 if (AOP_TYPE(right) == AOP_LIT) {
9755                         
9756                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9757                                 popGet(AOP(result),0));
9758                         
9759                         if (((int) operandLitValue(right))) 
9760                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9761                                 AOP(result)->aopu.aop_dir,
9762                                 AOP(result)->aopu.aop_dir);
9763                         else
9764                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9765                                 AOP(result)->aopu.aop_dir,
9766                                 AOP(result)->aopu.aop_dir);
9767                         goto release;
9768                 }
9769                 
9770                 /* the right is also a bit variable */
9771                 if (AOP_TYPE(right) == AOP_CRY) {
9772                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9773                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9774                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9775                         
9776                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9777                                 AOP(result)->aopu.aop_dir,
9778                                 AOP(result)->aopu.aop_dir);
9779                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9780                                 AOP(right)->aopu.aop_dir,
9781                                 AOP(right)->aopu.aop_dir);
9782                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9783                                 AOP(result)->aopu.aop_dir,
9784                                 AOP(result)->aopu.aop_dir);
9785                         goto release ;
9786                 }
9787                 
9788                 /* we need to or */
9789                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9790                 pic14_toBoolean(right);
9791                 emitSKPZ;
9792                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9793                 //aopPut(AOP(result),"a",0);
9794                 goto release ;
9795         }
9796         
9797         /* bit variables done */
9798         /* general case */
9799         size = AOP_SIZE(result);
9800         offset = 0 ;
9801         if(AOP_TYPE(right) == AOP_LIT)
9802                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9803         
9804         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9805                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9806                 if(aopIdx(AOP(result),0) == 4) {
9807                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9808                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9809                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9810                         goto release;
9811                 } else
9812                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9813         }
9814         
9815         know_W=-1;
9816         while (size--) {
9817                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9818                 if(AOP_TYPE(right) == AOP_LIT) {
9819                         if(lit&0xff) {
9820                                 if(know_W != (int)(lit&0xff))
9821                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9822                                 know_W = lit&0xff;
9823                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9824                         } else
9825                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9826                         
9827                         lit >>= 8;
9828                         
9829                 } else if (AOP_TYPE(right) == AOP_CRY) {
9830                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9831                         if(offset == 0) {
9832                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9833                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9834                         }
9835                 } else {
9836                         mov2w (AOP(right), offset);
9837                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9838                 }
9839                 
9840                 offset++;
9841         }
9842         
9843         
9844 release:
9845         freeAsmop (right,NULL,ic,FALSE);
9846         freeAsmop (result,NULL,ic,TRUE);
9847 }   
9848
9849 /*-----------------------------------------------------------------*/
9850 /* genJumpTab - genrates code for jump table                       */
9851 /*-----------------------------------------------------------------*/
9852 static void genJumpTab (iCode *ic)
9853 {
9854         symbol *jtab;
9855         char *l;
9856         
9857         FENTRY;
9858         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9859         
9860         aopOp(IC_JTCOND(ic),ic,FALSE);
9861         /* get the condition into accumulator */
9862         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9863         MOVA(l);
9864         /* multiply by three */
9865         pic14_emitcode("add","a,acc");
9866         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9867         
9868         jtab = newiTempLabel(NULL);
9869         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9870         pic14_emitcode("jmp","@a+dptr");
9871         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9872         
9873         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9874         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9875         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9876         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9877         emitSKPNC;
9878         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9879         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9880         emitpLabel(jtab->key);
9881         
9882         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9883         
9884         /* now generate the jump labels */
9885         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9886         jtab = setNextItem(IC_JTLABELS(ic))) {
9887                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9888                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9889                 
9890         }
9891         
9892 }
9893
9894 /*-----------------------------------------------------------------*/
9895 /* genMixedOperation - gen code for operators between mixed types  */
9896 /*-----------------------------------------------------------------*/
9897 /*
9898 TSD - Written for the PIC port - but this unfortunately is buggy.
9899 This routine is good in that it is able to efficiently promote 
9900 types to different (larger) sizes. Unfortunately, the temporary
9901 variables that are optimized out by this routine are sometimes
9902 used in other places. So until I know how to really parse the 
9903 iCode tree, I'm going to not be using this routine :(.
9904 */
9905 static int genMixedOperation (iCode *ic)
9906 {
9907         FENTRY;
9908 #if 0
9909         operand *result = IC_RESULT(ic);
9910         sym_link *ctype = operandType(IC_LEFT(ic));
9911         operand *right = IC_RIGHT(ic);
9912         int ret = 0;
9913         int big,small;
9914         int offset;
9915         
9916         iCode *nextic;
9917         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9918         
9919         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9920         
9921         nextic = ic->next;
9922         if(!nextic)
9923                 return 0;
9924         
9925         nextright = IC_RIGHT(nextic);
9926         nextleft  = IC_LEFT(nextic);
9927         nextresult = IC_RESULT(nextic);
9928         
9929         aopOp(right,ic,FALSE);
9930         aopOp(result,ic,FALSE);
9931         aopOp(nextright,  nextic, FALSE);
9932         aopOp(nextleft,   nextic, FALSE);
9933         aopOp(nextresult, nextic, FALSE);
9934         
9935         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9936                 
9937                 operand *t = right;
9938                 right = nextright;
9939                 nextright = t; 
9940                 
9941                 pic14_emitcode(";remove right +","");
9942                 
9943         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9944         /*
9945         operand *t = right;
9946         right = nextleft;
9947         nextleft = t; 
9948                 */
9949                 pic14_emitcode(";remove left +","");
9950         } else
9951                 return 0;
9952         
9953         big = AOP_SIZE(nextleft);
9954         small = AOP_SIZE(nextright);
9955         
9956         switch(nextic->op) {
9957                 
9958         case '+':
9959                 pic14_emitcode(";optimize a +","");
9960                 /* if unsigned or not an integral type */
9961                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9962                         pic14_emitcode(";add a bit to something","");
9963                 } else {
9964                         
9965                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9966                         
9967                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9968                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9969                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9970                         } else
9971                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9972                         
9973                         offset = 0;
9974                         while(--big) {
9975                                 
9976                                 offset++;
9977                                 
9978                                 if(--small) {
9979                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9980                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9981                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9982                                         }
9983                                         
9984                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9985                                         emitSKPNC;
9986                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9987                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9988                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9989                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9990                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9991                                         
9992                                 } else {
9993                                         pic14_emitcode("rlf","known_zero,w");
9994                                         
9995                                         /*
9996                                         if right is signed
9997                                         btfsc  right,7
9998                                         addlw ff
9999                                         */
10000                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10001                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10002                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10003                                         } else {
10004                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10005                                         }
10006                                 }
10007                         }
10008                         ret = 1;
10009                 }
10010         }
10011         ret = 1;
10012         
10013 release:
10014         freeAsmop(right,NULL,ic,TRUE);
10015         freeAsmop(result,NULL,ic,TRUE);
10016         freeAsmop(nextright,NULL,ic,TRUE);
10017         freeAsmop(nextleft,NULL,ic,TRUE);
10018         if(ret)
10019                 nextic->generated = 1;
10020         
10021         return ret;
10022 #else
10023         return 0;
10024 #endif
10025 }
10026 /*-----------------------------------------------------------------*/
10027 /* genCast - gen code for casting                                  */
10028 /*-----------------------------------------------------------------*/
10029 static void genCast (iCode *ic)
10030 {
10031         operand *result = IC_RESULT(ic);
10032         sym_link *ctype = operandType(IC_LEFT(ic));
10033         sym_link *rtype = operandType(IC_RIGHT(ic));
10034         operand *right = IC_RIGHT(ic);
10035         int size, offset ;
10036         
10037         FENTRY;
10038         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10039         /* if they are equivalent then do nothing */
10040         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10041                 return ;
10042         
10043         aopOp(right,ic,FALSE) ;
10044         aopOp(result,ic,FALSE);
10045         
10046         DEBUGpic14_AopType(__LINE__,NULL,right,result);
10047         
10048         /* if the result is a bit */
10049         if (AOP_TYPE(result) == AOP_CRY) {
10050         /* if the right size is a literal then
10051                 we know what the value is */
10052                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10053                 if (AOP_TYPE(right) == AOP_LIT) {
10054                         
10055                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10056                                 popGet(AOP(result),0));
10057                         
10058                         if (((int) operandLitValue(right))) 
10059                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
10060                                 AOP(result)->aopu.aop_dir,
10061                                 AOP(result)->aopu.aop_dir);
10062                         else
10063                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
10064                                 AOP(result)->aopu.aop_dir,
10065                                 AOP(result)->aopu.aop_dir);
10066                         
10067                         goto release;
10068                 }
10069                 
10070                 /* the right is also a bit variable */
10071                 if (AOP_TYPE(right) == AOP_CRY) {
10072                         
10073                         emitCLRC;
10074                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
10075                         
10076                         pic14_emitcode("clrc","");
10077                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
10078                                 AOP(right)->aopu.aop_dir,
10079                                 AOP(right)->aopu.aop_dir);
10080                         aopPut(AOP(result),"c",0);
10081                         goto release ;
10082                 }
10083                 
10084                 /* we need to or */
10085                 if (AOP_TYPE(right) == AOP_REG) {
10086                         emitpcode(POC_BCF,    popGet(AOP(result),0));
10087                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
10088                         emitpcode(POC_BSF,    popGet(AOP(result),0));
10089                 }
10090                 pic14_toBoolean(right);
10091                 aopPut(AOP(result),"a",0);
10092                 goto release ;
10093         }
10094         
10095         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10096                 int offset = 1;
10097                 size = AOP_SIZE(result);
10098                 
10099                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10100                 
10101                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
10102                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
10103                 emitpcode(POC_INCF,   popGet(AOP(result),0));
10104                 
10105                 while (size--)
10106                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
10107                 
10108                 goto release;
10109         }
10110         
10111         /* if they are the same size : or less */
10112         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10113                 
10114                 /* if they are in the same place */
10115                 if (pic14_sameRegs(AOP(right),AOP(result)))
10116                         goto release;
10117                 
10118                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10119                 if (IS_PTR_CONST(rtype))
10120                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
10121                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10122                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
10123                 
10124                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10125                         emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
10126                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
10127                         emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
10128                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
10129                         if(AOP_SIZE(result) <2)
10130                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10131                         
10132                 } else {
10133                         
10134                         /* if they in different places then copy */
10135                         size = AOP_SIZE(result);
10136                         offset = 0 ;
10137                         while (size--) {
10138                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
10139                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
10140                                 
10141                                 //aopPut(AOP(result),
10142                                 // aopGet(AOP(right),offset,FALSE,FALSE),
10143                                 // offset);
10144                                 
10145                                 offset++;
10146                         }
10147                 }
10148                 goto release;
10149         }
10150         
10151         
10152         /* if the result is of type pointer */
10153         if (IS_PTR(ctype)) {
10154                 
10155                 int p_type;
10156                 sym_link *type = operandType(right);
10157                 sym_link *etype = getSpec(type);
10158                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
10159                 
10160                 /* pointer to generic pointer */
10161                 if (IS_GENPTR(ctype)) {
10162                         char *l = zero;
10163                         
10164                         if (IS_PTR(type)) 
10165                                 p_type = DCL_TYPE(type);
10166                         else {
10167                                 /* we have to go by the storage class */
10168                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
10169                                 
10170                                 /*    if (SPEC_OCLS(etype)->codesp )  */
10171                                 /*        p_type = CPOINTER ;  */
10172                                 /*    else */
10173                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10174                                 /*      p_type = FPOINTER ; */
10175                                 /*        else */
10176                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10177                                 /*          p_type = PPOINTER; */
10178                                 /*      else */
10179                                 /*          if (SPEC_OCLS(etype) == idata ) */
10180                                 /*        p_type = IPOINTER ; */
10181                                 /*          else */
10182                                 /*        p_type = POINTER ; */
10183                         }
10184                         
10185                         /* the first two bytes are known */
10186                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
10187                         size = GPTRSIZE - 1; 
10188                         offset = 0 ;
10189                         while (size--) {
10190                                 if(offset < AOP_SIZE(right)) {
10191                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
10192                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
10193                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10194                                                 emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0));
10195                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
10196                                         } else { 
10197                                                 aopPut(AOP(result),
10198                                                         aopGet(AOP(right),offset,FALSE,FALSE),
10199                                                         offset);
10200                                         }
10201                                 } else 
10202                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
10203                                 offset++;
10204                         }
10205                         /* the last byte depending on type */
10206                         switch (p_type) {
10207                         case IPOINTER:
10208                         case POINTER:
10209                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
10210                                 break;
10211                         case FPOINTER:
10212                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
10213                                 l = one;
10214                                 break;
10215                         case CPOINTER:
10216                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
10217                                 l = "#0x02";
10218                                 break;        
10219                         case PPOINTER:
10220                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
10221                                 l = "#0x03";
10222                                 break;
10223                                 
10224                         default:
10225                                 /* this should never happen */
10226                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10227                                         "got unknown pointer type");
10228                                 exit(1);
10229                         }
10230                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
10231                         goto release ;
10232                 }
10233                 
10234                 /* just copy the pointers */
10235                 size = AOP_SIZE(result);
10236                 offset = 0 ;
10237                 while (size--) {
10238                         aopPut(AOP(result),
10239                                 aopGet(AOP(right),offset,FALSE,FALSE),
10240                                 offset);
10241                         offset++;
10242                 }
10243                 goto release ;
10244         }
10245         
10246         
10247         
10248         /* so we now know that the size of destination is greater
10249         than the size of the source.
10250         Now, if the next iCode is an operator then we might be
10251         able to optimize the operation without performing a cast.
10252         */
10253         if(genMixedOperation(ic))
10254                 goto release;
10255         
10256         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
10257         
10258         /* we move to result for the size of source */
10259         size = AOP_SIZE(right);
10260         offset = 0 ;
10261         while (size--) {
10262                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
10263                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
10264                 offset++;
10265         }
10266         
10267         /* now depending on the sign of the destination */
10268         size = AOP_SIZE(result) - AOP_SIZE(right);
10269         /* if unsigned or not an integral type */
10270         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10271                 while (size--)
10272                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
10273         } else {
10274                 /* we need to extend the sign :{ */
10275                 
10276                 if(size == 1) {
10277                         /* Save one instruction of casting char to int */
10278                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
10279                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10280                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
10281                 } else {
10282                         emitpcodeNULLop(POC_CLRW);
10283                         
10284                         if(offset)
10285                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10286                         else
10287                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10288                         
10289                         emitpcode(POC_MOVLW,   popGetLit(0xff));
10290                         
10291                         while (size--)
10292                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
10293                 }
10294         }
10295         
10296 release:
10297         freeAsmop(right,NULL,ic,TRUE);
10298         freeAsmop(result,NULL,ic,TRUE);
10299         
10300 }
10301
10302 /*-----------------------------------------------------------------*/
10303 /* genDjnz - generate decrement & jump if not zero instrucion      */
10304 /*-----------------------------------------------------------------*/
10305 static int genDjnz (iCode *ic, iCode *ifx)
10306 {
10307         symbol *lbl, *lbl1;
10308         FENTRY;
10309         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10310         
10311         if (!ifx)
10312                 return 0;
10313         
10314                 /* if the if condition has a false label
10315         then we cannot save */
10316         if (IC_FALSE(ifx))
10317                 return 0;
10318         
10319                 /* if the minus is not of the form 
10320         a = a - 1 */
10321         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10322                 !IS_OP_LITERAL(IC_RIGHT(ic)))
10323                 return 0;
10324         
10325         if (operandLitValue(IC_RIGHT(ic)) != 1)
10326                 return 0;
10327         
10328                 /* if the size of this greater than one then no
10329         saving */
10330         if (getSize(operandType(IC_RESULT(ic))) > 1)
10331                 return 0;
10332         
10333         /* otherwise we can save BIG */
10334         lbl = newiTempLabel(NULL);
10335         lbl1= newiTempLabel(NULL);
10336         
10337         aopOp(IC_RESULT(ic),ic,FALSE);
10338         
10339         if (IS_AOP_PREG(IC_RESULT(ic))) {
10340                 pic14_emitcode("dec","%s",
10341                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10342                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10343                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
10344         } else {  
10345                 
10346                 
10347                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
10348                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
10349                 
10350                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10351                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10352                 
10353         }
10354         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10355         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
10356         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10357         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
10358         
10359         
10360         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10361         ifx->generated = 1;
10362         return 1;
10363 }
10364
10365 /*-----------------------------------------------------------------*/
10366 /* genReceive - generate code for a receive iCode                  */
10367 /*-----------------------------------------------------------------*/
10368 static void genReceive (iCode *ic)
10369 {
10370         FENTRY;
10371         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10372         
10373         if (isOperandInFarSpace(IC_RESULT(ic)) &&
10374                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10375                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10376                 
10377                 int size = getSize(operandType(IC_RESULT(ic)));
10378                 int offset =  fReturnSizePic - size;
10379                 while (size--) {
10380                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
10381                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
10382                         offset++;
10383                 }
10384                 aopOp(IC_RESULT(ic),ic,FALSE);
10385                 size = AOP_SIZE(IC_RESULT(ic));
10386                 offset = 0;
10387                 while (size--) {
10388                         pic14_emitcode ("pop","acc");
10389                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10390                 }
10391                 
10392         } else {
10393                 _G.accInUse++;
10394                 aopOp(IC_RESULT(ic),ic,FALSE);
10395                 _G.accInUse--;
10396                 assignResultValue(IC_RESULT(ic));
10397         }
10398         
10399         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10400 }
10401
10402 /*-----------------------------------------------------------------*/
10403 /* genDummyRead - generate code for dummy read of volatiles        */
10404 /*-----------------------------------------------------------------*/
10405 static void
10406 genDummyRead (iCode * ic)
10407 {
10408         FENTRY;
10409         pic14_emitcode ("; genDummyRead","");
10410         pic14_emitcode ("; not implemented","");
10411         
10412         ic = ic;
10413 }
10414
10415 /*-----------------------------------------------------------------*/
10416 /* genpic14Code - generate code for pic14 based controllers        */
10417 /*-----------------------------------------------------------------*/
10418 /*
10419 * At this point, ralloc.c has gone through the iCode and attempted
10420 * to optimize in a way suitable for a PIC. Now we've got to generate
10421 * PIC instructions that correspond to the iCode.
10422 *
10423 * Once the instructions are generated, we'll pass through both the
10424 * peep hole optimizer and the pCode optimizer.
10425 *-----------------------------------------------------------------*/
10426
10427 void genpic14Code (iCode *lic)
10428 {
10429         iCode *ic;
10430         int cln = 0;
10431         const char *cline;
10432         
10433         FENTRY;
10434         lineHead = lineCurr = NULL;
10435         
10436         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
10437         addpBlock(pb);
10438         
10439         /* if debug information required */
10440         if (options.debug && currFunc) { 
10441                 if (currFunc) {
10442                         debugFile->writeFunction (currFunc, lic);
10443                 }
10444         }
10445         
10446         
10447         for (ic = lic ; ic ; ic = ic->next ) {
10448                 
10449                 //DEBUGpic14_emitcode(";ic","");
10450                 //fprintf (stderr, "in ic loop\n");
10451                 //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
10452                 //ic->lineno, printCLine(ic->filename, ic->lineno));
10453                 
10454                 if (!options.noCcodeInAsm && (cln != ic->lineno)) {
10455                   cln = ic->lineno;
10456                   //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
10457                   cline = printCLine (ic->filename, ic->lineno);
10458                   if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
10459                   addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
10460                   //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
10461                 }
10462                 
10463                 if (options.iCodeInAsm) {
10464                   emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
10465                 }
10466                 /* if the result is marked as
10467                 spilt and rematerializable or code for
10468                 this has already been generated then
10469                 do nothing */
10470                 if (resultRemat(ic) || ic->generated ) 
10471                         continue ;
10472                 
10473                 /* depending on the operation */
10474                 switch (ic->op) {
10475                 case '!' :
10476                         genNot(ic);
10477                         break;
10478                         
10479                 case '~' :
10480                         genCpl(ic);
10481                         break;
10482                         
10483                 case UNARYMINUS:
10484                         genUminus (ic);
10485                         break;
10486                         
10487                 case IPUSH:
10488                         genIpush (ic);
10489                         break;
10490                         
10491                 case IPOP:
10492                         /* IPOP happens only when trying to restore a 
10493                         spilt live range, if there is an ifx statement
10494                         following this pop then the if statement might
10495                         be using some of the registers being popped which
10496                         would destory the contents of the register so
10497                         we need to check for this condition and handle it */
10498                         if (ic->next            && 
10499                                 ic->next->op == IFX &&
10500                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10501                                 genIfx (ic->next,ic);
10502                         else
10503                                 genIpop (ic);
10504                         break; 
10505                         
10506                 case CALL:
10507                         genCall (ic);
10508                         break;
10509                         
10510                 case PCALL:
10511                         genPcall (ic);
10512                         break;
10513                         
10514                 case FUNCTION:
10515                         genFunction (ic);
10516                         break;
10517                         
10518                 case ENDFUNCTION:
10519                         genEndFunction (ic);
10520                         break;
10521                         
10522                 case RETURN:
10523                         genRet (ic);
10524                         break;
10525                         
10526                 case LABEL:
10527                         genLabel (ic);
10528                         break;
10529                         
10530                 case GOTO:
10531                         genGoto (ic);
10532                         break;
10533                         
10534                 case '+' :
10535                         genPlus (ic) ;
10536                         break;
10537                         
10538                 case '-' :
10539                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10540                                 genMinus (ic);
10541                         break;
10542                         
10543                 case '*' :
10544                         genMult (ic);
10545                         break;
10546                         
10547                 case '/' :
10548                         genDiv (ic) ;
10549                         break;
10550                         
10551                 case '%' :
10552                         genMod (ic);
10553                         break;
10554                         
10555                 case '>' :
10556                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
10557                         break;
10558                         
10559                 case '<' :
10560                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10561                         break;
10562                         
10563                 case LE_OP:
10564                 case GE_OP:
10565                 case NE_OP:
10566                         
10567                         /* note these two are xlated by algebraic equivalence
10568                         during parsing SDCC.y */
10569                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10570                                 "got '>=' or '<=' shouldn't have come here");
10571                         break;  
10572                         
10573                 case EQ_OP:
10574                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10575                         break;      
10576                         
10577                 case AND_OP:
10578                         genAndOp (ic);
10579                         break;
10580                         
10581                 case OR_OP:
10582                         genOrOp (ic);
10583                         break;
10584                         
10585                 case '^' :
10586                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10587                         break;
10588                         
10589                 case '|' :
10590                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10591                         break;
10592                         
10593                 case BITWISEAND:
10594                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10595                         break;
10596                         
10597                 case INLINEASM:
10598                         genInline (ic);
10599                         break;
10600                         
10601                 case RRC:
10602                         genRRC (ic);
10603                         break;
10604                         
10605                 case RLC:
10606                         genRLC (ic);
10607                         break;
10608                         
10609                 case GETHBIT:
10610                         genGetHbit (ic);
10611                         break;
10612                         
10613                 case LEFT_OP:
10614                         genLeftShift (ic);
10615                         break;
10616                         
10617                 case RIGHT_OP:
10618                         genRightShift (ic);
10619                         break;
10620                         
10621                 case GET_VALUE_AT_ADDRESS:
10622                         genPointerGet(ic);
10623                         break;
10624                         
10625                 case '=' :
10626                         if (POINTER_SET(ic))
10627                                 genPointerSet(ic);
10628                         else
10629                                 genAssign(ic);
10630                         break;
10631                         
10632                 case IFX:
10633                         genIfx (ic,NULL);
10634                         break;
10635                         
10636                 case ADDRESS_OF:
10637                         genAddrOf (ic);
10638                         break;
10639                         
10640                 case JUMPTABLE:
10641                         genJumpTab (ic);
10642                         break;
10643                         
10644                 case CAST:
10645                         genCast (ic);
10646                         break;
10647                         
10648                 case RECEIVE:
10649                         genReceive(ic);
10650                         break;
10651                         
10652                 case SEND:
10653                         addSet(&_G.sendSet,ic);
10654                         break;
10655                         
10656                 case DUMMY_READ_VOLATILE:
10657                         genDummyRead (ic);
10658                         break;
10659                         
10660                 default :
10661                         ic = ic;
10662                 }
10663         }
10664
10665         
10666         /* now we are ready to call the
10667         peep hole optimizer */
10668         if (!options.nopeep) {
10669                 peepHole (&lineHead);
10670         }
10671         /* now do the actual printing */
10672         printLine (lineHead,codeOutFile);
10673         
10674 #ifdef PCODE_DEBUG
10675         DFPRINTF((stderr,"printing pBlock\n\n"));
10676         printpBlock(stdout,pb);
10677 #endif
10678         
10679         return;
10680 }
10681
10682 int
10683 aop_isLitLike (asmop *aop)
10684 {
10685   assert (aop);
10686   if (aop->type == AOP_LIT) return 1;
10687   if (aop->type == AOP_IMMD) return 1;
10688   if ((aop->type == AOP_PCODE) &&
10689                 ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE)))
10690   {
10691     /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
10692      * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
10693     return 1;
10694   }
10695   return 0;
10696 }
10697
10698 int
10699 op_isLitLike (operand *op)
10700 {
10701   assert (op);
10702   if (aop_isLitLike (AOP(op))) return 1;
10703   return 0;
10704 }