c85d097f1eb5c2d2303276e3fa37c1ebe57c5bf8
[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 (sym->accuse) {
857                         int i;
858                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
859                         aop->size = getSize(sym->type);
860                         for ( i = 0 ; i < 2 ; i++ )
861                                 aop->aopu.aop_str[i] = accUse[i];
862                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
863                         return;  
864                 }
865                 
866                 if (sym->ruonly ) {
867                         if(sym->isptr) {        // && sym->uptr 
868                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
869                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
870                                 
871                                 //PCOI(aop->aopu.pcop)->_const = 0;
872                                 //PCOI(aop->aopu.pcop)->index = 0;
873                                 /*
874                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
875                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
876                                 */
877                                 //allocDirReg (IC_LEFT(ic));
878                                 
879                                 aop->size = getSize(sym->type);
880                                 DEBUGpic14_emitcode(";","%d",__LINE__);
881                                 return;
882                                 
883                         } else {
884                                 
885                                 unsigned i;
886                                 
887                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
888                                 aop->size = getSize(sym->type);
889                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
890                                         aop->aopu.aop_str[i] = fReturn[i];
891                                 
892                                 DEBUGpic14_emitcode(";","%d",__LINE__);
893                                 return;
894                         }
895                 }
896                 
897                 /* else spill location  */
898                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
899                         /* force a new aop if sizes differ */
900                         sym->usl.spillLoc->aop = NULL;
901                 }
902                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
903                         __FUNCTION__,__LINE__,
904                         sym->usl.spillLoc->rname,
905                         sym->rname, sym->usl.spillLoc->offset);
906                 
907                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
908                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
909                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
910                         getSize(sym->type), 
911                         sym->usl.spillLoc->offset);
912                 aop->size = getSize(sym->type);
913                 
914                 return;
915         }
916         
917         {
918                 sym_link *type = operandType(op);
919                 if(IS_PTR_CONST(type)) 
920                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
921         }
922         
923         /* must be in a register */
924         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
925         sym->aop = op->aop = aop = newAsmop(AOP_REG);
926         aop->size = sym->nRegs;
927         for ( i = 0 ; i < sym->nRegs ;i++)
928                 aop->aopu.aop_reg[i] = sym->regs[i];
929 }
930
931 /*-----------------------------------------------------------------*/
932 /* freeAsmop - free up the asmop given to an operand                       */
933 /*----------------------------------------------------------------*/
934 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
935 {       
936         asmop *aop ;
937         
938         if (!op)
939                 aop = aaop;
940         else 
941                 aop = op->aop;
942         
943         if (!aop)
944                 return ;
945         
946         if (aop->freed)
947                 goto dealloc; 
948         
949         aop->freed = 1;
950         
951         /* depending on the asmop type only three cases need work AOP_RO
952         , AOP_R1 && AOP_STK */
953 #if 0
954         switch (aop->type) {
955         case AOP_R0 :
956                 if (_G.r0Pushed ) {
957                         if (pop) {
958                                 pic14_emitcode ("pop","ar0");     
959                                 _G.r0Pushed--;
960                         }
961                 }
962                 bitVectUnSetBit(ic->rUsed,R0_IDX);
963                 break;
964                 
965         case AOP_R1 :
966                 if (_G.r1Pushed ) {
967                         if (pop) {
968                                 pic14_emitcode ("pop","ar1");
969                                 _G.r1Pushed--;
970                         }
971                 }
972                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
973                 break;
974                 
975         case AOP_STK :
976                 {
977                         int sz = aop->size;      
978                         int stk = aop->aopu.aop_stk + aop->size;
979                         bitVectUnSetBit(ic->rUsed,R0_IDX);
980                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
981                         
982                         getFreePtr(ic,&aop,FALSE);
983                         
984                         if (options.stack10bit)
985                         {
986                                 /* I'm not sure what to do here yet... */
987                                 /* #STUB */
988                                 fprintf(stderr, 
989                                         "*** Warning: probably generating bad code for "
990                                         "10 bit stack mode.\n");
991                         }
992                         
993                         if (stk) {
994                                 pic14_emitcode ("mov","a,_bp");
995                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
996                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
997                         } else {
998                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
999                         }
1000                         
1001                         while (sz--) {
1002                                 pic14_emitcode("pop","acc");
1003                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1004                                 if (!sz) break;
1005                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1006                         }
1007                         op->aop = aop;
1008                         freeAsmop(op,NULL,ic,TRUE);
1009                         if (_G.r0Pushed) {
1010                                 pic14_emitcode("pop","ar0");
1011                                 _G.r0Pushed--;
1012                         }
1013                         
1014                         if (_G.r1Pushed) {
1015                                 pic14_emitcode("pop","ar1");
1016                                 _G.r1Pushed--;
1017                         }         
1018                 }
1019         }
1020 #endif
1021         
1022 dealloc:
1023         /* all other cases just dealloc */
1024         if (op ) {
1025                 op->aop = NULL;
1026                 if (IS_SYMOP(op)) {
1027                         OP_SYMBOL(op)->aop = NULL;      
1028                         /* if the symbol has a spill */
1029                         if (SPIL_LOC(op))
1030                                 SPIL_LOC(op)->aop = NULL;
1031                 }
1032         }
1033 }
1034
1035 /*-----------------------------------------------------------------*/
1036 /* aopGet - for fetching value of the aop                                                  */
1037 /*-----------------------------------------------------------------*/
1038 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1039 {
1040         char *s = buffer ;
1041         char *rs;
1042         
1043         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1044         /* offset is greater than
1045         size then zero */
1046         if (offset > (aop->size - 1) &&
1047                 aop->type != AOP_LIT)
1048                 return zero;
1049         
1050         /* depending on type */
1051         switch (aop->type) {
1052                 
1053         case AOP_R0:
1054         case AOP_R1:
1055                 DEBUGpic14_emitcode(";","%d",__LINE__);
1056                 /* if we need to increment it */           
1057                 while (offset > aop->coff) {            
1058                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1059                         aop->coff++;
1060                 }
1061                 
1062                 while (offset < aop->coff) {
1063                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1064                         aop->coff--;
1065                 }
1066                 
1067                 aop->coff = offset ;
1068                 if (aop->paged) {
1069                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1070                         return (dname ? "acc" : "a");
1071                 }               
1072                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1073                 rs = Safe_calloc(1,strlen(s)+1);
1074                 strcpy(rs,s);   
1075                 return rs;
1076                 
1077         case AOP_DPTR:
1078         case AOP_DPTR2:
1079                 DEBUGpic14_emitcode(";","%d",__LINE__);
1080                 if (aop->type == AOP_DPTR2)
1081                 {
1082                         genSetDPTR(1);
1083                 }
1084                 
1085                 while (offset > aop->coff) {
1086                         pic14_emitcode ("inc","dptr");
1087                         aop->coff++;
1088                 }
1089                 
1090                 while (offset < aop->coff) {            
1091                         pic14_emitcode("lcall","__decdptr");
1092                         aop->coff--;
1093                 }
1094                 
1095                 aop->coff = offset;
1096                 if (aop->code) {
1097                         pic14_emitcode("clr","a");
1098                         pic14_emitcode("movc","a,@a+dptr");
1099                 }
1100                 else {
1101                         pic14_emitcode("movx","a,@dptr");
1102                 }
1103                 
1104                 if (aop->type == AOP_DPTR2)
1105                 {
1106                         genSetDPTR(0);
1107                 }
1108                 
1109                 return (dname ? "acc" : "a");
1110                 
1111                 
1112         case AOP_IMMD:
1113                 if (bit16) 
1114                         sprintf (s,"%s",aop->aopu.aop_immd);
1115                 else
1116                         if (offset) 
1117                                 sprintf(s,"(%s >> %d)",
1118                                 aop->aopu.aop_immd,
1119                                 offset*8);
1120                         else
1121                                 sprintf(s,"%s",
1122                                 aop->aopu.aop_immd);
1123                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1124                         rs = Safe_calloc(1,strlen(s)+1);
1125                         strcpy(rs,s);   
1126                         return rs;
1127                         
1128         case AOP_DIR:
1129                 if (offset) {
1130                         sprintf(s,"(%s + %d)",
1131                                 aop->aopu.aop_dir,
1132                                 offset);
1133                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1134                 } else
1135                         sprintf(s,"%s",aop->aopu.aop_dir);
1136                 rs = Safe_calloc(1,strlen(s)+1);
1137                 strcpy(rs,s);   
1138                 return rs;
1139                 
1140         case AOP_REG:
1141                 //if (dname) 
1142                 //        return aop->aopu.aop_reg[offset]->dname;
1143                 //else
1144                 return aop->aopu.aop_reg[offset]->name;
1145                 
1146         case AOP_CRY:
1147                 //pic14_emitcode(";","%d",__LINE__);
1148                 return aop->aopu.aop_dir;
1149                 
1150         case AOP_ACC:
1151                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1152                 return "AOP_accumulator_bug";
1153                 
1154         case AOP_LIT:
1155                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1156                 rs = Safe_calloc(1,strlen(s)+1);
1157                 strcpy(rs,s);   
1158                 return rs;
1159                 
1160         case AOP_STR:
1161                 aop->coff = offset ;
1162                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1163                         dname)
1164                         return "acc";
1165                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1166                 
1167                 return aop->aopu.aop_str[offset];
1168                 
1169         case AOP_PCODE:
1170                 {
1171                         pCodeOp *pcop = aop->aopu.pcop;
1172                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1173                         if(pcop->name) {
1174                                 if (offset) {
1175                                         DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1176                                         sprintf(s,"(%s+%d)", pcop->name,offset);
1177                                 } else {
1178                                         DEBUGpic14_emitcode(";","%s",pcop->name);
1179                                         sprintf(s,"%s", pcop->name);
1180                                 }
1181                         } else
1182                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1183                         
1184                 }
1185                 rs = Safe_calloc(1,strlen(s)+1);
1186                 strcpy(rs,s);   
1187                 return rs;
1188                 
1189   }
1190   
1191   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1192           "aopget got unsupported aop->type");
1193   exit(0);
1194 }
1195
1196
1197 /*-----------------------------------------------------------------*/
1198 /* popGetTempReg - create a new temporary pCodeOp                                  */
1199 /*-----------------------------------------------------------------*/
1200 pCodeOp *popGetTempReg(void)
1201 {
1202         
1203         pCodeOp *pcop;
1204         
1205         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1206         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1207                 PCOR(pcop)->r->wasUsed=1;
1208                 PCOR(pcop)->r->isFree=0;
1209         }
1210         
1211         return pcop;
1212 }
1213
1214 /*-----------------------------------------------------------------*/
1215 /* popReleaseTempReg - create a new temporary pCodeOp                              */
1216 /*-----------------------------------------------------------------*/
1217 void popReleaseTempReg(pCodeOp *pcop)
1218 {
1219         
1220         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1221                 PCOR(pcop)->r->isFree = 1;
1222         
1223 }
1224 /*-----------------------------------------------------------------*/
1225 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetLabel(unsigned int key)
1228 {
1229         
1230         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1231         
1232         if(key>(unsigned int)max_key)
1233                 max_key = key;
1234         
1235         return newpCodeOpLabel(NULL,key+100+labelOffset);
1236 }
1237
1238 /*-------------------------------------------------------------------*/
1239 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1240 /*-------------------------------------------------------------------*/
1241 pCodeOp *popGetHighLabel(unsigned int key)
1242 {
1243         pCodeOp *pcop;
1244         pcop = popGetLabel(key);
1245         PCOLAB(pcop)->offset = 1;
1246         return pcop;
1247 }
1248
1249 /*-----------------------------------------------------------------*/
1250 /* popGetLit - asm operator to pcode operator conversion                           */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popGetLit(unsigned int lit)
1253 {
1254         
1255         return newpCodeOpLit(lit);
1256 }
1257
1258 /*-----------------------------------------------------------------*/
1259 /* popGetImmd - asm operator to pcode immediate conversion                 */
1260 /*-----------------------------------------------------------------*/
1261 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1262 {
1263         
1264         return newpCodeOpImmd(name, offset,index, 0, is_func);
1265 }
1266
1267
1268 /*-----------------------------------------------------------------*/
1269 /* popGetWithString - asm operator to pcode operator conversion                    */
1270 /*-----------------------------------------------------------------*/
1271 pCodeOp *popGetWithString(char *str, int isExtern)
1272 {
1273         pCodeOp *pcop;
1274         
1275         
1276         if(!str) {
1277                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1278                 exit (1);
1279         }
1280         
1281         pcop = newpCodeOp(str,PO_STR);
1282         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1283         
1284         return pcop;
1285 }
1286
1287 /*-----------------------------------------------------------------*/
1288 /* popRegFromString -                                                                                      */
1289 /*-----------------------------------------------------------------*/
1290 pCodeOp *popRegFromString(char *str, int size, int offset)
1291 {
1292         
1293         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1294         pcop->type = PO_DIR;
1295         
1296         DEBUGpic14_emitcode(";","%d",__LINE__);
1297         
1298         if(!str)
1299                 str = "BAD_STRING";
1300         
1301         pcop->name = Safe_calloc(1,strlen(str)+1);
1302         strcpy(pcop->name,str);
1303         
1304         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1305         
1306         PCOR(pcop)->r = dirregWithName(pcop->name);
1307         if(PCOR(pcop)->r == NULL) {
1308                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1309                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1310                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1311         } else {
1312                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1313         }
1314         PCOR(pcop)->instance = offset;
1315         
1316         return pcop;
1317 }
1318
1319 /*-----------------------------------------------------------------*/
1320 /*-----------------------------------------------------------------*/
1321 pCodeOp *popRegFromIdx(int rIdx)
1322 {
1323         pCodeOp *pcop;
1324         
1325         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1326                 __FUNCTION__,__LINE__,rIdx);
1327         
1328         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1329         
1330         PCOR(pcop)->rIdx = rIdx;
1331         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1332         PCOR(pcop)->r->isFree = 0;
1333         PCOR(pcop)->r->wasUsed = 1;
1334         
1335         pcop->type = PCOR(pcop)->r->pc_type;
1336         
1337         
1338         return pcop;
1339 }
1340
1341 /*-----------------------------------------------------------------*/
1342 /* popGet - asm operator to pcode operator conversion                      */
1343 /*-----------------------------------------------------------------*/
1344 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1345 {
1346         //char *s = buffer ;
1347         //char *rs;
1348         
1349         pCodeOp *pcop;
1350         
1351         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1352         /* offset is greater than
1353         size then zero */
1354
1355         assert (offset >= 0 && offset < aop->size);
1356         
1357         if (offset > (aop->size - 1) &&
1358                 aop->type != AOP_LIT)
1359                 return NULL;  //zero;
1360         
1361         /* depending on type */
1362         switch (aop->type) {
1363                 
1364         case AOP_R0:
1365         case AOP_R1:
1366         case AOP_DPTR:
1367         case AOP_DPTR2:
1368         case AOP_ACC:
1369                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1370                 return NULL;
1371                 
1372         case AOP_IMMD:
1373                 DEBUGpic14_emitcode(";","%d",__LINE__);
1374                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1375                 
1376         case AOP_DIR:
1377                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1378 #if 0
1379                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1380                 pcop->type = PO_DIR;
1381                 
1382                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1383                 strcpy(pcop->name,aop->aopu.aop_dir);   
1384                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1385                 if(PCOR(pcop)->r == NULL) {
1386                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1387                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1388                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1389                 } else {
1390                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1391                 }
1392                 PCOR(pcop)->instance = offset;
1393                 
1394                 return pcop;
1395 #endif
1396                 
1397         case AOP_REG:
1398                 {
1399                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1400                         
1401                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402                         PCOR(pcop)->rIdx = rIdx;
1403                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1404                         PCOR(pcop)->r->wasUsed=1;
1405                         PCOR(pcop)->r->isFree=0;
1406                         
1407                         PCOR(pcop)->instance = offset;
1408                         pcop->type = PCOR(pcop)->r->pc_type;
1409                         //rs = aop->aopu.aop_reg[offset]->name;
1410                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1411                         return pcop;
1412                 }
1413                 
1414         case AOP_CRY:
1415                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1416                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1417                 //if(PCOR(pcop)->r == NULL)
1418                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1419                 return pcop;
1420                 
1421         case AOP_LIT:
1422                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1423                 
1424         case AOP_STR:
1425                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1426                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1427                 /*
1428                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1429                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1430                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1431                 pcop->type = PCOR(pcop)->r->pc_type;
1432                 pcop->name = PCOR(pcop)->r->name;
1433                 
1434                   return pcop;
1435                 */
1436                 
1437         case AOP_PCODE:
1438                 pcop = NULL;
1439                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
1440                         __LINE__, 
1441                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1442                 emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, offset);
1443                 switch (aop->aopu.pcop->type)
1444                 {
1445                 case PO_IMMEDIATE:
1446                   pcop = pCodeOpCopy (aop->aopu.pcop);
1447                   /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1448                    * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1449                   PCOI(pcop)->index += offset;
1450                   //PCOI(pcop)->offset = 0;
1451                   break;
1452                 case PO_DIR:
1453                   pcop = pCodeOpCopy (aop->aopu.pcop);
1454                   PCOR(pcop)->instance = offset;
1455                   break;
1456                 default:
1457                   assert ( !"unhandled pCode type" );
1458                   break;
1459                 } // switch
1460                 return pcop;
1461         }
1462         
1463         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1464                 "popGet got unsupported aop->type");
1465         exit(0);
1466 }
1467
1468 /*-----------------------------------------------------------------*/
1469 /* popGetAddr - access the low/high word of a symbol (immediate)   */
1470 /*              (for non-PO_IMMEDIATEs this is the same as poGet)  */
1471 /*-----------------------------------------------------------------*/
1472 pCodeOp *popGetAddr (asmop *aop, int offset)
1473 {
1474   if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
1475   {
1476     pCodeOp *pcop = aop->aopu.pcop;
1477     emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset);
1478     pcop = pCodeOpCopy (pcop);
1479     /* usually we want to access the memory at "<symbol> + offset" (using ->index),
1480      * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
1481     PCOI(pcop)->offset += offset;
1482     return pcop;
1483   } else {
1484     return popGet (aop, offset);
1485   }
1486 }
1487
1488 /*-----------------------------------------------------------------*/
1489 /* aopPut - puts a string for a aop                                                        */
1490 /*-----------------------------------------------------------------*/
1491 void aopPut (asmop *aop, char *s, int offset)
1492 {
1493         char *d = buffer ;
1494         symbol *lbl ;
1495         
1496         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1497         
1498         if (aop->size && offset > ( aop->size - 1)) {
1499                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1500                         "aopPut got offset > aop->size");
1501                 exit(0);
1502         }
1503         
1504         /* will assign value to value */
1505         /* depending on where it is ofcourse */
1506         switch (aop->type) {
1507         case AOP_DIR:
1508                 if (offset) {
1509                         sprintf(d,"(%s + %d)",
1510                                 aop->aopu.aop_dir,offset);
1511                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1512                         
1513                 } else
1514                         sprintf(d,"%s",aop->aopu.aop_dir);
1515                 
1516                 if (strcmp(d,s)) {
1517                         DEBUGpic14_emitcode(";","%d",__LINE__);
1518                         if(strcmp(s,"W"))
1519                                 pic14_emitcode("movf","%s,w",s);
1520                         pic14_emitcode("movwf","%s",d);
1521                         
1522                         if(strcmp(s,"W")) {
1523                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1524                                 if(offset >= aop->size) {
1525                                         emitpcode(POC_CLRF,popGet(aop,offset));
1526                                         break;
1527                                 } else
1528                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1529                         }
1530                         
1531                         emitpcode(POC_MOVWF,popGet(aop,offset));
1532                         
1533                         
1534                 }
1535                 break;
1536                 
1537         case AOP_REG:
1538                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1539                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1540                         /*
1541                         if (*s == '@'             ||
1542                         strcmp(s,"r0") == 0 ||
1543                         strcmp(s,"r1") == 0 ||
1544                         strcmp(s,"r2") == 0 ||
1545                         strcmp(s,"r3") == 0 ||
1546                         strcmp(s,"r4") == 0 ||
1547                         strcmp(s,"r5") == 0 ||
1548                         strcmp(s,"r6") == 0 || 
1549                         strcmp(s,"r7") == 0 )
1550                         pic14_emitcode("mov","%s,%s  ; %d",
1551                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1552                         else
1553                         */
1554                         
1555                         if(strcmp(s,"W")==0 )
1556                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1557                         
1558                         pic14_emitcode("movwf","%s",
1559                                 aop->aopu.aop_reg[offset]->name);
1560                         
1561                         if(strcmp(s,zero)==0) {
1562                                 emitpcode(POC_CLRF,popGet(aop,offset));
1563                                 
1564                         } else if(strcmp(s,"W")==0) {
1565                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1566                                 pcop->type = PO_GPR_REGISTER;
1567                                 
1568                                 PCOR(pcop)->rIdx = -1;
1569                                 PCOR(pcop)->r = NULL;
1570                                 
1571                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1572                                 pcop->name = Safe_strdup(s);
1573                                 emitpcode(POC_MOVFW,pcop);
1574                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1575                         } else if(strcmp(s,one)==0) {
1576                                 emitpcode(POC_CLRF,popGet(aop,offset));
1577                                 emitpcode(POC_INCF,popGet(aop,offset));
1578                         } else {
1579                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1580                         }
1581                 }
1582                 break;
1583                 
1584         case AOP_DPTR:
1585         case AOP_DPTR2:
1586                 
1587                 if (aop->type == AOP_DPTR2)
1588                 {
1589                         genSetDPTR(1);
1590                 }
1591                 
1592                 if (aop->code) {
1593                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1594                                 "aopPut writting to code space");
1595                         exit(0);
1596                 }
1597                 
1598                 while (offset > aop->coff) {
1599                         aop->coff++;
1600                         pic14_emitcode ("inc","dptr");
1601                 }
1602                 
1603                 while (offset < aop->coff) {
1604                         aop->coff-- ;
1605                         pic14_emitcode("lcall","__decdptr");
1606                 }
1607                 
1608                 aop->coff = offset;
1609                 
1610                 /* if not in accumulater */
1611                 MOVA(s);
1612                 
1613                 pic14_emitcode ("movx","@dptr,a");
1614                 
1615                 if (aop->type == AOP_DPTR2)
1616                 {
1617                         genSetDPTR(0);
1618                 }
1619                 break;
1620                 
1621         case AOP_R0:
1622         case AOP_R1:
1623                 while (offset > aop->coff) {
1624                         aop->coff++;
1625                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1626                 }
1627                 while (offset < aop->coff) {
1628                         aop->coff-- ;
1629                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1630                 }
1631                 aop->coff = offset;
1632                 
1633                 if (aop->paged) {
1634                         MOVA(s);                         
1635                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1636                         
1637                 } else
1638                         if (*s == '@') {
1639                                 MOVA(s);
1640                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1641                         } else
1642                                 if (strcmp(s,"r0") == 0 ||
1643                                         strcmp(s,"r1") == 0 ||
1644                                         strcmp(s,"r2") == 0 ||
1645                                         strcmp(s,"r3") == 0 ||
1646                                         strcmp(s,"r4") == 0 ||
1647                                         strcmp(s,"r5") == 0 ||
1648                                         strcmp(s,"r6") == 0 || 
1649                                         strcmp(s,"r7") == 0 ) {
1650                                         char buffer[10];
1651                                         sprintf(buffer,"a%s",s);
1652                                         pic14_emitcode("mov","@%s,%s",
1653                                                 aop->aopu.aop_ptr->name,buffer);
1654                                 } else
1655                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1656                                 
1657                                 break;
1658                                 
1659         case AOP_STK:
1660                 if (strcmp(s,"a") == 0)
1661                         pic14_emitcode("push","acc");
1662                 else
1663                         pic14_emitcode("push","%s",s);
1664                 
1665                 break;
1666                 
1667         case AOP_CRY:
1668                 /* if bit variable */
1669                 if (!aop->aopu.aop_dir) {
1670                         pic14_emitcode("clr","a");
1671                         pic14_emitcode("rlc","a");
1672                 } else {
1673                         if (s == zero) 
1674                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1675                         else
1676                                 if (s == one)
1677                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1678                                 else
1679                                         if (!strcmp(s,"c"))
1680                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1681                                         else {
1682                                                 lbl = newiTempLabel(NULL);
1683                                                 
1684                                                 if (strcmp(s,"a")) {
1685                                                         MOVA(s);
1686                                                 }
1687                                                 pic14_emitcode("clr","c");
1688                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1689                                                 pic14_emitcode("cpl","c");
1690                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1691                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1692                                         }
1693                 }
1694                 break;
1695                 
1696         case AOP_STR:
1697                 aop->coff = offset;
1698                 if (strcmp(aop->aopu.aop_str[offset],s))
1699                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1700                 break;
1701                 
1702         case AOP_ACC:
1703                 aop->coff = offset;
1704                 if (!offset && (strcmp(s,"acc") == 0))
1705                         break;
1706                 
1707                 if (strcmp(aop->aopu.aop_str[offset],s))
1708                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1709                 break;
1710                 
1711         default :
1712                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1713                         "aopPut got unsupported aop->type");
1714                 exit(0);
1715         }
1716         
1717 }
1718
1719 /*-----------------------------------------------------------------*/
1720 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1721 /*-----------------------------------------------------------------*/
1722 void mov2w (asmop *aop, int offset)
1723 {
1724         
1725         if(!aop)
1726                 return;
1727         
1728         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1729         
1730         if ( aop->type == AOP_PCODE ||
1731                 aop->type == AOP_LIT ||
1732                 aop->type == AOP_IMMD )
1733                 emitpcode(POC_MOVLW,popGet(aop,offset));
1734         else
1735                 emitpcode(POC_MOVFW,popGet(aop,offset));
1736         
1737 }
1738
1739 /*-----------------------------------------------------------------*/
1740 /* reAdjustPreg - points a register back to where it should        */
1741 /*-----------------------------------------------------------------*/
1742 static void reAdjustPreg (asmop *aop)
1743 {
1744         int size ;
1745         
1746         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1747         aop->coff = 0;
1748         if ((size = aop->size) <= 1)
1749                 return ;
1750         size-- ;
1751         switch (aop->type) {
1752         case AOP_R0 :
1753         case AOP_R1 :
1754                 while (size--)
1755                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1756                 break;                  
1757         case AOP_DPTR :
1758         case AOP_DPTR2:
1759                 if (aop->type == AOP_DPTR2)
1760                 {
1761                         genSetDPTR(1);
1762                 } 
1763                 while (size--)
1764                 {
1765                         pic14_emitcode("lcall","__decdptr");
1766                 }
1767                 
1768                 if (aop->type == AOP_DPTR2)
1769                 {
1770                         genSetDPTR(0);
1771                 }
1772                 break;
1773                 
1774         }
1775         
1776 }
1777
1778
1779 #if 0
1780 /*-----------------------------------------------------------------*/
1781 /* opIsGptr: returns non-zero if the passed operand is             */
1782 /* a generic pointer type.                                         */
1783 /*-----------------------------------------------------------------*/ 
1784 static int opIsGptr(operand *op)
1785 {
1786         sym_link *type = operandType(op);
1787         
1788         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1789         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1790         {
1791                 return 1;
1792         }
1793         return 0;          
1794 }
1795 #endif
1796
1797 /*-----------------------------------------------------------------*/
1798 /* pic14_getDataSize - get the operand data size                   */
1799 /*-----------------------------------------------------------------*/
1800 int pic14_getDataSize(operand *op)
1801 {
1802         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1803         
1804         
1805         return AOP_SIZE(op);
1806         
1807         // tsd- in the pic port, the genptr size is 1, so this code here
1808         // fails. ( in the 8051 port, the size was 4).
1809 #if 0
1810         int size;
1811         size = AOP_SIZE(op);
1812         if (size == GPTRSIZE)
1813         {
1814                 sym_link *type = operandType(op);
1815                 if (IS_GENPTR(type))
1816                 {
1817                         /* generic pointer; arithmetic operations
1818                         * should ignore the high byte (pointer type).
1819                         */
1820                         size--;
1821                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1822                 }
1823         }
1824         return size;
1825 #endif
1826 }
1827
1828 /*-----------------------------------------------------------------*/
1829 /* pic14_outAcc - output Acc                                       */
1830 /*-----------------------------------------------------------------*/
1831 void pic14_outAcc(operand *result)
1832 {
1833         int size,offset;
1834         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1835         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1836         
1837         
1838         size = pic14_getDataSize(result);
1839         if(size){
1840                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1841                 size--;
1842                 offset = 1;
1843                 /* unsigned or positive */
1844                 while(size--)
1845                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1846         }
1847         
1848 }
1849
1850 /*-----------------------------------------------------------------*/
1851 /* pic14_outBitC - output a bit C                                  */
1852 /*-----------------------------------------------------------------*/
1853 void pic14_outBitC(operand *result)
1854 {
1855         
1856         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1857         /* if the result is bit */
1858         if (AOP_TYPE(result) == AOP_CRY) 
1859                 aopPut(AOP(result),"c",0);
1860         else {
1861                 pic14_emitcode("clr","a  ; %d", __LINE__);
1862                 pic14_emitcode("rlc","a");
1863                 pic14_outAcc(result);
1864         }
1865 }
1866
1867 /*-----------------------------------------------------------------*/
1868 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1869 /*-----------------------------------------------------------------*/
1870 void pic14_toBoolean(operand *oper)
1871 {
1872         int size = AOP_SIZE(oper) - 1;
1873         int offset = 1;
1874         
1875         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1876         
1877         if ( AOP_TYPE(oper) != AOP_ACC) {
1878                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1879         }
1880         while (size--) {
1881                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1882         }
1883 }
1884
1885
1886 /*-----------------------------------------------------------------*/
1887 /* genNot - generate code for ! operation                          */
1888 /*-----------------------------------------------------------------*/
1889 static void genNot (iCode *ic)
1890 {
1891         symbol *tlbl;
1892         int size;
1893
1894         FENTRY;
1895         
1896         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1897         /* assign asmOps to operand & result */
1898         aopOp (IC_LEFT(ic),ic,FALSE);
1899         aopOp (IC_RESULT(ic),ic,TRUE);
1900         
1901         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1902         /* if in bit space then a special case */
1903         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1904                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1905                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1906                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1907                 } else {
1908                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1909                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1910                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1911                 }
1912                 goto release;
1913         }
1914         
1915         size = AOP_SIZE(IC_LEFT(ic));
1916         if(size == 1) {
1917                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1918                 emitpcode(POC_ANDLW,popGetLit(1));
1919                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1920                 goto release;
1921         }
1922         pic14_toBoolean(IC_LEFT(ic));
1923         
1924         tlbl = newiTempLabel(NULL);
1925         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1926         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1927         pic14_outBitC(IC_RESULT(ic));
1928         
1929 release:        
1930         /* release the aops */
1931         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1932         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1933 }
1934
1935
1936 /*-----------------------------------------------------------------*/
1937 /* genCpl - generate code for complement                                                   */
1938 /*-----------------------------------------------------------------*/
1939 static void genCpl (iCode *ic)
1940 {
1941         operand *left, *result;
1942         int size, offset=0;  
1943         
1944         FENTRY;
1945         
1946         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1947         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1948         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1949         
1950         /* if both are in bit space then 
1951         a special case */
1952         if (AOP_TYPE(result) == AOP_CRY &&
1953                 AOP_TYPE(left) == AOP_CRY ) { 
1954                 
1955                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1956                 pic14_emitcode("cpl","c"); 
1957                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1958                 goto release; 
1959         } 
1960         
1961         size = AOP_SIZE(result);
1962         while (size--) {
1963                 
1964                 if(AOP_TYPE(left) == AOP_ACC) 
1965                         emitpcode(POC_XORLW, popGetLit(0xff));
1966                 else
1967                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1968                 
1969                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1970                 offset++;
1971         }
1972         
1973         
1974 release:
1975         /* release the aops */
1976         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1977         freeAsmop(result,NULL,ic,TRUE);
1978 }
1979
1980 /*-----------------------------------------------------------------*/
1981 /* genUminusFloat - unary minus for floating points                        */
1982 /*-----------------------------------------------------------------*/
1983 static void genUminusFloat(operand *op,operand *result)
1984 {
1985         int size ,offset =0 ;
1986         char *l;
1987         
1988         FENTRY;
1989
1990         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1991         /* for this we just need to flip the 
1992         first it then copy the rest in place */
1993         size = AOP_SIZE(op) - 1;
1994         l = aopGet(AOP(op),3,FALSE,FALSE);
1995         
1996         MOVA(l);          
1997         
1998         pic14_emitcode("cpl","acc.7");
1999         aopPut(AOP(result),"a",3);      
2000         
2001         while(size--) {
2002                 aopPut(AOP(result),
2003                         aopGet(AOP(op),offset,FALSE,FALSE),
2004                         offset);
2005                 offset++;
2006         }                
2007 }
2008
2009 /*-----------------------------------------------------------------*/
2010 /* genUminus - unary minus code generation                                                 */
2011 /*-----------------------------------------------------------------*/
2012 static void genUminus (iCode *ic)
2013 {
2014         int size, i;
2015         sym_link *optype, *rtype;
2016         
2017         FENTRY;
2018         
2019         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2020         /* assign asmops */
2021         aopOp(IC_LEFT(ic),ic,FALSE);
2022         aopOp(IC_RESULT(ic),ic,TRUE);
2023         
2024         /* if both in bit space then special
2025         case */
2026         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2027                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
2028                 
2029                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
2030                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2031                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
2032                 
2033                 goto release; 
2034         } 
2035         
2036         optype = operandType(IC_LEFT(ic));
2037         rtype = operandType(IC_RESULT(ic));
2038         
2039         /* if float then do float stuff */
2040         if (IS_FLOAT(optype)) {
2041                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2042                 goto release;
2043         }
2044         
2045         /* otherwise subtract from zero by taking the 2's complement */
2046         size = AOP_SIZE(IC_LEFT(ic));
2047         
2048         for(i=0; i<size; i++) {
2049                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2050                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2051                 else {
2052                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2053                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2054                 }
2055         }
2056         
2057         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2058         for(i=1; i<size; i++) {
2059                 emitSKPNZ;
2060                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2061         }
2062         
2063 release:
2064         /* release the aops */
2065         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2066         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
2067 }
2068
2069 /*-----------------------------------------------------------------*/
2070 /* saveRegisters - will look for a call and save the registers     */
2071 /*-----------------------------------------------------------------*/
2072 static void saveRegisters(iCode *lic) 
2073 {
2074         int i;
2075         iCode *ic;
2076         bitVect *rsave;
2077         sym_link *dtype;
2078         
2079         FENTRY;
2080
2081         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2082         /* look for call */
2083         for (ic = lic ; ic ; ic = ic->next) 
2084                 if (ic->op == CALL || ic->op == PCALL)
2085                         break;
2086                 
2087                 if (!ic) {
2088                         fprintf(stderr,"found parameter push with no function call\n");
2089                         return ;
2090                 }
2091                 
2092                 /* if the registers have been saved already then
2093                 do nothing */
2094                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2095                         return ;
2096                 
2097                         /* find the registers in use at this time 
2098                 and push them away to safety */
2099                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2100                         ic->rUsed);
2101                 
2102                 ic->regsSaved = 1;
2103                 if (options.useXstack) {
2104                         if (bitVectBitValue(rsave,R0_IDX))
2105                                 pic14_emitcode("mov","b,r0");
2106                         pic14_emitcode("mov","r0,%s",spname);
2107                         for (i = 0 ; i < pic14_nRegs ; i++) {
2108                                 if (bitVectBitValue(rsave,i)) {
2109                                         if (i == R0_IDX)
2110                                                 pic14_emitcode("mov","a,b");
2111                                         else
2112                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2113                                         pic14_emitcode("movx","@r0,a");
2114                                         pic14_emitcode("inc","r0");
2115                                 }
2116                         }
2117                         pic14_emitcode("mov","%s,r0",spname);
2118                         if (bitVectBitValue(rsave,R0_IDX))
2119                                 pic14_emitcode("mov","r0,b");     
2120                 }// else
2121                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2122                 //        if (bitVectBitValue(rsave,i))
2123                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2124                 //}
2125                 
2126                 dtype = operandType(IC_LEFT(ic));
2127                 if (currFunc && dtype && 
2128                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2129                         IFFUNC_ISISR(currFunc->type) &&
2130                         !ic->bankSaved) 
2131                         
2132                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2133                 
2134 }
2135 /*-----------------------------------------------------------------*/
2136 /* unsaveRegisters - pop the pushed registers                                      */
2137 /*-----------------------------------------------------------------*/
2138 static void unsaveRegisters (iCode *ic)
2139 {
2140         int i;
2141         bitVect *rsave;
2142         
2143         FENTRY;
2144
2145         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2146         /* find the registers in use at this time 
2147         and push them away to safety */
2148         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2149                 ic->rUsed);
2150         
2151         if (options.useXstack) {
2152                 pic14_emitcode("mov","r0,%s",spname); 
2153                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2154                         if (bitVectBitValue(rsave,i)) {
2155                                 pic14_emitcode("dec","r0");
2156                                 pic14_emitcode("movx","a,@r0");
2157                                 if (i == R0_IDX)
2158                                         pic14_emitcode("mov","b,a");
2159                                 else
2160                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2161                         }       
2162                         
2163                 }
2164                 pic14_emitcode("mov","%s,r0",spname);
2165                 if (bitVectBitValue(rsave,R0_IDX))
2166                         pic14_emitcode("mov","r0,b");
2167         } //else
2168         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2169         //      if (bitVectBitValue(rsave,i))
2170         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2171         //}
2172         
2173 }  
2174
2175
2176 /*-----------------------------------------------------------------*/
2177 /* pushSide -                            */
2178 /*-----------------------------------------------------------------*/
2179 static void pushSide(operand * oper, int size)
2180 {
2181 #if 0
2182         int offset = 0;
2183         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2184         while (size--) {
2185                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2186                 if (AOP_TYPE(oper) != AOP_REG &&
2187                         AOP_TYPE(oper) != AOP_DIR &&
2188                         strcmp(l,"a") ) {
2189                         pic14_emitcode("mov","a,%s",l);
2190                         pic14_emitcode("push","acc");
2191                 } else
2192                         pic14_emitcode("push","%s",l);
2193         }
2194 #endif
2195 }
2196
2197 /*-----------------------------------------------------------------*/
2198 /* assignResultValue -                           */
2199 /*-----------------------------------------------------------------*/
2200 static void assignResultValue(operand * oper)
2201 {
2202         int size = AOP_SIZE(oper);
2203         
2204         FENTRY;
2205
2206         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2207         
2208         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2209         
2210         while (size--) {
2211                 if (GpsuedoStkPtr++)
2212                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2213                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2214         }
2215 }
2216
2217
2218 /*-----------------------------------------------------------------*/
2219 /* genIpush - genrate code for pushing this gets a little complex  */
2220 /*-----------------------------------------------------------------*/
2221 static void genIpush (iCode *ic)
2222 {
2223         FENTRY;
2224         
2225         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2226 #if 0
2227         int size, offset = 0 ;
2228         char *l;
2229         
2230         
2231         /* if this is not a parm push : ie. it is spill push 
2232         and spill push is always done on the local stack */
2233         if (!ic->parmPush) {
2234                 
2235                 /* and the item is spilt then do nothing */
2236                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2237                         return ;
2238                 
2239                 aopOp(IC_LEFT(ic),ic,FALSE);
2240                 size = AOP_SIZE(IC_LEFT(ic));
2241                 /* push it on the stack */
2242                 while(size--) {
2243                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2244                         if (*l == '#') {
2245                                 MOVA(l);
2246                                 l = "acc";
2247                         }
2248                         pic14_emitcode("push","%s",l);
2249                 }
2250                 return ;                
2251         }
2252         
2253         /* this is a paramter push: in this case we call
2254         the routine to find the call and save those
2255         registers that need to be saved */   
2256         saveRegisters(ic);
2257         
2258         /* then do the push */
2259         aopOp(IC_LEFT(ic),ic,FALSE);
2260         
2261         
2262         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2263         size = AOP_SIZE(IC_LEFT(ic));
2264         
2265         while (size--) {
2266                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2267                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2268                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2269                         strcmp(l,"a") ) {
2270                         pic14_emitcode("mov","a,%s",l);
2271                         pic14_emitcode("push","acc");
2272                 } else
2273                         pic14_emitcode("push","%s",l);
2274         }         
2275         
2276         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2277 #endif
2278 }
2279
2280 /*-----------------------------------------------------------------*/
2281 /* genIpop - recover the registers: can happen only for spilling   */
2282 /*-----------------------------------------------------------------*/
2283 static void genIpop (iCode *ic)
2284 {
2285         FENTRY;
2286
2287         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2288 #if 0
2289         int size,offset ;
2290         
2291         
2292         /* if the temp was not pushed then */
2293         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2294                 return ;
2295         
2296         aopOp(IC_LEFT(ic),ic,FALSE);
2297         size = AOP_SIZE(IC_LEFT(ic));
2298         offset = (size-1);
2299         while (size--) 
2300                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2301                 FALSE,TRUE));
2302         
2303         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2304 #endif
2305 }
2306
2307 /*-----------------------------------------------------------------*/
2308 /* unsaverbank - restores the resgister bank from stack                    */
2309 /*-----------------------------------------------------------------*/
2310 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2311 {
2312         FENTRY;
2313
2314         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2315 #if 0
2316         int i;
2317         asmop *aop ;
2318         regs *r = NULL;
2319         
2320         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2321         if (popPsw) {
2322                 if (options.useXstack) {
2323                         aop = newAsmop(0);
2324                         r = getFreePtr(ic,&aop,FALSE);
2325                         
2326                         
2327                         pic14_emitcode("mov","%s,_spx",r->name);
2328                         pic14_emitcode("movx","a,@%s",r->name);
2329                         pic14_emitcode("mov","psw,a");
2330                         pic14_emitcode("dec","%s",r->name);
2331                         
2332                 }else
2333                         pic14_emitcode ("pop","psw");
2334         }
2335         
2336         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2337                 if (options.useXstack) {           
2338                         pic14_emitcode("movx","a,@%s",r->name);
2339                         //pic14_emitcode("mov","(%s+%d),a",
2340                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2341                         pic14_emitcode("dec","%s",r->name);
2342                         
2343                 } else 
2344                         pic14_emitcode("pop",""); //"(%s+%d)",
2345                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2346         }
2347         
2348         if (options.useXstack) {
2349                 
2350                 pic14_emitcode("mov","_spx,%s",r->name);
2351                 freeAsmop(NULL,aop,ic,TRUE);
2352                 
2353         }
2354 #endif 
2355 }
2356
2357 /*-----------------------------------------------------------------*/
2358 /* saverbank - saves an entire register bank on the stack                  */
2359 /*-----------------------------------------------------------------*/
2360 static void saverbank (int bank, iCode *ic, bool pushPsw)
2361 {
2362         FENTRY;
2363
2364         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2365 #if 0
2366         int i;
2367         asmop *aop ;
2368         regs *r = NULL;
2369         
2370         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2371         if (options.useXstack) {
2372                 
2373                 aop = newAsmop(0);
2374                 r = getFreePtr(ic,&aop,FALSE);  
2375                 pic14_emitcode("mov","%s,_spx",r->name);
2376                 
2377         }
2378         
2379         for (i = 0 ; i < pic14_nRegs ;i++) {
2380                 if (options.useXstack) {
2381                         pic14_emitcode("inc","%s",r->name);
2382                         //pic14_emitcode("mov","a,(%s+%d)",
2383                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2384                         pic14_emitcode("movx","@%s,a",r->name);                 
2385                 } else 
2386                         pic14_emitcode("push","");// "(%s+%d)",
2387                 //regspic14[i].base,8*bank+regspic14[i].offset);
2388         }
2389         
2390         if (pushPsw) {
2391                 if (options.useXstack) {
2392                         pic14_emitcode("mov","a,psw");
2393                         pic14_emitcode("movx","@%s,a",r->name); 
2394                         pic14_emitcode("inc","%s",r->name);
2395                         pic14_emitcode("mov","_spx,%s",r->name);                 
2396                         freeAsmop (NULL,aop,ic,TRUE);
2397                         
2398                 } else
2399                         pic14_emitcode("push","psw");
2400                 
2401                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2402         }
2403         ic->bankSaved = 1;
2404 #endif
2405 }
2406
2407 /*-----------------------------------------------------------------*/
2408 /* genCall - generates a call statement                                                    */
2409 /*-----------------------------------------------------------------*/
2410 static void genCall (iCode *ic)
2411 {
2412         sym_link *dtype;         
2413         symbol *sym;
2414         unsigned char *name;
2415         int isExtern;
2416         
2417         FENTRY;
2418
2419         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2420         
2421         /* if caller saves & we have not saved then */
2422         if (!ic->regsSaved)
2423                 saveRegisters(ic);
2424         
2425                 /* if we are calling a function that is not using
2426                 the same register bank then we need to save the
2427         destination registers on the stack */
2428         dtype = operandType(IC_LEFT(ic));
2429         if (currFunc && dtype && 
2430                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2431                 IFFUNC_ISISR(currFunc->type) &&
2432                 !ic->bankSaved) 
2433                 
2434                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2435         
2436         /* if send set is not empty the assign */
2437         if (_G.sendSet) {
2438                 iCode *sic;
2439                 /* For the Pic port, there is no data stack.
2440                 * So parameters passed to functions are stored
2441                 * in registers. (The pCode optimizer will get
2442                 * rid of most of these :).
2443                 */
2444                 int psuedoStkPtr=-1;
2445                 int firstTimeThruLoop = 1;
2446                 
2447                 _G.sendSet = reverseSet(_G.sendSet);
2448                 
2449                 /* First figure how many parameters are getting passed */
2450                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2451                 sic = setNextItem(_G.sendSet)) {
2452                         
2453                         aopOp(IC_LEFT(sic),sic,FALSE);
2454                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2455                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2456                 }
2457                 
2458                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2459                 sic = setNextItem(_G.sendSet)) {
2460                         int size, offset = 0;
2461                         
2462                         aopOp(IC_LEFT(sic),sic,FALSE);
2463                         size = AOP_SIZE(IC_LEFT(sic));
2464                         
2465                         while (size--) {
2466                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2467                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2468                                 
2469                                 if(!firstTimeThruLoop) {
2470                                         /* If this is not the first time we've been through the loop
2471                                         * then we need to save the parameter in a temporary
2472                                         * register. The last byte of the last parameter is
2473                                         * passed in W. */
2474                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2475                                         
2476                                 }
2477                                 firstTimeThruLoop=0;
2478                                 
2479                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2480                                 offset++;
2481                         }
2482                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2483                 }
2484                 _G.sendSet = NULL;
2485         }
2486         /* make the call */
2487         sym = OP_SYMBOL(IC_LEFT(ic));
2488         name = sym->rname[0] ? sym->rname : sym->name;
2489         isExtern = IS_EXTERN(sym->etype);
2490         if (isExtern) {
2491                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2492         }
2493         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2494         if (isExtern) {
2495                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2496         }
2497         GpsuedoStkPtr=0;
2498         /* if we need assign a result value */
2499         if ((IS_ITEMP(IC_RESULT(ic)) && 
2500                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2501                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2502                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2503                 
2504                 _G.accInUse++;
2505                 aopOp(IC_RESULT(ic),ic,FALSE);
2506                 _G.accInUse--;
2507                 
2508                 assignResultValue(IC_RESULT(ic));
2509                 
2510                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2511                         AopType(AOP_TYPE(IC_RESULT(ic))));
2512                 
2513                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2514         }
2515         
2516         /* adjust the stack for parameters if 
2517         required */
2518         if (ic->parmBytes) {
2519                 int i;
2520                 if (ic->parmBytes > 3) {
2521                         pic14_emitcode("mov","a,%s",spname);
2522                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2523                         pic14_emitcode("mov","%s,a",spname);
2524                 } else 
2525                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2526                                 pic14_emitcode("dec","%s",spname);
2527                         
2528         }
2529         
2530         /* if register bank was saved then pop them */
2531         if (ic->bankSaved)
2532                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533         
2534         /* if we hade saved some registers then unsave them */
2535         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2536                 unsaveRegisters (ic);
2537         
2538         
2539 }
2540
2541 /*-----------------------------------------------------------------*/
2542 /* genPcall - generates a call by pointer statement                        */
2543 /*-----------------------------------------------------------------*/
2544 static void genPcall (iCode *ic)
2545 {
2546         sym_link *dtype;
2547         symbol *albl = newiTempLabel(NULL);
2548         symbol *blbl = newiTempLabel(NULL);
2549         PIC_OPCODE poc;
2550         pCodeOp *pcop;
2551         operand *left;
2552         
2553         FENTRY;
2554
2555         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2556         /* if caller saves & we have not saved then */
2557         if (!ic->regsSaved)
2558                 saveRegisters(ic);
2559         
2560                 /* if we are calling a function that is not using
2561                 the same register bank then we need to save the
2562         destination registers on the stack */
2563         dtype = operandType(IC_LEFT(ic));
2564         if (currFunc && dtype && 
2565                 IFFUNC_ISISR(currFunc->type) &&
2566                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2567                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2568         
2569         left = IC_LEFT(ic);
2570         aopOp(left,ic,FALSE);
2571         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2572         
2573         pushSide(IC_LEFT(ic), FPTRSIZE);
2574         
2575         /* if send set is not empty, assign parameters */
2576         if (_G.sendSet) {
2577                 
2578                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2579                 /* no way to pass args - W always gets used to make the call */
2580         }
2581         /* first idea - factor out a common helper function and call it.
2582         But don't know how to get it generated only once in its own block
2583         
2584         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2585                 char *rname;
2586                 char *buffer;
2587                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2588                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2589                 buffer = Safe_calloc(1,strlen(rname)+16);
2590                 sprintf(buffer, "%s_goto_helper", rname);
2591                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2592                 free(buffer);
2593         }
2594         */
2595         emitpcode(POC_CALL,popGetLabel(albl->key));
2596         pcop = popGetLabel(blbl->key);
2597         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2598         emitpcode(POC_GOTO,pcop);
2599         emitpLabel(albl->key);
2600         
2601         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2602         
2603         emitpcode(poc,popGet(AOP(left),1));
2604         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2605         emitpcode(poc,popGet(AOP(left),0));
2606         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2607         
2608         emitpLabel(blbl->key);
2609         
2610         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2611         
2612         /* if we need to assign a result value */
2613         if ((IS_ITEMP(IC_RESULT(ic)) &&
2614                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2615                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2616                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2617                 
2618                 _G.accInUse++;
2619                 aopOp(IC_RESULT(ic),ic,FALSE);
2620                 _G.accInUse--;
2621                 
2622                 assignResultValue(IC_RESULT(ic));
2623                 
2624                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2625         }
2626         
2627         /* if register bank was saved then unsave them */
2628         if (currFunc && dtype && 
2629                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2630                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2631         
2632                 /* if we hade saved some registers then
2633         unsave them */
2634         if (ic->regsSaved)
2635                 unsaveRegisters (ic);
2636         
2637 }
2638
2639 /*-----------------------------------------------------------------*/
2640 /* resultRemat - result  is rematerializable                                       */
2641 /*-----------------------------------------------------------------*/
2642 static int resultRemat (iCode *ic)
2643 {
2644         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2645         FENTRY;
2646
2647         if (SKIP_IC(ic) || ic->op == IFX)
2648                 return 0;
2649         
2650         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2651                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2652                 if (sym->remat && !POINTER_SET(ic)) 
2653                         return 1;
2654         }
2655         
2656         return 0;
2657 }
2658
2659 #if defined(__BORLANDC__) || defined(_MSC_VER)
2660 #define STRCASECMP stricmp
2661 #else
2662 #define STRCASECMP strcasecmp
2663 #endif
2664
2665 #if 0
2666 /*-----------------------------------------------------------------*/
2667 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2668 /*-----------------------------------------------------------------*/
2669 static bool inExcludeList(char *s)
2670 {
2671         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2672         int i =0;
2673         
2674         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2675         if (options.excludeRegs[i] &&
2676                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2677                 return FALSE ;
2678         
2679         for ( i = 0 ; options.excludeRegs[i]; i++) {
2680                 if (options.excludeRegs[i] &&
2681                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2682                         return TRUE;
2683         }
2684         return FALSE ;
2685 }
2686 #endif
2687
2688 /*-----------------------------------------------------------------*/
2689 /* genFunction - generated code for function entry                                 */
2690 /*-----------------------------------------------------------------*/
2691 static void genFunction (iCode *ic)
2692 {
2693         symbol *sym;
2694         sym_link *ftype;
2695         
2696         FENTRY;
2697
2698         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2699         
2700         labelOffset += (max_key+4);
2701         max_key=0;
2702         GpsuedoStkPtr=0;
2703         _G.nRegsSaved = 0;
2704         /* create the function header */
2705         pic14_emitcode(";","-----------------------------------------");
2706         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2707         pic14_emitcode(";","-----------------------------------------");
2708         
2709         pic14_emitcode("","%s:",sym->rname);
2710         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2711         
2712         ftype = operandType(IC_LEFT(ic));
2713         
2714         /* if critical function then turn interrupts off */
2715         if (IFFUNC_ISCRITICAL(ftype))
2716                 pic14_emitcode("clr","ea");
2717         
2718                 /* here we need to generate the equates for the
2719         register bank if required */
2720 #if 0
2721         if (FUNC_REGBANK(ftype) != rbank) {
2722                 int i ;
2723                 
2724                 rbank = FUNC_REGBANK(ftype);
2725                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2726                         if (strcmp(regspic14[i].base,"0") == 0)
2727                                 pic14_emitcode("","%s = 0x%02x",
2728                                 regspic14[i].dname,
2729                                 8*rbank+regspic14[i].offset);
2730                         else
2731                                 pic14_emitcode ("","%s = %s + 0x%02x",
2732                                 regspic14[i].dname,
2733                                 regspic14[i].base,
2734                                 8*rbank+regspic14[i].offset);
2735                 }
2736         }
2737 #endif
2738         
2739         /* if this is an interrupt service routine */
2740         if (IFFUNC_ISISR(sym->type)) {
2741         /*  already done in pic14createInterruptVect() - delete me
2742         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2743         emitpcodeNULLop(POC_NOP);
2744         emitpcodeNULLop(POC_NOP);
2745         emitpcodeNULLop(POC_NOP);
2746                 */
2747                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2748                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2749                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2750                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2751                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2752                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2753                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2754                 
2755                 pBlockConvert2ISR(pb);
2756 #if 0  
2757                 if (!inExcludeList("acc"))              
2758                         pic14_emitcode ("push","acc");  
2759                 if (!inExcludeList("b"))
2760                         pic14_emitcode ("push","b");
2761                 if (!inExcludeList("dpl"))
2762                         pic14_emitcode ("push","dpl");
2763                 if (!inExcludeList("dph"))
2764                         pic14_emitcode ("push","dph");
2765                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2766                 {
2767                         pic14_emitcode ("push", "dpx");
2768                         /* Make sure we're using standard DPTR */
2769                         pic14_emitcode ("push", "dps");
2770                         pic14_emitcode ("mov", "dps, #0x00");
2771                         if (options.stack10bit)
2772                         { 
2773                                 /* This ISR could conceivably use DPTR2. Better save it. */
2774                                 pic14_emitcode ("push", "dpl1");
2775                                 pic14_emitcode ("push", "dph1");
2776                                 pic14_emitcode ("push", "dpx1");
2777                         }
2778                 }
2779                 /* if this isr has no bank i.e. is going to
2780                 run with bank 0 , then we need to save more
2781                 registers :-) */
2782                 if (!FUNC_REGBANK(sym->type)) {
2783                         
2784                 /* if this function does not call any other
2785                 function then we can be economical and
2786                         save only those registers that are used */
2787                         if (! IFFUNC_HASFCALL(sym->type)) {
2788                                 int i;
2789                                 
2790                                 /* if any registers used */
2791                                 if (sym->regsUsed) {
2792                                         /* save the registers used */
2793                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2794                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2795                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2796                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2797                                         }
2798                                 }
2799                                 
2800                         } else {
2801                         /* this function has    a function call cannot
2802                         determines register usage so we will have the
2803                                 entire bank */
2804                                 saverbank(0,ic,FALSE);
2805                         }       
2806                 }
2807 #endif
2808         } else {
2809         /* if callee-save to be used for this function
2810                 then save the registers being used in this function */
2811                 if (IFFUNC_CALLEESAVES(sym->type)) {
2812                         int i;
2813                         
2814                         /* if any registers used */
2815                         if (sym->regsUsed) {
2816                                 /* save the registers used */
2817                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2818                                         if (bitVectBitValue(sym->regsUsed,i) ||
2819                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2820                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2821                                                 _G.nRegsSaved++;
2822                                         }
2823                                 }
2824                         }
2825                 }
2826         }
2827         
2828         /* set the register bank to the desired value */
2829         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2830                 pic14_emitcode("push","psw");
2831                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2832         }
2833         
2834         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2835                 
2836                 if (options.useXstack) {
2837                         pic14_emitcode("mov","r0,%s",spname);
2838                         pic14_emitcode("mov","a,_bp");
2839                         pic14_emitcode("movx","@r0,a");
2840                         pic14_emitcode("inc","%s",spname);
2841                 }
2842                 else
2843                 {
2844                         /* set up the stack */
2845                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2846                 }
2847                 pic14_emitcode ("mov","_bp,%s",spname);
2848         }
2849         
2850         /* adjust the stack for the function */
2851         if (sym->stack) {
2852                 
2853                 int i = sym->stack;
2854                 if (i > 256 ) 
2855                         werror(W_STACK_OVERFLOW,sym->name);
2856                 
2857                 if (i > 3 && sym->recvSize < 4) {                
2858                         
2859                         pic14_emitcode ("mov","a,sp");
2860                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2861                         pic14_emitcode ("mov","sp,a");
2862                         
2863                 }
2864                 else
2865                         while(i--)
2866                                 pic14_emitcode("inc","sp");
2867         }
2868         
2869         if (sym->xstack) {
2870                 
2871                 pic14_emitcode ("mov","a,_spx");
2872                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2873                 pic14_emitcode ("mov","_spx,a");
2874         }
2875         
2876 }
2877
2878 /*-----------------------------------------------------------------*/
2879 /* genEndFunction - generates epilogue for functions                       */
2880 /*-----------------------------------------------------------------*/
2881 static void genEndFunction (iCode *ic)
2882 {
2883         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2884         
2885         FENTRY;
2886
2887         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2888         
2889         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2890         {
2891                 pic14_emitcode ("mov","%s,_bp",spname);
2892         }
2893         
2894         /* if use external stack but some variables were
2895         added to the local stack then decrement the
2896         local stack */
2897         if (options.useXstack && sym->stack) {    
2898                 pic14_emitcode("mov","a,sp");
2899                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2900                 pic14_emitcode("mov","sp,a");
2901         }
2902         
2903         
2904         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2905                 if (options.useXstack) {
2906                         pic14_emitcode("mov","r0,%s",spname);
2907                         pic14_emitcode("movx","a,@r0");
2908                         pic14_emitcode("mov","_bp,a");
2909                         pic14_emitcode("dec","%s",spname);
2910                 }
2911                 else
2912                 {
2913                         pic14_emitcode ("pop","_bp");
2914                 }
2915         }
2916         
2917         /* restore the register bank    */        
2918         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2919                 pic14_emitcode ("pop","psw");
2920         
2921         if (IFFUNC_ISISR(sym->type)) {
2922                 
2923                 /* now we need to restore the registers */
2924                 /* if this isr has no bank i.e. is going to
2925                 run with bank 0 , then we need to save more
2926 registers :-) */
2927                 if (!FUNC_REGBANK(sym->type)) {
2928                         
2929                 /* if this function does not call any other
2930                 function then we can be economical and
2931                         save only those registers that are used */
2932                         if (! IFFUNC_HASFCALL(sym->type)) {
2933                                 int i;
2934                                 
2935                                 /* if any registers used */
2936                                 if (sym->regsUsed) {
2937                                         /* save the registers used */
2938                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2939                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2940                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2941                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2942                                         }
2943                                 }
2944                                 
2945                         } else {
2946                         /* this function has    a function call cannot
2947                         determines register usage so we will have the
2948                                 entire bank */
2949                                 unsaverbank(0,ic,FALSE);
2950                         }       
2951                 }
2952 #if 0
2953                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2954                 {
2955                         if (options.stack10bit)
2956                         {
2957                                 pic14_emitcode ("pop", "dpx1");
2958                                 pic14_emitcode ("pop", "dph1");
2959                                 pic14_emitcode ("pop", "dpl1");
2960                         } 
2961                         pic14_emitcode ("pop", "dps");
2962                         pic14_emitcode ("pop", "dpx");
2963                 }
2964                 if (!inExcludeList("dph"))
2965                         pic14_emitcode ("pop","dph");
2966                 if (!inExcludeList("dpl"))
2967                         pic14_emitcode ("pop","dpl");
2968                 if (!inExcludeList("b"))
2969                         pic14_emitcode ("pop","b");
2970                 if (!inExcludeList("acc"))
2971                         pic14_emitcode ("pop","acc");
2972                 
2973                 if (IFFUNC_ISCRITICAL(sym->type))
2974                         pic14_emitcode("setb","ea");
2975 #endif
2976                 
2977                 /* if debug then send end of function */
2978                 /*      if (options.debug && currFunc) { */
2979                 if (currFunc) {
2980                         debugFile->writeEndFunction (currFunc, ic, 1);
2981                 }
2982                 
2983                 pic14_emitcode ("reti","");
2984                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2985                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2986                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2987                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2988                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2989                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2990                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2991                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2992                 emitpcodeNULLop(POC_RETFIE);
2993         }
2994         else {
2995                 if (IFFUNC_ISCRITICAL(sym->type))
2996                         pic14_emitcode("setb","ea");
2997                 
2998                 if (IFFUNC_CALLEESAVES(sym->type)) {
2999                         int i;
3000                         
3001                         /* if any registers used */
3002                         if (sym->regsUsed) {
3003                                 /* save the registers used */
3004                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3005                                         if (bitVectBitValue(sym->regsUsed,i) ||
3006                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3007                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
3008                                 }
3009                         }
3010                         
3011                 }
3012                 
3013                 /* if debug then send end of function */
3014                 if (currFunc) {
3015                         debugFile->writeEndFunction (currFunc, ic, 1);
3016                 }
3017                 
3018                 pic14_emitcode ("return","");
3019                 emitpcodeNULLop(POC_RETURN);
3020                 
3021                 /* Mark the end of a function */
3022                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
3023         }
3024         
3025 }
3026
3027 /*-----------------------------------------------------------------*/
3028 /* genRet - generate code for return statement                                     */
3029 /*-----------------------------------------------------------------*/
3030 static void genRet (iCode *ic)
3031 {
3032         int size,offset = 0 , pushed = 0;
3033         
3034         FENTRY;
3035
3036         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3037         /* if we have no return value then
3038         just generate the "ret" */
3039         if (!IC_LEFT(ic)) 
3040                 goto jumpret;           
3041         
3042                 /* we have something to return then
3043         move the return value into place */
3044         aopOp(IC_LEFT(ic),ic,FALSE);
3045         size = AOP_SIZE(IC_LEFT(ic));
3046         
3047         while (size--) {
3048                 char *l ;
3049                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3050                         /* #NOCHANGE */
3051                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
3052                                 FALSE,TRUE);
3053                         pic14_emitcode("push","%s",l);
3054                         pushed++;
3055                 } else {
3056                         l = aopGet(AOP(IC_LEFT(ic)),offset,
3057                                 FALSE,FALSE);
3058                         if (strcmp(fReturn[offset],l)) {
3059                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
3060                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3061                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3062                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3063                                         emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset));
3064                                 }else {
3065                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3066                                 }
3067                                 if(size) {
3068                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
3069                                 }
3070                                 offset++;
3071                         }
3072                 }
3073         }
3074         
3075         if (pushed) {
3076                 while(pushed) {
3077                         pushed--;
3078                         if (strcmp(fReturn[pushed],"a"))
3079                                 pic14_emitcode("pop",fReturn[pushed]);
3080                         else
3081                                 pic14_emitcode("pop","acc");
3082                 }
3083         }
3084         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3085         
3086 jumpret:
3087         /* generate a jump to the return label
3088         if the next is not the return statement */
3089         if (!(ic->next && ic->next->op == LABEL &&
3090                 IC_LABEL(ic->next) == returnLabel)) {
3091                 
3092                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3093                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3094         }
3095         
3096 }
3097
3098 /*-----------------------------------------------------------------*/
3099 /* genLabel - generates a label                                                                    */
3100 /*-----------------------------------------------------------------*/
3101 static void genLabel (iCode *ic)
3102 {
3103         FENTRY;
3104
3105         /* special case never generate */
3106         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3107         if (IC_LABEL(ic) == entryLabel)
3108                 return ;
3109         
3110         emitpLabel(IC_LABEL(ic)->key);
3111         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3112 }
3113
3114 /*-----------------------------------------------------------------*/
3115 /* genGoto - generates a goto                                                                      */
3116 /*-----------------------------------------------------------------*/
3117 //tsd
3118 static void genGoto (iCode *ic)
3119 {
3120         FENTRY;
3121
3122         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3123         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3124 }
3125
3126
3127 /*-----------------------------------------------------------------*/
3128 /* genMultbits :- multiplication of bits                                                   */
3129 /*-----------------------------------------------------------------*/
3130 static void genMultbits (operand *left, 
3131                                                  operand *right, 
3132                                                  operand *result)
3133 {
3134         FENTRY;
3135         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3136         
3137         if(!pic14_sameRegs(AOP(result),AOP(right)))
3138                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3139         
3140         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3141         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3142         emitpcode(POC_BCF,  popGet(AOP(result),0));
3143         
3144 }
3145
3146
3147 /*-----------------------------------------------------------------*/
3148 /* genMultOneByte : 8 bit multiplication & division                        */
3149 /*-----------------------------------------------------------------*/
3150 static void genMultOneByte (operand *left,
3151                                                         operand *right,
3152                                                         operand *result)
3153 {
3154         sym_link *opetype = operandType(result);
3155         
3156         // symbol *lbl ;
3157         int size,offset;
3158         
3159         FENTRY;
3160         
3161         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3162         DEBUGpic14_AopType(__LINE__,left,right,result);
3163         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3164         
3165         /* (if two literals, the value is computed before) */
3166         /* if one literal, literal on the right */
3167         if (AOP_TYPE(left) == AOP_LIT){
3168                 operand *t = right;
3169                 right = left;
3170                 left = t;
3171         }
3172         
3173         size = AOP_SIZE(result);
3174         if(size == 1) {
3175                 
3176                 if (AOP_TYPE(right) == AOP_LIT){
3177                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3178                                 aopGet(AOP(right),0,FALSE,FALSE), 
3179                                 aopGet(AOP(left),0,FALSE,FALSE), 
3180                                 aopGet(AOP(result),0,FALSE,FALSE));
3181                         pic14_emitcode("call","genMultLit");
3182                 } else {
3183                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3184                                 aopGet(AOP(right),0,FALSE,FALSE), 
3185                                 aopGet(AOP(left),0,FALSE,FALSE), 
3186                                 aopGet(AOP(result),0,FALSE,FALSE));
3187                         pic14_emitcode("call","genMult8X8_8");
3188                         
3189                 }
3190                 genMult8X8_8 (left, right,result);
3191                 
3192                 
3193                 /* signed or unsigned */
3194                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3195                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3196                 //MOVA(l);               
3197                 //pic14_emitcode("mul","ab");
3198                 /* if result size = 1, mul signed = mul unsigned */
3199                 //aopPut(AOP(result),"a",0);
3200                 
3201         } else {        // (size > 1)
3202                 
3203                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3204                         aopGet(AOP(right),0,FALSE,FALSE), 
3205                         aopGet(AOP(left),0,FALSE,FALSE), 
3206                         aopGet(AOP(result),0,FALSE,FALSE));
3207                 
3208                 if (SPEC_USIGN(opetype)){
3209                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3210                         genUMult8X8_16 (left, right, result, NULL);
3211                         
3212                         if (size > 2) {
3213                                 /* for filling the MSBs */
3214                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3215                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3216                         }
3217                 }
3218                 else{
3219                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3220                         
3221                         pic14_emitcode("mov","a,b");
3222                         
3223                         /* adjust the MSB if left or right neg */
3224                         
3225                         /* if one literal */
3226                         if (AOP_TYPE(right) == AOP_LIT){
3227                                 pic14_emitcode("multiply ","right is a lit");
3228                                 /* AND literal negative */
3229                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3230                                         /* adjust MSB (c==0 after mul) */
3231                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3232                                 }
3233                         }
3234                         else{
3235                                 genSMult8X8_16 (left, right, result, NULL);
3236                         }
3237                         
3238                         if(size > 2){
3239                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3240                                 /* get the sign */
3241                                 pic14_emitcode("rlc","a");
3242                                 pic14_emitcode("subb","a,acc");
3243                         }
3244                 }
3245                 
3246                 size -= 2;
3247                 offset = 2;
3248                 if (size > 0)
3249                         while (size--)
3250                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3251                         //aopPut(AOP(result),"a",offset++);
3252         }
3253 }
3254
3255 /*-----------------------------------------------------------------*/
3256 /* genMult - generates code for multiplication                                     */
3257 /*-----------------------------------------------------------------*/
3258 static void genMult (iCode *ic)
3259 {
3260         operand *left = IC_LEFT(ic);
3261         operand *right = IC_RIGHT(ic);
3262         operand *result= IC_RESULT(ic); 
3263         
3264         FENTRY;
3265
3266         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3267         /* assign the amsops */
3268         aopOp (left,ic,FALSE);
3269         aopOp (right,ic,FALSE);
3270         aopOp (result,ic,TRUE);
3271         
3272         DEBUGpic14_AopType(__LINE__,left,right,result);
3273         
3274         /* special cases first */
3275         /* both are bits */
3276         if (AOP_TYPE(left) == AOP_CRY &&
3277                 AOP_TYPE(right)== AOP_CRY) {
3278                 genMultbits(left,right,result);
3279                 goto release ;
3280         }
3281         
3282         /* if both are of size == 1 */
3283         if (AOP_SIZE(left) == 1 &&
3284                 AOP_SIZE(right) == 1 ) {
3285                 genMultOneByte(left,right,result);
3286                 goto release ;
3287         }
3288         
3289         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3290         
3291         /* should have been converted to function call */
3292         //assert(0) ;
3293         
3294 release :
3295         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3296         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3297         freeAsmop(result,NULL,ic,TRUE); 
3298 }
3299
3300 /*-----------------------------------------------------------------*/
3301 /* genDivbits :- division of bits                                                                  */
3302 /*-----------------------------------------------------------------*/
3303 static void genDivbits (operand *left, 
3304                                                 operand *right, 
3305                                                 operand *result)
3306 {
3307         
3308         char *l;
3309         
3310         FENTRY;
3311
3312         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3313         /* the result must be bit */      
3314         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3315         l = aopGet(AOP(left),0,FALSE,FALSE);
3316         
3317         MOVA(l);          
3318         
3319         pic14_emitcode("div","ab");
3320         pic14_emitcode("rrc","a");
3321         aopPut(AOP(result),"c",0);
3322 }
3323
3324 /*-----------------------------------------------------------------*/
3325 /* genDivOneByte : 8 bit division                                                                  */
3326 /*-----------------------------------------------------------------*/
3327 static void genDivOneByte (operand *left,
3328                                                    operand *right,
3329                                                    operand *result)
3330 {
3331         sym_link *opetype = operandType(result);
3332         char *l ;
3333         symbol *lbl ;
3334         int size,offset;
3335         
3336         FENTRY;
3337         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3338         size = AOP_SIZE(result) - 1;
3339         offset = 1;
3340         /* signed or unsigned */
3341         if (SPEC_USIGN(opetype)) {
3342                 /* unsigned is easy */
3343                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3344                 l = aopGet(AOP(left),0,FALSE,FALSE);
3345                 MOVA(l);                
3346                 pic14_emitcode("div","ab");
3347                 aopPut(AOP(result),"a",0);
3348                 while (size--)
3349                         aopPut(AOP(result),zero,offset++);
3350                 return ;
3351         }
3352         
3353         /* signed is a little bit more difficult */
3354         
3355         /* save the signs of the operands */
3356         l = aopGet(AOP(left),0,FALSE,FALSE);      
3357         MOVA(l);          
3358         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3359         pic14_emitcode("push","acc"); /* save it on the stack */
3360         
3361         /* now sign adjust for both left & right */
3362         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3363         MOVA(l);                 
3364         lbl = newiTempLabel(NULL);
3365         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3366         pic14_emitcode("cpl","a");   
3367         pic14_emitcode("inc","a");
3368         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3369         pic14_emitcode("mov","b,a");
3370         
3371         /* sign adjust left side */
3372         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3373         MOVA(l);
3374         
3375         lbl = newiTempLabel(NULL);
3376         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3377         pic14_emitcode("cpl","a");
3378         pic14_emitcode("inc","a");
3379         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3380         
3381         /* now the division */
3382         pic14_emitcode("div","ab");
3383         /* we are interested in the lower order
3384         only */
3385         pic14_emitcode("mov","b,a");
3386         lbl = newiTempLabel(NULL);
3387         pic14_emitcode("pop","acc");     
3388         /* if there was an over flow we don't 
3389         adjust the sign of the result */
3390         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3391         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3392         CLRC;
3393         pic14_emitcode("clr","a");
3394         pic14_emitcode("subb","a,b");
3395         pic14_emitcode("mov","b,a");
3396         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3397         
3398         /* now we are done */
3399         aopPut(AOP(result),"b",0);
3400         if(size > 0){
3401                 pic14_emitcode("mov","c,b.7");
3402                 pic14_emitcode("subb","a,acc");   
3403         }
3404         while (size--)
3405                 aopPut(AOP(result),"a",offset++);
3406         
3407 }
3408
3409 /*-----------------------------------------------------------------*/
3410 /* genDiv - generates code for division                                                    */
3411 /*-----------------------------------------------------------------*/
3412 static void genDiv (iCode *ic)
3413 {
3414         operand *left = IC_LEFT(ic);
3415         operand *right = IC_RIGHT(ic);
3416         operand *result= IC_RESULT(ic); 
3417         
3418         FENTRY;
3419         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3420         /* assign the amsops */
3421         aopOp (left,ic,FALSE);
3422         aopOp (right,ic,FALSE);
3423         aopOp (result,ic,TRUE);
3424         
3425         /* special cases first */
3426         /* both are bits */
3427         if (AOP_TYPE(left) == AOP_CRY &&
3428                 AOP_TYPE(right)== AOP_CRY) {
3429                 genDivbits(left,right,result);
3430                 goto release ;
3431         }
3432         
3433         /* if both are of size == 1 */
3434         if (AOP_SIZE(left) == 1 &&
3435                 AOP_SIZE(right) == 1 ) {
3436                 genDivOneByte(left,right,result);
3437                 goto release ;
3438         }
3439         
3440         /* should have been converted to function call */
3441         assert(0);
3442 release :
3443         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3444         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3445         freeAsmop(result,NULL,ic,TRUE); 
3446 }
3447
3448 /*-----------------------------------------------------------------*/
3449 /* genModbits :- modulus of bits                                                                   */
3450 /*-----------------------------------------------------------------*/
3451 static void genModbits (operand *left, 
3452                                                 operand *right, 
3453                                                 operand *result)
3454 {
3455         
3456         char *l;
3457         
3458         FENTRY;
3459         /* the result must be bit */      
3460         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3461         l = aopGet(AOP(left),0,FALSE,FALSE);
3462         
3463         MOVA(l);
3464         
3465         pic14_emitcode("div","ab");
3466         pic14_emitcode("mov","a,b");
3467         pic14_emitcode("rrc","a");
3468         aopPut(AOP(result),"c",0);
3469 }
3470
3471 /*-----------------------------------------------------------------*/
3472 /* genModOneByte : 8 bit modulus                                                                   */
3473 /*-----------------------------------------------------------------*/
3474 static void genModOneByte (operand *left,
3475                                                    operand *right,
3476                                                    operand *result)
3477 {
3478         sym_link *opetype = operandType(result);
3479         char *l ;
3480         symbol *lbl ;
3481         
3482         FENTRY;
3483         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3484         /* signed or unsigned */
3485         if (SPEC_USIGN(opetype)) {
3486                 /* unsigned is easy */
3487                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3488                 l = aopGet(AOP(left),0,FALSE,FALSE);
3489                 MOVA(l);        
3490                 pic14_emitcode("div","ab");
3491                 aopPut(AOP(result),"b",0);
3492                 return ;
3493         }
3494         
3495         /* signed is a little bit more difficult */
3496         
3497         /* save the signs of the operands */
3498         l = aopGet(AOP(left),0,FALSE,FALSE);      
3499         MOVA(l);
3500         
3501         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3502         pic14_emitcode("push","acc"); /* save it on the stack */
3503         
3504         /* now sign adjust for both left & right */
3505         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3506         MOVA(l);
3507         
3508         lbl = newiTempLabel(NULL);
3509         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3510         pic14_emitcode("cpl","a");   
3511         pic14_emitcode("inc","a");
3512         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3513         pic14_emitcode("mov","b,a"); 
3514         
3515         /* sign adjust left side */
3516         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3517         MOVA(l);
3518         
3519         lbl = newiTempLabel(NULL);
3520         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3521         pic14_emitcode("cpl","a");   
3522         pic14_emitcode("inc","a");
3523         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3524         
3525         /* now the multiplication */
3526         pic14_emitcode("div","ab");
3527         /* we are interested in the lower order
3528         only */
3529         lbl = newiTempLabel(NULL);
3530         pic14_emitcode("pop","acc");     
3531         /* if there was an over flow we don't 
3532         adjust the sign of the result */
3533         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3534         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3535         CLRC ;
3536         pic14_emitcode("clr","a");
3537         pic14_emitcode("subb","a,b");
3538         pic14_emitcode("mov","b,a");
3539         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3540         
3541         /* now we are done */
3542         aopPut(AOP(result),"b",0);
3543         
3544 }
3545
3546 /*-----------------------------------------------------------------*/
3547 /* genMod - generates code for division                                                    */
3548 /*-----------------------------------------------------------------*/
3549 static void genMod (iCode *ic)
3550 {
3551         operand *left = IC_LEFT(ic);
3552         operand *right = IC_RIGHT(ic);
3553         operand *result= IC_RESULT(ic);  
3554         
3555         FENTRY;
3556         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3557         /* assign the amsops */
3558         aopOp (left,ic,FALSE);
3559         aopOp (right,ic,FALSE);
3560         aopOp (result,ic,TRUE);
3561         
3562         /* special cases first */
3563         /* both are bits */
3564         if (AOP_TYPE(left) == AOP_CRY &&
3565                 AOP_TYPE(right)== AOP_CRY) {
3566                 genModbits(left,right,result);
3567                 goto release ;
3568         }
3569         
3570         /* if both are of size == 1 */
3571         if (AOP_SIZE(left) == 1 &&
3572                 AOP_SIZE(right) == 1 ) {
3573                 genModOneByte(left,right,result);
3574                 goto release ;
3575         }
3576         
3577         /* should have been converted to function call */
3578         assert(0);
3579         
3580 release :
3581         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3582         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3583         freeAsmop(result,NULL,ic,TRUE); 
3584 }
3585
3586 /*-----------------------------------------------------------------*/
3587 /* genIfxJump :- will create a jump depending on the ifx                   */
3588 /*-----------------------------------------------------------------*/
3589 /*
3590 note: May need to add parameter to indicate when a variable is in bit space.
3591 */
3592 static void genIfxJump (iCode *ic, char *jval)
3593 {
3594         
3595         FENTRY;
3596         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3597         /* if true label then we jump if condition
3598         supplied is true */
3599         if ( IC_TRUE(ic) ) {
3600                 
3601                 if(strcmp(jval,"a") == 0)
3602                         emitSKPZ;
3603                 else if (strcmp(jval,"c") == 0)
3604                         emitSKPC;
3605                 else {
3606                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3607                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3608                 }
3609                 
3610                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3611                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3612                 
3613         }
3614         else {
3615                 /* false label is present */
3616                 if(strcmp(jval,"a") == 0)
3617                         emitSKPNZ;
3618                 else if (strcmp(jval,"c") == 0)
3619                         emitSKPNC;
3620                 else {
3621                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3622                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3623                 }
3624                 
3625                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3626                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3627                 
3628         }
3629         
3630         
3631         /* mark the icode as generated */
3632         ic->generated = 1;
3633 }
3634
3635 /*-----------------------------------------------------------------*/
3636 /* genSkip                                                                                                                 */
3637 /*-----------------------------------------------------------------*/
3638 static void genSkip(iCode *ifx,int status_bit)
3639 {
3640         FENTRY;
3641         if(!ifx)
3642                 return;
3643         
3644         if ( IC_TRUE(ifx) ) {
3645                 switch(status_bit) {
3646                 case 'z':
3647                         emitSKPNZ;
3648                         break;
3649                         
3650                 case 'c':
3651                         emitSKPNC;
3652                         break;
3653                         
3654                 case 'd':
3655                         emitSKPDC;
3656                         break;
3657                         
3658                 }
3659                 
3660                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3661                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3662                 
3663         } else {
3664                 
3665                 switch(status_bit) {
3666                         
3667                 case 'z':
3668                         emitSKPZ;
3669                         break;
3670                         
3671                 case 'c':
3672                         emitSKPC;
3673                         break;
3674                         
3675                 case 'd':
3676                         emitSKPDC;
3677                         break;
3678                 }
3679                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3680                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3681                 
3682         }
3683         
3684 }
3685
3686 /*-----------------------------------------------------------------*/
3687 /* genSkipc                                                                                                        */
3688 /*-----------------------------------------------------------------*/
3689 static void genSkipc(resolvedIfx *rifx)
3690 {
3691         FENTRY;
3692         if(!rifx)
3693                 return;
3694         
3695         if(rifx->condition)
3696                 emitSKPC;
3697         else
3698                 emitSKPNC;
3699         
3700         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3701         rifx->generated = 1;
3702 }
3703
3704 /*-----------------------------------------------------------------*/
3705 /* genSkipz2                                                                                                       */
3706 /*-----------------------------------------------------------------*/
3707 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3708 {
3709         FENTRY;
3710         if(!rifx)
3711                 return;
3712         
3713         if( (rifx->condition ^ invert_condition) & 1)
3714                 emitSKPZ;
3715         else
3716                 emitSKPNZ;
3717         
3718         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3719         rifx->generated = 1;
3720 }
3721
3722 /*-----------------------------------------------------------------*/
3723 /* genSkipz                                                        */
3724 /*-----------------------------------------------------------------*/
3725 static void genSkipz(iCode *ifx, int condition)
3726 {
3727         FENTRY;
3728         if(!ifx)
3729                 return;
3730         
3731         if(condition)
3732                 emitSKPNZ;
3733         else
3734                 emitSKPZ;
3735         
3736         if ( IC_TRUE(ifx) )
3737                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3738         else
3739                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3740         
3741         if ( IC_TRUE(ifx) )
3742                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3743         else
3744                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3745         
3746 }
3747 /*-----------------------------------------------------------------*/
3748 /* genSkipCond                                                     */
3749 /*-----------------------------------------------------------------*/
3750 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3751 {
3752         FENTRY;
3753         if(!rifx)
3754                 return;
3755         
3756         if(rifx->condition)
3757                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3758         else
3759                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3760         
3761         
3762         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3763         rifx->generated = 1;
3764 }
3765
3766 #if 0
3767 /*-----------------------------------------------------------------*/
3768 /* genChkZeroes :- greater or less than comparison                 */
3769 /*     For each byte in a literal that is zero, inclusive or the   */
3770 /*     the corresponding byte in the operand with W                */
3771 /*     returns true if any of the bytes are zero                   */
3772 /*-----------------------------------------------------------------*/
3773 static int genChkZeroes(operand *op, int lit,  int size)
3774 {
3775         
3776         int i;
3777         int flag =1;
3778         
3779         while(size--) {
3780                 i = (lit >> (size*8)) & 0xff;
3781                 
3782                 if(i==0) {
3783                         if(flag) 
3784                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3785                         else
3786                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3787                         flag = 0;
3788                 }
3789         }
3790         
3791         return (flag==0);
3792 }
3793 #endif
3794
3795 /*-----------------------------------------------------------------*/
3796 /* genCmp :- greater or less than comparison                       */
3797 /*-----------------------------------------------------------------*/
3798 static void genCmp (operand *left,operand *right,
3799                                         operand *result, iCode *ifx, int sign)
3800 {
3801         int size; //, offset = 0 ;
3802         unsigned long lit = 0L,i = 0;
3803         resolvedIfx rFalseIfx;
3804         //  resolvedIfx rTrueIfx;
3805         symbol *truelbl;
3806
3807         FENTRY;
3808         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3809         /*
3810         if(ifx) {
3811         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3812         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3813         }
3814         */
3815         
3816         resolveIfx(&rFalseIfx,ifx);
3817         truelbl  = newiTempLabel(NULL);
3818         size = max(AOP_SIZE(left),AOP_SIZE(right));
3819         
3820         DEBUGpic14_AopType(__LINE__,left,right,result);
3821         
3822 #define _swapp
3823         
3824         /* if literal is on the right then swap with left */
3825         if ((AOP_TYPE(right) == AOP_LIT)) {
3826                 operand *tmp = right ;
3827                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3828                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3829 #ifdef _swapp
3830                 
3831                 lit = (lit - 1) & mask;
3832                 right = left;
3833                 left = tmp;
3834                 rFalseIfx.condition ^= 1;
3835 #endif
3836                 
3837         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3838                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3839         }
3840         
3841         
3842         //if(IC_TRUE(ifx) == NULL)
3843         /* if left & right are bit variables */
3844         if (AOP_TYPE(left) == AOP_CRY &&
3845                 AOP_TYPE(right) == AOP_CRY ) {
3846                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3847                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3848         } else {
3849         /* subtract right from left if at the
3850         end the carry flag is set then we know that
3851                 left is greater than right */
3852                 
3853                 symbol *lbl  = newiTempLabel(NULL);
3854                 
3855 #ifndef _swapp
3856                 if(AOP_TYPE(right) == AOP_LIT) {
3857                         
3858                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3859                         
3860                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3861                         
3862                         /* special cases */
3863                         
3864                         if(lit == 0) {
3865                                 
3866                                 if(sign != 0) 
3867                                         genSkipCond(&rFalseIfx,left,size-1,7);
3868                                 else 
3869                                         /* no need to compare to 0...*/
3870                                         /* NOTE: this is a de-generate compare that most certainly 
3871                                         *       creates some dead code. */
3872                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3873                                 
3874                                 if(ifx) ifx->generated = 1;
3875                                 return;
3876                                 
3877                         }
3878                         size--;
3879                         
3880                         if(size == 0) {
3881                                 //i = (lit >> (size*8)) & 0xff;
3882                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3883                                 
3884                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3885                                 
3886                                 i = ((0-lit) & 0xff);
3887                                 if(sign) {
3888                                         if( i == 0x81) { 
3889                                         /* lit is 0x7f, all signed chars are less than
3890                                                 * this except for 0x7f itself */
3891                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3892                                                 genSkipz2(&rFalseIfx,0);
3893                                         } else {
3894                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3895                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3896                                                 genSkipc(&rFalseIfx);
3897                                         }
3898                                         
3899                                 } else {
3900                                         if(lit == 1) {
3901                                                 genSkipz2(&rFalseIfx,1);
3902                                         } else {
3903                                                 emitpcode(POC_ADDLW, popGetLit(i));
3904                                                 genSkipc(&rFalseIfx);
3905                                         }
3906                                 }
3907                                 
3908                                 if(ifx) ifx->generated = 1;
3909                                 return;
3910                         }
3911                         
3912                         /* chars are out of the way. now do ints and longs */
3913                         
3914                         
3915                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3916                         
3917                         /* special cases */
3918                         
3919                         if(sign) {
3920                                 
3921                                 if(lit == 0) {
3922                                         genSkipCond(&rFalseIfx,left,size,7);
3923                                         if(ifx) ifx->generated = 1;
3924                                         return;
3925                                 }
3926                                 
3927                                 if(lit <0x100) {
3928                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3929                                         
3930                                         //rFalseIfx.condition ^= 1;
3931                                         //genSkipCond(&rFalseIfx,left,size,7);
3932                                         //rFalseIfx.condition ^= 1;
3933                                         
3934                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3935                                         if(rFalseIfx.condition)
3936                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3937                                         else
3938                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3939                                         
3940                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3941                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3942                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3943                                         
3944                                         while(size > 1)
3945                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3946                                         
3947                                         if(rFalseIfx.condition) {
3948                                                 emitSKPZ;
3949                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3950                                                 
3951                                         } else {
3952                                                 emitSKPNZ;
3953                                         }
3954                                         
3955                                         genSkipc(&rFalseIfx);
3956                                         emitpLabel(truelbl->key);
3957                                         if(ifx) ifx->generated = 1;
3958                                         return;
3959                                         
3960                                 }
3961                                 
3962                                 if(size == 1) {
3963                                         
3964                                         if( (lit & 0xff) == 0) {
3965                                                 /* lower byte is zero */
3966                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3967                                                 i = ((lit >> 8) & 0xff) ^0x80;
3968                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3969                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3970                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3971                                                 genSkipc(&rFalseIfx);
3972                                                 
3973                                                 
3974                                                 if(ifx) ifx->generated = 1;
3975                                                 return;
3976                                                 
3977                                         }
3978                                 } else {
3979                                         /* Special cases for signed longs */
3980                                         if( (lit & 0xffffff) == 0) {
3981                                                 /* lower byte is zero */
3982                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3983                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3984                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3985                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3986                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3987                                                 genSkipc(&rFalseIfx);
3988                                                 
3989                                                 
3990                                                 if(ifx) ifx->generated = 1;
3991                                                 return;
3992                                                 
3993                                         }
3994                                         
3995                                 }
3996                                 
3997                                 
3998                                 if(lit & (0x80 << (size*8))) {
3999                                         /* lit is negative */
4000                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4001                                         
4002                                         //genSkipCond(&rFalseIfx,left,size,7);
4003                                         
4004                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4005                                         
4006                                         if(rFalseIfx.condition)
4007                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4008                                         else
4009                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4010                                         
4011                                         
4012                                 } else {
4013                                         /* lit is positive */
4014                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4015                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
4016                                         if(rFalseIfx.condition)
4017                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4018                                         else
4019                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4020                                         
4021                                 }
4022                                 
4023                                 /* There are no more special cases, so perform a general compare */
4024                                 
4025                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4026                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4027                                 
4028                                 while(size--) {
4029                                         
4030                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4031                                         emitSKPNZ;
4032                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4033                                 }
4034                                 //rFalseIfx.condition ^= 1;
4035                                 genSkipc(&rFalseIfx);
4036                                 
4037                                 emitpLabel(truelbl->key);
4038                                 
4039                                 if(ifx) ifx->generated = 1;
4040                                 return;
4041                                 
4042                                 
4043                         }
4044
4045
4046                         /* sign is out of the way. So now do an unsigned compare */
4047                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4048
4049
4050                         /* General case - compare to an unsigned literal on the right.*/
4051
4052                         i = (lit >> (size*8)) & 0xff;
4053                         emitpcode(POC_MOVLW, popGetLit(i));
4054                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4055                         while(size--) {
4056                                 i = (lit >> (size*8)) & 0xff;
4057                                 
4058                                 if(i) {
4059                                         emitpcode(POC_MOVLW, popGetLit(i));
4060                                         emitSKPNZ;
4061                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4062                                 } else {
4063                                 /* this byte of the lit is zero, 
4064                                         *if it's not the last then OR in the variable */
4065                                         if(size)
4066                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
4067                                 }
4068                         }
4069
4070
4071                 emitpLabel(lbl->key);
4072                 //if(emitFinalCheck)
4073                 genSkipc(&rFalseIfx);
4074                 if(sign)
4075                         emitpLabel(truelbl->key);
4076
4077                 if(ifx) ifx->generated = 1;
4078                 return;
4079
4080
4081                 }
4082 #endif  // _swapp
4083
4084                 if(AOP_TYPE(left) == AOP_LIT) {
4085                         //symbol *lbl = newiTempLabel(NULL);
4086                         
4087                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4088                         
4089                         
4090                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4091                         
4092                         /* Special cases */
4093                         if((lit == 0) && (sign == 0)){
4094                                 
4095                                 size--;
4096                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4097                                 while(size) 
4098                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
4099                                 
4100                                 genSkipz2(&rFalseIfx,0);
4101                                 if(ifx) ifx->generated = 1;
4102                                 return;
4103                         }
4104                         
4105                         if(size==1) {
4106                                 /* Special cases */
4107                                 lit &= 0xff;
4108                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4109                                         /* degenerate compare can never be true */
4110                                         if(rFalseIfx.condition == 0)
4111                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4112                                         
4113                                         if(ifx) ifx->generated = 1;
4114                                         return;
4115                                 }
4116                                 
4117                                 if(sign) {
4118                                         /* signed comparisons to a literal byte */
4119                                         
4120                                         int lp1 = (lit+1) & 0xff;
4121                                         
4122                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4123                                         switch (lp1) {
4124                                         case 0:
4125                                                 rFalseIfx.condition ^= 1;
4126                                                 genSkipCond(&rFalseIfx,right,0,7);
4127                                                 break;
4128                                         case 0x7f:
4129                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4130                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
4131                                                 genSkipz2(&rFalseIfx,1);
4132                                                 break;
4133                                         default:
4134                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4135                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4136                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4137                                                 rFalseIfx.condition ^= 1;
4138                                                 genSkipc(&rFalseIfx);
4139                                                 break;
4140                                         }
4141                                         if(ifx) ifx->generated = 1;
4142                                 } else {
4143                                         /* unsigned comparisons to a literal byte */
4144                                         
4145                                         switch(lit & 0xff ) {
4146                                         case 0:
4147                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4148                                                 genSkipz2(&rFalseIfx,0);
4149                                                 if(ifx) ifx->generated = 1;
4150                                                 break;
4151                                         case 0x7f:
4152                                                 genSkipCond(&rFalseIfx,right,0,7);
4153                                                 if(ifx) ifx->generated = 1;
4154                                                 break;
4155                                                 
4156                                         default:
4157                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4158                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4159                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4160                                                 rFalseIfx.condition ^= 1;
4161                                                 if (AOP_TYPE(result) == AOP_CRY) {
4162                                                         genSkipc(&rFalseIfx);
4163                                                         if(ifx) ifx->generated = 1;
4164                                                 } else {
4165                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4166                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4167                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4168                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4169                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4170                                                 }       
4171                                                 break;
4172                                         }
4173                                 }
4174                                 
4175                                 //goto check_carry;
4176                                 return;
4177                                 
4178                         } else {
4179                                 
4180                                 /* Size is greater than 1 */
4181                                 
4182                                 if(sign) {
4183                                         int lp1 = lit+1;
4184                                         
4185                                         size--;
4186                                         
4187                                         if(lp1 == 0) {
4188                                                 /* this means lit = 0xffffffff, or -1 */
4189                                                 
4190                                                 
4191                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4192                                                 rFalseIfx.condition ^= 1;
4193                                                 genSkipCond(&rFalseIfx,right,size,7);
4194                                                 if(ifx) ifx->generated = 1;
4195                                                 return;
4196                                         }
4197                                         
4198                                         if(lit == 0) {
4199                                                 int s = size;
4200                                                 
4201                                                 if(rFalseIfx.condition) {
4202                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4203                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4204                                                 }
4205                                                 
4206                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4207                                                 while(size--)
4208                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4209                                                 
4210                                                 
4211                                                 emitSKPZ;
4212                                                 if(rFalseIfx.condition) {
4213                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4214                                                         emitpLabel(truelbl->key);
4215                                                 }else {
4216                                                         rFalseIfx.condition ^= 1;
4217                                                         genSkipCond(&rFalseIfx,right,s,7);
4218                                                 }
4219                                                 
4220                                                 if(ifx) ifx->generated = 1;
4221                                                 return;
4222                                         }
4223                                         
4224                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4225                                                 /* lower byte of signed word is zero */
4226                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4227                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4228                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4229                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4230                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4231                                                 rFalseIfx.condition ^= 1;
4232                                                 genSkipc(&rFalseIfx);
4233                                                 
4234                                                 
4235                                                 if(ifx) ifx->generated = 1;
4236                                                 return;
4237                                         }
4238                                         
4239                                         if(lit & (0x80 << (size*8))) {
4240                                                 /* Lit is less than zero */
4241                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4242                                                 //rFalseIfx.condition ^= 1;
4243                                                 //genSkipCond(&rFalseIfx,left,size,7);
4244                                                 //rFalseIfx.condition ^= 1;
4245                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4246                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4247                                                 
4248                                                 if(rFalseIfx.condition)
4249                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4250                                                 else
4251                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4252                                                 
4253                                                 
4254                                         } else {
4255                                                 /* Lit is greater than or equal to zero */
4256                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4257                                                 //rFalseIfx.condition ^= 1;
4258                                                 //genSkipCond(&rFalseIfx,right,size,7);
4259                                                 //rFalseIfx.condition ^= 1;
4260                                                 
4261                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4262                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4263                                                 
4264                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4265                                                 if(rFalseIfx.condition)
4266                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4267                                                 else
4268                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4269                                                 
4270                                         }
4271                                         
4272                                         
4273                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4274                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4275                                         
4276                                         while(size--) {
4277                                                 
4278                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4279                                                 emitSKPNZ;
4280                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4281                                         }
4282                                         rFalseIfx.condition ^= 1;
4283                                         //rFalseIfx.condition = 1;
4284                                         genSkipc(&rFalseIfx);
4285                                         
4286                                         emitpLabel(truelbl->key);
4287                                         
4288                                         if(ifx) ifx->generated = 1;
4289                                         return;
4290                                         // end of if (sign)
4291                                 } else {
4292                                         
4293                                         /* compare word or long to an unsigned literal on the right.*/
4294                                         
4295                                         
4296                                         size--;
4297                                         if(lit < 0xff) {
4298                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4299                                                 switch (lit) {
4300                                                 case 0:
4301                                                         break; /* handled above */
4302                                                 /*
4303                                                 case 0xff:
4304                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4305                                                         while(size--)
4306                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4307                                                         genSkipz2(&rFalseIfx,0);
4308                                                         break;
4309                                                 */
4310                                                 default:
4311                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4312                                                         while(--size)
4313                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4314                                                         
4315                                                         emitSKPZ;
4316                                                         if(rFalseIfx.condition)
4317                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4318                                                         else
4319                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4320                                                         
4321                                                         
4322                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4323                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4324                                                         
4325                                                         rFalseIfx.condition ^= 1;
4326                                                         genSkipc(&rFalseIfx);
4327                                                 }
4328                                                 
4329                                                 emitpLabel(truelbl->key);
4330                                                 
4331                                                 if(ifx) ifx->generated = 1;
4332                                                 return;
4333                                         }
4334                                         
4335                                         
4336                                         lit++;
4337                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4338                                         i = (lit >> (size*8)) & 0xff;
4339                                         
4340                                         emitpcode(POC_MOVLW, popGetLit(i));
4341                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4342                                         
4343                                         while(size--) {
4344                                                 i = (lit >> (size*8)) & 0xff;
4345                                                 
4346                                                 if(i) {
4347                                                         emitpcode(POC_MOVLW, popGetLit(i));
4348                                                         emitSKPNZ;
4349                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4350                                                 } else {
4351                                                 /* this byte of the lit is zero, 
4352                                                         *if it's not the last then OR in the variable */
4353                                                         if(size)
4354                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4355                                                 }
4356                                         }
4357                                         
4358                                         
4359                                         emitpLabel(lbl->key);
4360                                         
4361                                         rFalseIfx.condition ^= 1;
4362                                         genSkipc(&rFalseIfx);
4363                                 }
4364                                 
4365                                 if(sign)
4366                                         emitpLabel(truelbl->key);
4367                                 if(ifx) ifx->generated = 1;
4368                                 return;
4369                         }
4370                 }
4371                 /* Compare two variables */
4372                 
4373                 DEBUGpic14_emitcode(";sign","%d",sign);
4374                 
4375                 size--;
4376                 if(sign) {
4377                         /* Sigh. thus sucks... */
4378                         if(size) {
4379                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4380                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4381                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4382                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4383                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4384                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4385                         } else {
4386                                 /* Signed char comparison */
4387                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4388                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4389                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4390                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4391                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4392                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4393                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4394                                 
4395                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4396                                 genSkipc(&rFalseIfx);
4397                                 
4398                                 if(ifx) ifx->generated = 1;
4399                                 return;
4400                         }
4401                         
4402                 } else {
4403                         
4404                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4405                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4406                 }
4407                 
4408                 
4409                 /* The rest of the bytes of a multi-byte compare */
4410                 while (size) {
4411                         
4412                         emitSKPZ;
4413                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4414                         size--;
4415                         
4416                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4417                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4418                         
4419                         
4420                 }
4421                 
4422                 emitpLabel(lbl->key);
4423                 
4424                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4425                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4426                         (AOP_TYPE(result) == AOP_REG)) {
4427                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4428                         emitpcode(POC_RLF, popGet(AOP(result),0));
4429                 } else {
4430                         genSkipc(&rFalseIfx);
4431                 }       
4432                 //genSkipc(&rFalseIfx);
4433                 if(ifx) ifx->generated = 1;
4434                 
4435                 return;
4436                 
4437         }
4438         
4439         // check_carry:
4440         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4441                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4442                 pic14_outBitC(result);
4443         } else {
4444                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4445                 /* if the result is used in the next
4446                 ifx conditional branch then generate
4447                 code a little differently */
4448                 if (ifx )
4449                         genIfxJump (ifx,"c");
4450                 else
4451                         pic14_outBitC(result);
4452                 /* leave the result in acc */
4453         }
4454         
4455 }
4456
4457 /*-----------------------------------------------------------------*/
4458 /* genCmpGt :- greater than comparison                             */
4459 /*-----------------------------------------------------------------*/
4460 static void genCmpGt (iCode *ic, iCode *ifx)
4461 {
4462         operand *left, *right, *result;
4463         sym_link *letype , *retype;
4464         int sign ;
4465         
4466         FENTRY;
4467         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4468         left = IC_LEFT(ic);
4469         right= IC_RIGHT(ic);
4470         result = IC_RESULT(ic);
4471         
4472         letype = getSpec(operandType(left));
4473         retype =getSpec(operandType(right));
4474         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4475         /* assign the amsops */
4476         aopOp (left,ic,FALSE);
4477         aopOp (right,ic,FALSE);
4478         aopOp (result,ic,TRUE);
4479         
4480         genCmp(right, left, result, ifx, sign);
4481         
4482         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4483         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4484         freeAsmop(result,NULL,ic,TRUE); 
4485 }
4486
4487 /*-----------------------------------------------------------------*/
4488 /* genCmpLt - less than comparisons                                */
4489 /*-----------------------------------------------------------------*/
4490 static void genCmpLt (iCode *ic, iCode *ifx)
4491 {
4492         operand *left, *right, *result;
4493         sym_link *letype , *retype;
4494         int sign ;
4495         
4496         FENTRY;
4497         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4498         left = IC_LEFT(ic);
4499         right= IC_RIGHT(ic);
4500         result = IC_RESULT(ic);
4501         
4502         letype = getSpec(operandType(left));
4503         retype =getSpec(operandType(right));
4504         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4505         
4506         /* assign the amsops */
4507         aopOp (left,ic,FALSE);
4508         aopOp (right,ic,FALSE);
4509         aopOp (result,ic,TRUE);
4510         
4511         genCmp(left, right, result, ifx, sign);
4512         
4513         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4514         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4515         freeAsmop(result,NULL,ic,TRUE); 
4516 }
4517
4518 /*-----------------------------------------------------------------*/
4519 /* genc16bit2lit - compare a 16 bit value to a literal             */
4520 /*-----------------------------------------------------------------*/
4521 static void genc16bit2lit(operand *op, int lit, int offset)
4522 {
4523         int i;
4524         
4525         FENTRY;
4526         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4527         if( (lit&0xff) == 0) 
4528                 i=1;
4529         else
4530                 i=0;
4531         
4532         emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
4533         switch( BYTEofLONG(lit,i)) { 
4534         case 0:
4535                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4536                 break;
4537         case 1:
4538                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4539                 break;
4540         case 0xff:
4541                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4542                 break;
4543         default:
4544                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4545                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4546         }
4547         
4548         i ^= 1;
4549         
4550         emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
4551         switch( BYTEofLONG(lit,i)) { 
4552         case 0:
4553                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4554                 break;
4555         case 1:
4556                 emitSKPNZ;
4557                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4558                 break;
4559         case 0xff:
4560                 emitSKPNZ;
4561                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4562                 break;
4563         default:
4564                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4565                 emitSKPNZ;
4566                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4567                 
4568         }
4569         
4570 }
4571
4572 /*-----------------------------------------------------------------*/
4573 /* gencjneshort - compare and jump if not equal                    */
4574 /*-----------------------------------------------------------------*/
4575 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4576 {
4577         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4578         int offset = 0;
4579         int res_offset = 0;  /* the result may be a different size then left or right */
4580         int res_size = AOP_SIZE(result);
4581         resolvedIfx rIfx;
4582         symbol *lbl;
4583         
4584         unsigned long lit = 0L;
4585         FENTRY;
4586         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4587         DEBUGpic14_AopType(__LINE__,left,right,result);
4588         if(result)
4589                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4590         resolveIfx(&rIfx,ifx);
4591         lbl =  newiTempLabel(NULL);
4592         
4593         
4594         /* if the left side is a literal or 
4595         if the right is in a pointer register and left 
4596         is not */
4597         if ((AOP_TYPE(left) == AOP_LIT) || 
4598                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4599                 operand *t = right;
4600                 right = left;
4601                 left = t;
4602         }
4603         if(AOP_TYPE(right) == AOP_LIT)
4604                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4605         
4606         /* if the right side is a literal then anything goes */
4607         if (AOP_TYPE(right) == AOP_LIT &&
4608                 AOP_TYPE(left) != AOP_DIR ) {
4609                 switch(size) {
4610                 case 2:
4611                         genc16bit2lit(left, lit, 0);
4612                         emitSKPNZ;
4613                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4614                         break;
4615                 default:
4616                         while (size--) {
4617                                 if(lit & 0xff) {
4618                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4620                                 } else {
4621                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4622                                 }
4623                                 
4624                                 emitSKPNZ;
4625                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4626                                 offset++;
4627                                 if(res_offset < res_size-1)
4628                                         res_offset++;
4629                                 lit >>= 8;
4630                         }
4631                         break;
4632                 }
4633         }
4634         
4635         /* if the right side is in a register or in direct space or
4636         if the left is a pointer register & right is not */    
4637         else if (AOP_TYPE(right) == AOP_REG ||
4638                 AOP_TYPE(right) == AOP_DIR || 
4639                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4640                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4641                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4642                 int lbl_key = lbl->key;
4643                 
4644                 if(result) {
4645                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4646                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4647                 }else {
4648                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4649                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4650                                 __FUNCTION__,__LINE__);
4651                         return;
4652                 }
4653                 
4654                 /*     switch(size) { */
4655                 /*     case 2: */
4656                 /*       genc16bit2lit(left, lit, 0); */
4657                 /*       emitSKPNZ; */
4658                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4659                 /*       break; */
4660                 /*     default: */
4661                 while (size--) {
4662                         int emit_skip=1;
4663                         if((AOP_TYPE(left) == AOP_DIR) && 
4664                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4665                                 
4666                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4667                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4668                                 
4669                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4670                                 
4671                                 switch (lit & 0xff) {
4672                                 case 0:
4673                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4674                                         break;
4675                                 case 1:
4676                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4677                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4678                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4679                                         emit_skip=0;
4680                                         break;
4681                                 case 0xff:
4682                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4683                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4684                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4685                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4686                                         emit_skip=0;
4687                                         break;
4688                                 default:
4689                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4690                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4691                                 }
4692                                 lit >>= 8;
4693                                 
4694                         } else {
4695                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4696                         }
4697                         if(emit_skip) {
4698                                 if(AOP_TYPE(result) == AOP_CRY) {
4699                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4700                                         if(rIfx.condition)
4701                                                 emitSKPNZ;
4702                                         else
4703                                                 emitSKPZ;
4704                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4705                                 } else {
4706                                         /* fix me. probably need to check result size too */
4707                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4708                                         if(rIfx.condition)
4709                                                 emitSKPZ;
4710                                         else
4711                                                 emitSKPNZ;
4712                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4713                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4714                                 }
4715                                 if(ifx)
4716                                         ifx->generated=1;
4717                         }
4718                         emit_skip++;
4719                         offset++;
4720                         if(res_offset < res_size-1)
4721                                 res_offset++;
4722                 }
4723                 /*       break; */
4724                 /*     } */
4725         } else if(AOP_TYPE(right) == AOP_REG &&
4726                 AOP_TYPE(left) != AOP_DIR){
4727                 
4728                 while(size--) {
4729                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4730                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4731                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4732                         if(rIfx.condition)
4733                                 emitSKPNZ;
4734                         else
4735                                 emitSKPZ;
4736                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4737                         offset++;
4738                         if(res_offset < res_size-1)
4739                                 res_offset++;
4740                 }
4741                 
4742         }else{
4743                 /* right is a pointer reg need both a & b */
4744                 while(size--) {
4745                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4746                         if(strcmp(l,"b"))
4747                                 pic14_emitcode("mov","b,%s",l);
4748                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4749                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4750                         offset++;
4751                 }
4752         }
4753         
4754         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4755         if(!rIfx.condition)
4756                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4757         
4758         emitpLabel(lbl->key);
4759         
4760         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4761         
4762         if(ifx)
4763                 ifx->generated = 1;
4764 }
4765
4766 #if 0
4767 /*-----------------------------------------------------------------*/
4768 /* gencjne - compare and jump if not equal                         */
4769 /*-----------------------------------------------------------------*/
4770 static void gencjne(operand *left, operand *right, iCode *ifx)
4771 {
4772         symbol *tlbl  = newiTempLabel(NULL);
4773         
4774         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4775         gencjneshort(left, right, lbl);
4776         
4777         pic14_emitcode("mov","a,%s",one);
4778         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4779         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4780         pic14_emitcode("clr","a");
4781         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4782         
4783         emitpLabel(lbl->key);
4784         emitpLabel(tlbl->key);
4785         
4786 }
4787 #endif
4788
4789 /*-----------------------------------------------------------------*/
4790 /* genCmpEq - generates code for equal to                          */
4791 /*-----------------------------------------------------------------*/
4792 static void genCmpEq (iCode *ic, iCode *ifx)
4793 {
4794         operand *left, *right, *result;
4795         unsigned long lit = 0L;
4796         int size,offset=0;
4797         
4798         FENTRY;
4799         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4800         
4801         if(ifx)
4802                 DEBUGpic14_emitcode ("; ifx is non-null","");
4803         else
4804                 DEBUGpic14_emitcode ("; ifx is null","");
4805         
4806         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4807         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4808         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4809         
4810         size = max(AOP_SIZE(left),AOP_SIZE(right));
4811         
4812         DEBUGpic14_AopType(__LINE__,left,right,result);
4813         
4814         /* if literal, literal on the right or 
4815         if the right is in a pointer register and left 
4816         is not */
4817         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4818                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4819                 operand *tmp = right ;
4820                 right = left;
4821                 left = tmp;
4822         }
4823         
4824         
4825         if(ifx && !AOP_SIZE(result)){
4826                 symbol *tlbl;
4827                 /* if they are both bit variables */
4828                 if (AOP_TYPE(left) == AOP_CRY &&
4829                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4830                         if(AOP_TYPE(right) == AOP_LIT){
4831                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4832                                 if(lit == 0L){
4833                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4834                                         pic14_emitcode("cpl","c");
4835                                 } else if(lit == 1L) {
4836                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4837                                 } else {
4838                                         pic14_emitcode("clr","c");
4839                                 }
4840                                 /* AOP_TYPE(right) == AOP_CRY */
4841                         } else {
4842                                 symbol *lbl = newiTempLabel(NULL);
4843                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4844                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4845                                 pic14_emitcode("cpl","c");
4846                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4847                         }
4848                         /* if true label then we jump if condition
4849                         supplied is true */
4850                         tlbl = newiTempLabel(NULL);
4851                         if ( IC_TRUE(ifx) ) {
4852                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4853                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4854                         } else {
4855                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4856                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4857                         }
4858                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4859                         
4860                         {
4861                                 /* left and right are both bit variables, result is carry */
4862                                 resolvedIfx rIfx;
4863                                 
4864                                 resolveIfx(&rIfx,ifx);
4865                                 
4866                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4867                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4868                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4869                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4870                                 genSkipz2(&rIfx,0);
4871                         }
4872                 } else {
4873                         
4874                         /* They're not both bit variables. Is the right a literal? */
4875                         if(AOP_TYPE(right) == AOP_LIT) {
4876                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4877                                 
4878                                 switch(size) {
4879                                         
4880                                 case 1:
4881                                         switch(lit & 0xff) {
4882                                         case 1:
4883                                                 if ( IC_TRUE(ifx) ) {
4884                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4885                                                         emitSKPNZ;
4886                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4887                                                 } else {
4888                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4889                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4890                                                 }
4891                                                 break;
4892                                         case 0xff:
4893                                                 if ( IC_TRUE(ifx) ) {
4894                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4895                                                         emitSKPNZ;
4896                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4897                                                 } else {
4898                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4899                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4900                                                 }
4901                                                 break;
4902                                         default:
4903                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4904                                                 if(lit)
4905                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4906                                                 genSkip(ifx,'z');
4907                                         }
4908                                         
4909                                         
4910                                         /* end of size == 1 */
4911                                         break;
4912                                         
4913                                         case 2:
4914                                                 genc16bit2lit(left,lit,offset);
4915                                                 genSkip(ifx,'z');
4916                                                 break;
4917                                                 /* end of size == 2 */
4918                                                 
4919                                         default:
4920                                                 /* size is 4 */
4921                                                 if(lit==0) {
4922                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4923                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4924                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4925                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4926                                                         
4927                                                 } else {
4928                                                         
4929                                                         /* search for patterns that can be optimized */
4930                                                         
4931                                                         genc16bit2lit(left,lit,0);
4932                                                         lit >>= 16;
4933                                                         if(lit) {
4934                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4935                                                                 //genSkip(ifx,'z');
4936                                                                 genc16bit2lit(left,lit,2);
4937                                                         } else {
4938                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4939                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4940                                                                 
4941                                                         }
4942                                                         
4943                                                 }
4944                                                 
4945                                                 genSkip(ifx,'z');
4946                                 }
4947                                 
4948                                 ifx->generated = 1;
4949                                 goto release ;
4950                                 
4951                                 
4952                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4953                                 /* we know the left is not a bit, but that the right is */
4954                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4955                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4956                                         popGet(AOP(right),offset));
4957                                 emitpcode(POC_XORLW,popGetLit(1));
4958                                 
4959                                 /* if the two are equal, then W will be 0 and the Z bit is set
4960                                 * we could test Z now, or go ahead and check the high order bytes if
4961                                 * the variable we're comparing is larger than a byte. */
4962                                 
4963                                 while(--size)
4964                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4965                                 
4966                                 if ( IC_TRUE(ifx) ) {
4967                                         emitSKPNZ;
4968                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4969                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4970                                 } else {
4971                                         emitSKPZ;
4972                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4973                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4974                                 }
4975                                 
4976                         } else {
4977                                 /* They're both variables that are larger than bits */
4978                                 int s = size;
4979                                 
4980                                 tlbl = newiTempLabel(NULL);
4981                                 
4982                                 while(size--) {
4983                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4984                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4985                                         
4986                                         if ( IC_TRUE(ifx) ) {
4987                                                 if(size) {
4988                                                         emitSKPZ;
4989                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4990                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4991                                                 } else {
4992                                                         emitSKPNZ;
4993                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4994                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4995                                                 }
4996                                         } else {
4997                                                 emitSKPZ;
4998                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4999                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5000                                         }
5001                                         offset++;
5002                                 }
5003                                 if(s>1 && IC_TRUE(ifx)) {
5004                                         emitpLabel(tlbl->key);
5005                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
5006                                 }
5007                         }
5008                 }
5009                 /* mark the icode as generated */
5010                 ifx->generated = 1;
5011                 goto release ;
5012         }
5013   
5014   /* if they are both bit variables */
5015   if (AOP_TYPE(left) == AOP_CRY &&
5016           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5017           if(AOP_TYPE(right) == AOP_LIT){
5018                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5019                   if(lit == 0L){
5020                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5021                           pic14_emitcode("cpl","c");
5022                   } else if(lit == 1L) {
5023                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5024                   } else {
5025                           pic14_emitcode("clr","c");
5026                   }
5027                   /* AOP_TYPE(right) == AOP_CRY */
5028           } else {
5029                   symbol *lbl = newiTempLabel(NULL);
5030                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5031                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5032                   pic14_emitcode("cpl","c");
5033                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
5034           }
5035           /* c = 1 if egal */
5036           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5037                   pic14_outBitC(result);
5038                   goto release ;
5039           }
5040           if (ifx) {
5041                   genIfxJump (ifx,"c");
5042                   goto release ;
5043           }
5044           /* if the result is used in an arithmetic operation
5045           then put the result in place */
5046           pic14_outBitC(result);
5047   } else {
5048           
5049           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5050           gencjne(left,right,result,ifx);
5051           /*
5052           if(ifx) 
5053           gencjne(left,right,newiTempLabel(NULL));
5054           else {
5055           if(IC_TRUE(ifx)->key)
5056           gencjne(left,right,IC_TRUE(ifx)->key);
5057           else
5058           gencjne(left,right,IC_FALSE(ifx)->key);
5059           ifx->generated = 1;
5060           goto release ;
5061           }
5062           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5063           aopPut(AOP(result),"a",0);
5064           goto release ;
5065           }
5066           
5067                 if (ifx) {
5068                 genIfxJump (ifx,"a");
5069                 goto release ;
5070                 }
5071           */
5072           /* if the result is used in an arithmetic operation
5073           then put the result in place */
5074           /*
5075           if (AOP_TYPE(result) != AOP_CRY) 
5076           pic14_outAcc(result);
5077           */
5078           /* leave the result in acc */
5079   }
5080   
5081 release:
5082   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5083   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084   freeAsmop(result,NULL,ic,TRUE);
5085 }
5086
5087 /*-----------------------------------------------------------------*/
5088 /* ifxForOp - returns the icode containing the ifx for operand     */
5089 /*-----------------------------------------------------------------*/
5090 static iCode *ifxForOp ( operand *op, iCode *ic )
5091 {
5092         FENTRY;
5093         /* if true symbol then needs to be assigned */
5094         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5095         if (IS_TRUE_SYMOP(op))
5096                 return NULL ;
5097         
5098         /* if this has register type condition and
5099         the next instruction is ifx with the same operand
5100         and live to of the operand is upto the ifx only then */
5101         if (ic->next &&
5102                 ic->next->op == IFX &&
5103                 IC_COND(ic->next)->key == op->key &&
5104                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5105                 return ic->next;
5106         
5107         if (ic->next &&
5108                 ic->next->op == IFX &&
5109                 IC_COND(ic->next)->key == op->key) {
5110                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5111                 return ic->next;
5112         }
5113         
5114         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5115         if (ic->next &&
5116                 ic->next->op == IFX)
5117                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5118         
5119         if (ic->next &&
5120                 ic->next->op == IFX &&
5121                 IC_COND(ic->next)->key == op->key) {
5122                 DEBUGpic14_emitcode ("; "," key is okay");
5123                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5124                         OP_SYMBOL(op)->liveTo,
5125                         ic->next->seq);
5126         }
5127         
5128         
5129         return NULL;
5130 }
5131 /*-----------------------------------------------------------------*/
5132 /* genAndOp - for && operation                                     */
5133 /*-----------------------------------------------------------------*/
5134 static void genAndOp (iCode *ic)
5135 {
5136         operand *left,*right, *result;
5137         /*     symbol *tlbl; */
5138         
5139         FENTRY;
5140         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5141         /* note here that && operations that are in an
5142         if statement are taken away by backPatchLabels
5143         only those used in arthmetic operations remain */
5144         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5145         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5146         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5147         
5148         DEBUGpic14_AopType(__LINE__,left,right,result);
5149         
5150         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5151         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5152         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5153         
5154         /* if both are bit variables */
5155         /*     if (AOP_TYPE(left) == AOP_CRY && */
5156         /*         AOP_TYPE(right) == AOP_CRY ) { */
5157         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5158         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5159         /*         pic14_outBitC(result); */
5160         /*     } else { */
5161         /*         tlbl = newiTempLabel(NULL); */
5162         /*         pic14_toBoolean(left);     */
5163         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5164         /*         pic14_toBoolean(right); */
5165         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5166         /*         pic14_outBitAcc(result); */
5167         /*     } */
5168         
5169         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5170         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171         freeAsmop(result,NULL,ic,TRUE);
5172 }
5173
5174
5175 /*-----------------------------------------------------------------*/
5176 /* genOrOp - for || operation                                      */
5177 /*-----------------------------------------------------------------*/
5178 /*
5179 tsd pic port -
5180 modified this code, but it doesn't appear to ever get called
5181 */
5182
5183 static void genOrOp (iCode *ic)
5184 {
5185         operand *left,*right, *result;
5186         symbol *tlbl;
5187         
5188         /* note here that || operations that are in an
5189         if statement are taken away by backPatchLabels
5190         only those used in arthmetic operations remain */
5191         FENTRY;
5192         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5193         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5194         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5195         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5196         
5197         DEBUGpic14_AopType(__LINE__,left,right,result);
5198         
5199         /* if both are bit variables */
5200         if (AOP_TYPE(left) == AOP_CRY &&
5201                 AOP_TYPE(right) == AOP_CRY ) {
5202                 pic14_emitcode("clrc","");
5203                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5204                         AOP(left)->aopu.aop_dir,
5205                         AOP(left)->aopu.aop_dir);
5206                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5207                         AOP(right)->aopu.aop_dir,
5208                         AOP(right)->aopu.aop_dir);
5209                 pic14_emitcode("setc","");
5210                 
5211         } else {
5212                 tlbl = newiTempLabel(NULL);
5213                 pic14_toBoolean(left);
5214                 emitSKPZ;
5215                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5216                 pic14_toBoolean(right);
5217                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5218                 
5219                 pic14_outBitAcc(result);
5220         }
5221         
5222         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5223         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5224         freeAsmop(result,NULL,ic,TRUE);            
5225 }
5226
5227 /*-----------------------------------------------------------------*/
5228 /* isLiteralBit - test if lit == 2^n                               */
5229 /*-----------------------------------------------------------------*/
5230 static int isLiteralBit(unsigned long lit)
5231 {
5232         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5233                 0x100L,0x200L,0x400L,0x800L,
5234                 0x1000L,0x2000L,0x4000L,0x8000L,
5235                 0x10000L,0x20000L,0x40000L,0x80000L,
5236                 0x100000L,0x200000L,0x400000L,0x800000L,
5237                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5238                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5239         int idx;
5240         
5241         FENTRY;
5242         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5243         for(idx = 0; idx < 32; idx++)
5244                 if(lit == pw[idx])
5245                         return idx+1;
5246                 return 0;
5247 }
5248
5249 /*-----------------------------------------------------------------*/
5250 /* continueIfTrue -                                                */
5251 /*-----------------------------------------------------------------*/
5252 static void continueIfTrue (iCode *ic)
5253 {
5254         FENTRY;
5255         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5256         if(IC_TRUE(ic))
5257                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5258         ic->generated = 1;
5259 }
5260
5261 /*-----------------------------------------------------------------*/
5262 /* jmpIfTrue -                                                     */
5263 /*-----------------------------------------------------------------*/
5264 static void jumpIfTrue (iCode *ic)
5265 {
5266         FENTRY;
5267         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5268         if(!IC_TRUE(ic))
5269                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5270         ic->generated = 1;
5271 }
5272
5273 /*-----------------------------------------------------------------*/
5274 /* jmpTrueOrFalse -                                                */
5275 /*-----------------------------------------------------------------*/
5276 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5277 {
5278         FENTRY;
5279         // ugly but optimized by peephole
5280         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5281         if(IC_TRUE(ic)){
5282                 symbol *nlbl = newiTempLabel(NULL);
5283                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5284                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5285                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5286                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5287         }
5288         else{
5289                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5290                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5291         }
5292         ic->generated = 1;
5293 }
5294
5295 /*-----------------------------------------------------------------*/
5296 /* genAnd  - code for and                                          */
5297 /*-----------------------------------------------------------------*/
5298 static void genAnd (iCode *ic, iCode *ifx)
5299 {
5300         operand *left, *right, *result;
5301         int size, offset=0;  
5302         unsigned long lit = 0L;
5303         int bytelit = 0;
5304         resolvedIfx rIfx;
5305         
5306         FENTRY;
5307         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5308         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5309         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5310         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5311         
5312         resolveIfx(&rIfx,ifx);
5313         
5314         /* if left is a literal & right is not then exchange them */
5315         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5316                 AOP_NEEDSACC(left)) {
5317                 operand *tmp = right ;
5318                 right = left;
5319                 left = tmp;
5320         }
5321         
5322         /* if result = right then exchange them */
5323         if(pic14_sameRegs(AOP(result),AOP(right))){
5324                 operand *tmp = right ;
5325                 right = left;
5326                 left = tmp;
5327         }
5328         
5329         /* if right is bit then exchange them */
5330         if (AOP_TYPE(right) == AOP_CRY &&
5331                 AOP_TYPE(left) != AOP_CRY){
5332                 operand *tmp = right ;
5333                 right = left;
5334                 left = tmp;
5335         }
5336         if(AOP_TYPE(right) == AOP_LIT)
5337                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5338         
5339         size = AOP_SIZE(result);
5340         
5341         DEBUGpic14_AopType(__LINE__,left,right,result);
5342         
5343         // if(bit & yy)
5344         // result = bit & yy;
5345         if (AOP_TYPE(left) == AOP_CRY){
5346                 // c = bit & literal;
5347                 if(AOP_TYPE(right) == AOP_LIT){
5348                         if(lit & 1) {
5349                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5350                                         // no change
5351                                         goto release;
5352                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5353                         } else {
5354                                 // bit(result) = 0;
5355                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5356                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5357                                         goto release;
5358                                 }
5359                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5360                                         jumpIfTrue(ifx);
5361                                         goto release;
5362                                 }
5363                                 pic14_emitcode("clr","c");
5364                         }
5365                 } else {
5366                         if (AOP_TYPE(right) == AOP_CRY){
5367                                 // c = bit & bit;
5368                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5369                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5370                         } else {
5371                                 // c = bit & val;
5372                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5373                                 // c = lsb
5374                                 pic14_emitcode("rrc","a");
5375                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5376                         }
5377                 }
5378                 // bit = c
5379                 // val = c
5380                 if(size)
5381                         pic14_outBitC(result);
5382                 // if(bit & ...)
5383                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5384                         genIfxJump(ifx, "c");           
5385                 goto release ;
5386         }
5387         
5388         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5389         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5390         if((AOP_TYPE(right) == AOP_LIT) &&
5391                 (AOP_TYPE(result) == AOP_CRY) &&
5392                 (AOP_TYPE(left) != AOP_CRY)){
5393                 int posbit = isLiteralBit(lit);
5394                 /* left &  2^n */
5395                 if(posbit){
5396                         posbit--;
5397                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5398                         // bit = left & 2^n
5399                         if(size)
5400                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5401                         // if(left &  2^n)
5402                         else{
5403                                 if(ifx){
5404                                         int offset = 0;
5405                                         while (posbit > 7) {
5406                                                 posbit -= 8;
5407                                                 offset++;
5408                                         }
5409                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5410                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5411                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5412                                         
5413                                         ifx->generated = 1;
5414                                 }
5415                                 goto release;
5416                         }
5417                 } else {
5418                         symbol *tlbl = newiTempLabel(NULL);
5419                         int sizel = AOP_SIZE(left);
5420                         if(size)
5421                                 pic14_emitcode("setb","c");
5422                         while(sizel--){
5423                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5424                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5425                                         // byte ==  2^n ?
5426                                         if((posbit = isLiteralBit(bytelit)) != 0)
5427                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5428                                         else{
5429                                                 if(bytelit != 0x0FFL)
5430                                                         pic14_emitcode("anl","a,%s",
5431                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5432                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5433                                         }
5434                                 }
5435                                 offset++;
5436                         }
5437                         // bit = left & literal
5438                         if(size){
5439                                 pic14_emitcode("clr","c");
5440                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5441                         }
5442                         // if(left & literal)
5443                         else{
5444                                 if(ifx)
5445                                         jmpTrueOrFalse(ifx, tlbl);
5446                                 goto release ;
5447                         }
5448                 }
5449                 pic14_outBitC(result);
5450                 goto release ;
5451         }
5452         
5453         /* if left is same as result */
5454         if(pic14_sameRegs(AOP(result),AOP(left))){
5455                 int know_W = -1;
5456                 for(;size--; offset++,lit>>=8) {
5457                         if(AOP_TYPE(right) == AOP_LIT){
5458                                 switch(lit & 0xff) {
5459                                 case 0x00:
5460                                         /*  and'ing with 0 has clears the result */
5461                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5462                                         break;
5463                                 case 0xff:
5464                                         /* and'ing with 0xff is a nop when the result and left are the same */
5465                                         break;
5466                                         
5467                                 default:
5468                                         {
5469                                                 int p = my_powof2( (~lit) & 0xff );
5470                                                 if(p>=0) {
5471                                                         /* only one bit is set in the literal, so use a bcf instruction */
5472                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5473                                                         
5474                                                 } else {
5475                                                         if(know_W != (int)(lit&0xff))
5476                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5477                                                         know_W = lit &0xff;
5478                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5479                                                 }
5480                                         }    
5481                                 }
5482                         } else {
5483                                 if (AOP_TYPE(left) == AOP_ACC) {
5484                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5485                                 } else {        
5486                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5487                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5488                                         
5489                                 }
5490                         }
5491                 }
5492                 
5493         } else {
5494                 // left & result in different registers
5495                 if(AOP_TYPE(result) == AOP_CRY){
5496                         // result = bit
5497                         // if(size), result in bit
5498                         // if(!size && ifx), conditional oper: if(left & right)
5499                         symbol *tlbl = newiTempLabel(NULL);
5500                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5501                         if(size)
5502                                 pic14_emitcode("setb","c");
5503                         while(sizer--){
5504                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5505                                 pic14_emitcode("anl","a,%s",
5506                                         aopGet(AOP(left),offset,FALSE,FALSE));
5507                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5508                                 offset++;
5509                         }
5510                         if(size){
5511                                 CLRC;
5512                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5513                                 pic14_outBitC(result);
5514                         } else if(ifx)
5515                                 jmpTrueOrFalse(ifx, tlbl);
5516                 } else {
5517                         for(;(size--);offset++) {
5518                                 // normal case
5519                                 // result = left & right
5520                                 if(AOP_TYPE(right) == AOP_LIT){
5521                                         int t = (lit >> (offset*8)) & 0x0FFL;
5522                                         switch(t) { 
5523                                         case 0x00:
5524                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5525                                                 break;
5526                                         case 0xff:
5527                                                 if(AOP_TYPE(left) != AOP_ACC) {
5528                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5529                                                 }
5530                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5531                                                 break;
5532                                         default:
5533                                                 if(AOP_TYPE(left) == AOP_ACC) {
5534                                                         emitpcode(POC_ANDLW, popGetLit(t));
5535                                                 } else {
5536                                                         emitpcode(POC_MOVLW, popGetLit(t));
5537                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5538                                                 }
5539                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5540                                         }
5541                                         continue;
5542                                 }
5543                                 
5544                                 if (AOP_TYPE(left) == AOP_ACC) {
5545                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5546                                 } else {
5547                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5548                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5549                                 }
5550                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5551                         }
5552                 }
5553         }
5554         
5555 release :
5556         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5557         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5558         freeAsmop(result,NULL,ic,TRUE);     
5559 }
5560
5561 /*-----------------------------------------------------------------*/
5562 /* genOr  - code for or                                            */
5563 /*-----------------------------------------------------------------*/
5564 static void genOr (iCode *ic, iCode *ifx)
5565 {
5566         operand *left, *right, *result;
5567         int size, offset=0;
5568         unsigned long lit = 0L;
5569         
5570         FENTRY;
5571         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5572         
5573         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5574         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5575         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5576         
5577         DEBUGpic14_AopType(__LINE__,left,right,result);
5578         
5579         /* if left is a literal & right is not then exchange them */
5580         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5581                 AOP_NEEDSACC(left)) {
5582                 operand *tmp = right ;
5583                 right = left;
5584                 left = tmp;
5585         }
5586         
5587         /* if result = right then exchange them */
5588         if(pic14_sameRegs(AOP(result),AOP(right))){
5589                 operand *tmp = right ;
5590                 right = left;
5591                 left = tmp;
5592         }
5593         
5594         /* if right is bit then exchange them */
5595         if (AOP_TYPE(right) == AOP_CRY &&
5596                 AOP_TYPE(left) != AOP_CRY){
5597                 operand *tmp = right ;
5598                 right = left;
5599                 left = tmp;
5600         }
5601         
5602         DEBUGpic14_AopType(__LINE__,left,right,result);
5603         
5604         if(AOP_TYPE(right) == AOP_LIT)
5605                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5606         
5607         size = AOP_SIZE(result);
5608         
5609         // if(bit | yy)
5610         // xx = bit | yy;
5611         if (AOP_TYPE(left) == AOP_CRY){
5612                 if(AOP_TYPE(right) == AOP_LIT){
5613                         // c = bit & literal;
5614                         if(lit){
5615                                 // lit != 0 => result = 1
5616                                 if(AOP_TYPE(result) == AOP_CRY){
5617                                         if(size)
5618                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5619                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5620                                         //   AOP(result)->aopu.aop_dir,
5621                                         //   AOP(result)->aopu.aop_dir);
5622                                         else if(ifx)
5623                                                 continueIfTrue(ifx);
5624                                         goto release;
5625                                 }
5626                         } else {
5627                                 // lit == 0 => result = left
5628                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5629                                         goto release;
5630                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5631                         }
5632                 } else {
5633                         if (AOP_TYPE(right) == AOP_CRY){
5634                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5635                                         // c = bit | bit;
5636                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5637                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5638                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5639                                         
5640                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5641                                                 AOP(result)->aopu.aop_dir,
5642                                                 AOP(result)->aopu.aop_dir);
5643                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5644                                                 AOP(right)->aopu.aop_dir,
5645                                                 AOP(right)->aopu.aop_dir);
5646                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5647                                                 AOP(result)->aopu.aop_dir,
5648                                                 AOP(result)->aopu.aop_dir);
5649                                 } else {
5650                                         if( AOP_TYPE(result) == AOP_ACC) {
5651                                                 emitpcode(POC_MOVLW, popGetLit(0));
5652                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5653                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5654                                                 emitpcode(POC_MOVLW, popGetLit(1));
5655                                                 
5656                                         } else {
5657                                                 
5658                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5659                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5660                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5661                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5662                                                 
5663                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5664                                                         AOP(result)->aopu.aop_dir,
5665                                                         AOP(result)->aopu.aop_dir);
5666                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5667                                                         AOP(right)->aopu.aop_dir,
5668                                                         AOP(right)->aopu.aop_dir);
5669                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5670                                                         AOP(left)->aopu.aop_dir,
5671                                                         AOP(left)->aopu.aop_dir);
5672                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5673                                                         AOP(result)->aopu.aop_dir,
5674                                                         AOP(result)->aopu.aop_dir);
5675                                         }
5676                                 }
5677                         } else {
5678                                 // c = bit | val;
5679                                 symbol *tlbl = newiTempLabel(NULL);
5680                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5681                                 
5682                                 
5683                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5684                                 if( AOP_TYPE(right) == AOP_ACC) {
5685                                         emitpcode(POC_IORLW, popGetLit(0));
5686                                         emitSKPNZ;
5687                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5688                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5689                                 }
5690                                 
5691                                 
5692                                 
5693                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5694                                         pic14_emitcode(";XXX setb","c");
5695                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5696                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5697                                 pic14_toBoolean(right);
5698                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5699                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5700                                         jmpTrueOrFalse(ifx, tlbl);
5701                                         goto release;
5702                                 } else {
5703                                         CLRC;
5704                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5705                                 }
5706                         }
5707                 }
5708                 // bit = c
5709                 // val = c
5710                 if(size)
5711                         pic14_outBitC(result);
5712                 // if(bit | ...)
5713                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5714                         genIfxJump(ifx, "c");           
5715                 goto release ;
5716         }
5717
5718         // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5719         // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5720         if((AOP_TYPE(right) == AOP_LIT) &&
5721           (AOP_TYPE(result) == AOP_CRY) &&
5722           (AOP_TYPE(left) != AOP_CRY)){
5723                 if(lit){
5724                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5725                         // result = 1
5726                         if(size)
5727                                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5728                         else 
5729                                 continueIfTrue(ifx);
5730                         goto release;
5731                 } else {
5732                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5733                         // lit = 0, result = boolean(left)
5734                         if(size)
5735                                 pic14_emitcode(";XXX setb","c");
5736                         pic14_toBoolean(right);
5737                         if(size){
5738                                 symbol *tlbl = newiTempLabel(NULL);
5739                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5740                                 CLRC;
5741                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5742                         } else {
5743                                 genIfxJump (ifx,"a");
5744                                 goto release;
5745                         }
5746                 }
5747                 pic14_outBitC(result);
5748                 goto release ;
5749         }
5750
5751         /* if left is same as result */
5752         if(pic14_sameRegs(AOP(result),AOP(left))){
5753                 int know_W = -1;
5754                 for(;size--; offset++,lit>>=8) {
5755                         if(AOP_TYPE(right) == AOP_LIT){
5756                                 if((lit & 0xff) == 0)
5757                                         /*  or'ing with 0 has no effect */
5758                                         continue;
5759                                 else {
5760                                         int p = my_powof2(lit & 0xff);
5761                                         if(p>=0) {
5762                                                 /* only one bit is set in the literal, so use a bsf instruction */
5763                                                 emitpcode(POC_BSF,
5764                                                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5765                                         } else {
5766                                                 if(know_W != (int)(lit & 0xff))
5767                                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5768                                                 know_W = lit & 0xff;
5769                                                 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5770                                         }
5771                                         
5772                                 }
5773                         } else {
5774                                 if (AOP_TYPE(left) == AOP_ACC) {
5775                                         emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5776                                         pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5777                                 } else {        
5778                                         emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5779                                         emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5780                                         
5781                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5782                                         pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5783                                         
5784                                 }
5785                         }
5786                 }
5787         } else {
5788                 // left & result in different registers
5789                 if(AOP_TYPE(result) == AOP_CRY){
5790                         // result = bit
5791                         // if(size), result in bit
5792                         // if(!size && ifx), conditional oper: if(left | right)
5793                         symbol *tlbl = newiTempLabel(NULL);
5794                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5795                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5796                         
5797                         
5798                         if(size)
5799                                 pic14_emitcode(";XXX setb","c");
5800                         while(sizer--){
5801                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5802                                 pic14_emitcode(";XXX orl","a,%s",
5803                                         aopGet(AOP(left),offset,FALSE,FALSE));
5804                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5805                                 offset++;
5806                         }
5807                         if(size){
5808                                 CLRC;
5809                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5810                                 pic14_outBitC(result);
5811                         } else if(ifx)
5812                                 jmpTrueOrFalse(ifx, tlbl);
5813                 } else for(;(size--);offset++){
5814                         // normal case
5815                         // result = left | right
5816                         if(AOP_TYPE(right) == AOP_LIT){
5817                                 int t = (lit >> (offset*8)) & 0x0FFL;
5818                                 switch(t) { 
5819                                 case 0x00:
5820                                         if (AOP_TYPE(left) != AOP_ACC) {
5821                                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5822                                         }
5823                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5824                                         
5825                                         break;
5826                                 default:
5827                                         if (AOP_TYPE(left) == AOP_ACC) {
5828                                                 emitpcode(POC_IORLW,  popGetLit(t));
5829                                         } else {
5830                                                 emitpcode(POC_MOVLW,  popGetLit(t));
5831                                                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5832                                         }
5833                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5834                                 }
5835                                 continue;
5836                         }
5837                         
5838                         // faster than result <- left, anl result,right
5839                         // and better if result is SFR
5840                         if (AOP_TYPE(left) == AOP_ACC) {
5841                                 emitpcode(POC_IORFW,popGet(AOP(right),offset));
5842                         } else {
5843                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5844                                 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5845                         }
5846                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5847                 }
5848         }
5849
5850 release :
5851         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5852         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5853         freeAsmop(result,NULL,ic,TRUE);     
5854 }
5855
5856 /*-----------------------------------------------------------------*/
5857 /* genXor - code for xclusive or                                   */
5858 /*-----------------------------------------------------------------*/
5859 static void genXor (iCode *ic, iCode *ifx)
5860 {
5861         operand *left, *right, *result;
5862         int size, offset=0;
5863         unsigned long lit = 0L;
5864         
5865         FENTRY;
5866         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5867         
5868         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5869         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5870         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5871         
5872         /* if left is a literal & right is not ||
5873         if left needs acc & right does not */
5874         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5875                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5876                 operand *tmp = right ;
5877                 right = left;
5878                 left = tmp;
5879         }
5880         
5881         /* if result = right then exchange them */
5882         if(pic14_sameRegs(AOP(result),AOP(right))){
5883                 operand *tmp = right ;
5884                 right = left;
5885                 left = tmp;
5886         }
5887         
5888         /* if right is bit then exchange them */
5889         if (AOP_TYPE(right) == AOP_CRY &&
5890                 AOP_TYPE(left) != AOP_CRY){
5891                 operand *tmp = right ;
5892                 right = left;
5893                 left = tmp;
5894         }
5895         if(AOP_TYPE(right) == AOP_LIT)
5896                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5897         
5898         size = AOP_SIZE(result);
5899         
5900         // if(bit ^ yy)
5901         // xx = bit ^ yy;
5902         if (AOP_TYPE(left) == AOP_CRY){
5903                 if(AOP_TYPE(right) == AOP_LIT){
5904                         // c = bit & literal;
5905                         if(lit>>1){
5906                                 // lit>>1  != 0 => result = 1
5907                                 if(AOP_TYPE(result) == AOP_CRY){
5908                                         if(size)
5909                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5910                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5911                                         else if(ifx)
5912                                                 continueIfTrue(ifx);
5913                                         goto release;
5914                                 }
5915                                 pic14_emitcode("setb","c");
5916                         } else{
5917                                 // lit == (0 or 1)
5918                                 if(lit == 0){
5919                                         // lit == 0, result = left
5920                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5921                                                 goto release;
5922                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5923                                 } else{
5924                                         // lit == 1, result = not(left)
5925                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5926                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5927                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5928                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5929                                                 goto release;
5930                                         } else {
5931                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5932                                                 pic14_emitcode("cpl","c");
5933                                         }
5934                                 }
5935                         }
5936                         
5937                 } else {
5938                         // right != literal
5939                         symbol *tlbl = newiTempLabel(NULL);
5940                         if (AOP_TYPE(right) == AOP_CRY){
5941                                 // c = bit ^ bit;
5942                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5943                         }
5944                         else{
5945                                 int sizer = AOP_SIZE(right);
5946                                 // c = bit ^ val
5947                                 // if val>>1 != 0, result = 1
5948                                 pic14_emitcode("setb","c");
5949                                 while(sizer){
5950                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5951                                         if(sizer == 1)
5952                                                 // test the msb of the lsb
5953                                                 pic14_emitcode("anl","a,#0xfe");
5954                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5955                                         sizer--;
5956                                 }
5957                                 // val = (0,1)
5958                                 pic14_emitcode("rrc","a");
5959                         }
5960                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5961                         pic14_emitcode("cpl","c");
5962                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5963                 }
5964                 // bit = c
5965                 // val = c
5966                 if(size)
5967                         pic14_outBitC(result);
5968                 // if(bit | ...)
5969                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5970                         genIfxJump(ifx, "c");           
5971                 goto release ;
5972         }
5973         
5974         if(pic14_sameRegs(AOP(result),AOP(left))){
5975                 /* if left is same as result */
5976                 for(;size--; offset++) {
5977                         if(AOP_TYPE(right) == AOP_LIT){
5978                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5979                                 if(t == 0x00L)
5980                                         continue;
5981                                 else
5982                                         if (IS_AOP_PREG(left)) {
5983                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5984                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5985                                                 aopPut(AOP(result),"a",offset);
5986                                         } else {
5987                                                 emitpcode(POC_MOVLW, popGetLit(t));
5988                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5989                                                 pic14_emitcode("xrl","%s,%s",
5990                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5991                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5992                                         }
5993                         } else {
5994                                 if (AOP_TYPE(left) == AOP_ACC)
5995                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5996                                 else {
5997                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5998                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5999                                         /*
6000                                         if (IS_AOP_PREG(left)) {
6001                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
6002                                         aopPut(AOP(result),"a",offset);
6003                                         } else
6004                                         pic14_emitcode("xrl","%s,a",
6005                                         aopGet(AOP(left),offset,FALSE,TRUE));
6006                                         */
6007                                 }
6008                         }
6009                 }
6010         } else {
6011                 // left & result in different registers
6012                 if(AOP_TYPE(result) == AOP_CRY){
6013                         // result = bit
6014                         // if(size), result in bit
6015                         // if(!size && ifx), conditional oper: if(left ^ right)
6016                         symbol *tlbl = newiTempLabel(NULL);
6017                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6018                         if(size)
6019                                 pic14_emitcode("setb","c");
6020                         while(sizer--){
6021                                 if((AOP_TYPE(right) == AOP_LIT) &&
6022                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6023                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
6024                                 } else {
6025                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6026                                         pic14_emitcode("xrl","a,%s",
6027                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6028                                 }
6029                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6030                                 offset++;
6031                         }
6032                         if(size){
6033                                 CLRC;
6034                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6035                                 pic14_outBitC(result);
6036                         } else if(ifx)
6037                                 jmpTrueOrFalse(ifx, tlbl);
6038                 } else for(;(size--);offset++){
6039                         // normal case
6040                         // result = left & right
6041                         if(AOP_TYPE(right) == AOP_LIT){
6042                                 int t = (lit >> (offset*8)) & 0x0FFL;
6043                                 switch(t) { 
6044                                 case 0x00:
6045                                         if (AOP_TYPE(left) != AOP_ACC) {
6046                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6047                                         }
6048                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6049                                         pic14_emitcode("movf","%s,w",
6050                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6051                                         pic14_emitcode("movwf","%s",
6052                                                 aopGet(AOP(result),offset,FALSE,FALSE));
6053                                         break;
6054                                 case 0xff:
6055                                         if (AOP_TYPE(left) == AOP_ACC) {
6056                                                 emitpcode(POC_XORLW, popGetLit(t));
6057                                         } else {
6058                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6059                                         }
6060                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6061                                         break;
6062                                 default:
6063                                         if (AOP_TYPE(left) == AOP_ACC) {
6064                                                 emitpcode(POC_XORLW, popGetLit(t));
6065                                         } else {
6066                                                 emitpcode(POC_MOVLW, popGetLit(t));
6067                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6068                                         }
6069                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6070                                         pic14_emitcode("movlw","0x%x",t);
6071                                         pic14_emitcode("xorwf","%s,w",
6072                                                 aopGet(AOP(left),offset,FALSE,FALSE));
6073                                         pic14_emitcode("movwf","%s",
6074                                                 aopGet(AOP(result),offset,FALSE,FALSE));
6075                                         
6076                                 }
6077                                 continue;
6078                         }
6079                         
6080                         // faster than result <- left, anl result,right
6081                         // and better if result is SFR
6082                         if (AOP_TYPE(left) == AOP_ACC) {
6083                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6084                         } else {
6085                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6086                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6087                         }
6088                         if ( AOP_TYPE(result) != AOP_ACC){
6089                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6090                         }
6091                 }
6092         }
6093         
6094 release :
6095         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6096         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6097         freeAsmop(result,NULL,ic,TRUE);     
6098 }
6099
6100 /*-----------------------------------------------------------------*/
6101 /* genInline - write the inline code out                           */
6102 /*-----------------------------------------------------------------*/
6103 static void genInline (iCode *ic)
6104 {
6105   char *buffer, *bp, *bp1;
6106
6107   FENTRY;
6108   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6109
6110   _G.inLine += (!options.asmpeep);
6111
6112   buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6113   strcpy(buffer,IC_INLINE(ic));
6114
6115   /* emit each line as a code */
6116   while (*bp) {
6117     if (*bp == '\n') {
6118       *bp++ = '\0';
6119       
6120       if(*bp1)
6121         addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6122       bp1 = bp;
6123     } else {
6124       if (*bp == ':') {
6125         bp++;
6126         *bp = '\0';
6127         bp++;
6128
6129         /* print label, use this special format with NULL directive
6130          * to denote that the argument should not be indented with tab */
6131         addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
6132
6133         bp1 = bp;
6134       } else
6135         bp++;
6136     }
6137   }
6138   if ((bp1 != bp) && *bp1)
6139     addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6140
6141   Safe_free(buffer);
6142
6143   _G.inLine -= (!options.asmpeep);
6144 }
6145
6146 /*-----------------------------------------------------------------*/
6147 /* genRRC - rotate right with carry                                */
6148 /*-----------------------------------------------------------------*/
6149 static void genRRC (iCode *ic)
6150 {
6151         operand *left , *result ;
6152         int size, offset = 0, same;
6153         
6154         FENTRY;
6155         /* rotate right with carry */
6156         left = IC_LEFT(ic);
6157         result=IC_RESULT(ic);
6158         aopOp (left,ic,FALSE);
6159         aopOp (result,ic,FALSE);
6160         
6161         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6162         
6163         same = pic14_sameRegs(AOP(result),AOP(left));
6164         
6165         size = AOP_SIZE(result);    
6166         
6167         /* get the lsb and put it into the carry */
6168         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6169         
6170         offset = 0 ;
6171         
6172         while(size--) {
6173                 
6174                 if(same) {
6175                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6176                 } else {
6177                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6178                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6179                 }
6180                 
6181                 offset++;
6182         }
6183         
6184         freeAsmop(left,NULL,ic,TRUE);
6185         freeAsmop(result,NULL,ic,TRUE);
6186 }
6187
6188 /*-----------------------------------------------------------------*/
6189 /* genRLC - generate code for rotate left with carry               */
6190 /*-----------------------------------------------------------------*/
6191 static void genRLC (iCode *ic)
6192 {    
6193         operand *left , *result ;
6194         int size, offset = 0;
6195         int same;
6196         
6197         FENTRY;
6198         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6199         /* rotate right with carry */
6200         left = IC_LEFT(ic);
6201         result=IC_RESULT(ic);
6202         aopOp (left,ic,FALSE);
6203         aopOp (result,ic,FALSE);
6204         
6205         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6206         
6207         same = pic14_sameRegs(AOP(result),AOP(left));
6208         
6209         /* move it to the result */
6210         size = AOP_SIZE(result);    
6211         
6212         /* get the msb and put it into the carry */
6213         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6214         
6215         offset = 0 ;
6216         
6217         while(size--) {
6218                 
6219                 if(same) {
6220                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6221                 } else {
6222                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6223                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6224                 }
6225                 
6226                 offset++;
6227         }
6228         
6229         
6230         freeAsmop(left,NULL,ic,TRUE);
6231         freeAsmop(result,NULL,ic,TRUE);
6232 }
6233
6234 /*-----------------------------------------------------------------*/
6235 /* genGetHbit - generates code get highest order bit               */
6236 /*-----------------------------------------------------------------*/
6237 static void genGetHbit (iCode *ic)
6238 {
6239         operand *left, *result;
6240         left = IC_LEFT(ic);
6241         result=IC_RESULT(ic);
6242         aopOp (left,ic,FALSE);
6243         aopOp (result,ic,FALSE);
6244         
6245         FENTRY;
6246         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6247         /* get the highest order byte into a */
6248         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6249         if(AOP_TYPE(result) == AOP_CRY){
6250                 pic14_emitcode("rlc","a");
6251                 pic14_outBitC(result);
6252         }
6253         else{
6254                 pic14_emitcode("rl","a");
6255                 pic14_emitcode("anl","a,#0x01");
6256                 pic14_outAcc(result);
6257         }
6258         
6259         
6260         freeAsmop(left,NULL,ic,TRUE);
6261         freeAsmop(result,NULL,ic,TRUE);
6262 }
6263
6264 /*-----------------------------------------------------------------*/
6265 /* AccRol - rotate left accumulator by known count                 */
6266 /*-----------------------------------------------------------------*/
6267 static void AccRol (operand *op,int offset,int shCount)
6268 {
6269         FENTRY;
6270         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6271         shCount &= 0x0007;              // shCount : 0..7
6272         switch(shCount){
6273         case 0 :
6274                 break;
6275         case 1 :
6276                 pic14_emitcode("rl","a");
6277                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6278                 break;
6279         case 2 :
6280                 pic14_emitcode("rl","a");
6281                 pic14_emitcode("rl","a");
6282                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6283                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6284                 break;
6285         case 3 :
6286                 pic14_emitcode("swap","a");
6287                 pic14_emitcode("rr","a");
6288                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6289                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6290                 break;
6291         case 4 :
6292                 pic14_emitcode("swap","a");
6293                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6294                 break;
6295         case 5 :
6296                 pic14_emitcode("swap","a");
6297                 pic14_emitcode("rl","a");
6298                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6299                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6300                 break;
6301         case 6 :
6302                 pic14_emitcode("rr","a");
6303                 pic14_emitcode("rr","a");
6304                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6305                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6306                 break;
6307         case 7 :
6308                 pic14_emitcode("rr","a");
6309                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6310                 break;
6311         }
6312 }
6313
6314 /*-----------------------------------------------------------------*/
6315 /* AccLsh - left shift accumulator by known count                  */
6316 /*-----------------------------------------------------------------*/
6317 static void AccLsh (operand *op,int offset,int shCount)
6318 {
6319         FENTRY;
6320         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6321         if(shCount != 0){
6322                 /*
6323                 if(shCount == 1) {
6324                         pic14_emitcode("add","a,acc");
6325                         emitCLRC;
6326                         emitpcode(POC_RLF,popGet(AOP(op),offset));
6327                 } else {
6328                         if(shCount == 2) {
6329                                 pic14_emitcode("add","a,acc");
6330                                 emitCLRC;
6331                                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6332                                 pic14_emitcode("add","a,acc");
6333                                 emitCLRC;
6334                                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6335                         } else {
6336                 */
6337                 {
6338                         {
6339                                 /* rotate left accumulator */
6340                                 AccRol(op,offset,shCount);
6341                                 /* and kill the lower order bits */
6342                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6343                                 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6344                         }
6345                 }
6346         }
6347 }
6348
6349 /*-----------------------------------------------------------------*/
6350 /* AccRsh - right shift accumulator by known count                 */
6351 /*-----------------------------------------------------------------*/
6352 static void AccRsh (operand *op,int offset,int shCount)
6353 {
6354         FENTRY;
6355         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6356         if(shCount != 0){
6357                 if(shCount == 1){
6358                         CLRC;
6359                         pic14_emitcode("rrc","a");
6360                 } else {
6361                         /* rotate right accumulator */
6362                         AccRol(op,offset,8 - shCount);
6363                         /* and kill the higher order bits */
6364                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6365                 }
6366         }
6367 }
6368
6369 #if 0
6370 /*-----------------------------------------------------------------*/
6371 /* AccSRsh - signed right shift accumulator by known count                 */
6372 /*-----------------------------------------------------------------*/
6373 static void AccSRsh (int shCount)
6374 {
6375         symbol *tlbl ;
6376         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6377         if(shCount != 0){
6378                 if(shCount == 1){
6379                         pic14_emitcode("mov","c,acc.7");
6380                         pic14_emitcode("rrc","a");
6381                 } else if(shCount == 2){
6382                         pic14_emitcode("mov","c,acc.7");
6383                         pic14_emitcode("rrc","a");
6384                         pic14_emitcode("mov","c,acc.7");
6385                         pic14_emitcode("rrc","a");
6386                 } else {
6387                         tlbl = newiTempLabel(NULL);
6388                         /* rotate right accumulator */
6389                         AccRol(8 - shCount);
6390                         /* and kill the higher order bits */
6391                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6392                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6393                         pic14_emitcode("orl","a,#0x%02x",
6394                                 (unsigned char)~SRMask[shCount]);
6395                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6396                 }
6397         }
6398 }
6399 #endif
6400 /*-----------------------------------------------------------------*/
6401 /* shiftR1Left2Result - shift right one byte from left to result   */
6402 /*-----------------------------------------------------------------*/
6403 static void shiftR1Left2ResultSigned (operand *left, int offl,
6404                                                                           operand *result, int offr,
6405                                                                           int shCount)
6406 {
6407         int same;
6408         
6409         FENTRY;
6410         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6411         
6412         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6413         
6414         switch(shCount) {
6415         case 1:
6416                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6417                 if(same) 
6418                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6419                 else {
6420                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6421                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422                 }
6423                 
6424                 break;
6425         case 2:
6426                 
6427                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6428                 if(same) 
6429                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6430                 else {
6431                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6432                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433                 }
6434                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6435                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6436                 
6437                 break;
6438                 
6439         case 3:
6440                 if(same)
6441                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6442                 else {
6443                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6444                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445                 }
6446                 
6447                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6448                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6449                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6450                 
6451                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6452                 emitpcode(POC_IORLW, popGetLit(0xe0));
6453                 
6454                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6455                 break;
6456                 
6457         case 4:
6458                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6459                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6460                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6461                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6462                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6463                 break;
6464         case 5:
6465                 if(same) {
6466                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6467                 } else {
6468                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6469                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6470                 }
6471                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6472                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6473                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6474                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6475                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6476                 break;
6477                 
6478         case 6:
6479                 if(same) {
6480                         emitpcode(POC_MOVLW, popGetLit(0x00));
6481                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6482                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6483                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6484                         emitpcode(POC_IORLW, popGetLit(0x01));
6485                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6486                 } else {
6487                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6488                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6489                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6490                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6491                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6492                 }
6493                 break;
6494                 
6495         case 7:
6496                 if(same) {
6497                         emitpcode(POC_MOVLW, popGetLit(0x00));
6498                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6499                         emitpcode(POC_MOVLW, popGetLit(0xff));
6500                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6501                 } else {
6502                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6503                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6504                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6505                 }
6506                 
6507         default:
6508                 break;
6509         }
6510 }
6511
6512 /*-----------------------------------------------------------------*/
6513 /* shiftR1Left2Result - shift right one byte from left to result   */
6514 /*-----------------------------------------------------------------*/
6515 static void shiftR1Left2Result (operand *left, int offl,
6516                                                                 operand *result, int offr,
6517                                                                 int shCount, int sign)
6518 {
6519         int same;
6520         
6521         FENTRY;
6522         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6523         
6524         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6525         
6526         /* Copy the msb into the carry if signed. */
6527         if(sign) {
6528                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6529                 return;
6530         }
6531         
6532         
6533         
6534         switch(shCount) {
6535         case 1:
6536                 emitCLRC;
6537                 if(same) 
6538                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6539                 else {
6540                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6541                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6542                 }
6543                 break;
6544         case 2:
6545                 emitCLRC;
6546                 if(same) {
6547                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6548                 } else {
6549                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6550                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6551                 }
6552                 emitCLRC;
6553                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6554                 
6555                 break;
6556         case 3:
6557                 if(same)
6558                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6559                 else {
6560                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6561                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6562                 }
6563                 
6564                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6565                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6566                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6567                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6568                 break;
6569                 
6570         case 4:
6571                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6572                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6573                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6574                 break;
6575                 
6576         case 5:
6577                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6578                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6579                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6580                 emitCLRC;
6581                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6582                 
6583                 break;
6584         case 6:
6585                 
6586                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6587                 emitpcode(POC_ANDLW, popGetLit(0x80));
6588                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6589                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6590                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6591                 break;
6592                 
6593         case 7:
6594                 
6595                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6596                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6597                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6598                 
6599                 break;
6600                 
6601         default:
6602                 break;
6603         }
6604 }
6605
6606 /*-----------------------------------------------------------------*/
6607 /* shiftL1Left2Result - shift left one byte from left to result    */
6608 /*-----------------------------------------------------------------*/
6609 static void shiftL1Left2Result (operand *left, int offl,
6610                                                                 operand *result, int offr, int shCount)
6611 {
6612         int same;
6613         
6614         //    char *l;
6615         FENTRY;
6616         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6617         
6618         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6619         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6620         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6621         //    MOVA(l);
6622         /* shift left accumulator */
6623         //AccLsh(shCount); // don't comment out just yet...
6624         //    aopPut(AOP(result),"a",offr);
6625         
6626         switch(shCount) {
6627         case 1:
6628                 /* Shift left 1 bit position */
6629                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6630                 if(same) {
6631                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6632                 } else {
6633                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6634                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6635                 }
6636                 break;
6637         case 2:
6638                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6639                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6640                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6641                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6642                 break;
6643         case 3:
6644                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6645                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6646                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6647                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6648                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6649                 break;
6650         case 4:
6651                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6652                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6653                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6654                 break;
6655         case 5:
6656                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6657                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6658                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6659                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6660                 break;
6661         case 6:
6662                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6663                 emitpcode(POC_ANDLW, popGetLit(0x30));
6664                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6665                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6666                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6667                 break;
6668         case 7:
6669                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6670                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6671                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6672                 break;
6673                 
6674         default:
6675                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6676         }
6677         
6678 }
6679
6680 /*-----------------------------------------------------------------*/
6681 /* movLeft2Result - move byte from left to result                  */
6682 /*-----------------------------------------------------------------*/
6683 static void movLeft2Result (operand *left, int offl,
6684                                                         operand *result, int offr)
6685 {
6686         char *l;
6687         FENTRY;
6688         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6689         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6690                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6691                 
6692                 if (*l == '@' && (IS_AOP_PREG(result))) {
6693                         pic14_emitcode("mov","a,%s",l);
6694                         aopPut(AOP(result),"a",offr);
6695                 } else {
6696                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6697                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6698                 }
6699         }
6700 }
6701
6702 /*-----------------------------------------------------------------*/
6703 /* shiftL2Left2Result - shift left two bytes from left to result   */
6704 /*-----------------------------------------------------------------*/
6705 static void shiftL2Left2Result (operand *left, int offl,
6706                                                                 operand *result, int offr, int shCount)
6707 {
6708         FENTRY;
6709         
6710         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6711         
6712         if(pic14_sameRegs(AOP(result), AOP(left))) {
6713                 switch(shCount) {
6714                 case 0:
6715                         break;
6716                 case 1:
6717                 case 2:
6718                 case 3:
6719                         
6720                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6721                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6722                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6723                         
6724                         while(--shCount) {
6725                                 emitCLRC;
6726                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6727                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6728                         }
6729                         
6730                         break;
6731                 case 4:
6732                 case 5:
6733                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6734                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6735                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6736                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6737                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6738                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6739                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6740                         if(shCount >=5) {
6741                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6742                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6743                         }
6744                         break;
6745                 case 6:
6746                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6747                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6748                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6749                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6750                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6751                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6752                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6753                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6754                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6755                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6756                         break;
6757                 case 7:
6758                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6759                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6760                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6761                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6762                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6763                 }
6764                 
6765         } else {
6766                 switch(shCount) {
6767                 case 0:
6768                         break;
6769                 case 1:
6770                 case 2:
6771                 case 3:
6772                 /* note, use a mov/add for the shift since the mov has a
6773                         chance of getting optimized out */
6774                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6775                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6776                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6777                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6778                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6779                         
6780                         while(--shCount) {
6781                                 emitCLRC;
6782                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6783                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6784                         }
6785                         break;
6786                         
6787                 case 4:
6788                 case 5:
6789                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6790                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6791                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6792                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6793                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6794                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6795                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6796                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6797                         
6798                         
6799                         if(shCount == 5) {
6800                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6801                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6802                         }
6803                         break;
6804                 case 6:
6805                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6806                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6807                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6808                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6809                         
6810                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6811                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6812                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6813                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6814                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6815                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6816                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6817                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6818                         break;
6819                 case 7:
6820                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6821                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6822                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6823                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6824                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6825                 }
6826         }
6827         
6828 }
6829 /*-----------------------------------------------------------------*/
6830 /* shiftR2Left2Result - shift right two bytes from left to result  */
6831 /*-----------------------------------------------------------------*/
6832 static void shiftR2Left2Result (operand *left, int offl,
6833                                                                 operand *result, int offr,
6834                                                                 int shCount, int sign)
6835 {
6836         int same=0;
6837         
6838         FENTRY;
6839         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6840         same = pic14_sameRegs(AOP(result), AOP(left));
6841         
6842         if(same && ((offl + MSB16) == offr)){
6843                 same=1;
6844                 /* don't crash result[offr] */
6845                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6846                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6847         }
6848         /* else {
6849         movLeft2Result(left,offl, result, offr);
6850         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6851         }
6852         */
6853         /* a:x >> shCount (x = lsb(result))*/
6854         /*
6855         if(sign)
6856         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6857         else {
6858         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6859         */
6860         switch(shCount) {
6861         case 0:
6862                 break;
6863         case 1:
6864         case 2:
6865         case 3:
6866                 if(sign)
6867                         emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6868                 else
6869                         emitCLRC;
6870                 
6871                 if(same) {
6872                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6873                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6874                 } else {
6875                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6876                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6877                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6878                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6879                 }
6880                 
6881                 while(--shCount) {
6882                         if(sign)
6883                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6884                         else
6885                                 emitCLRC;
6886                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6887                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6888                 }
6889                 break;
6890         case 4:
6891         case 5:
6892                 if(same) {
6893                         
6894                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6895                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6896                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6897                         
6898                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6899                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6900                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6901                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6902                 } else {
6903                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6904                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6905                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6906                         
6907                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6908                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6909                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6910                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6911                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6912                 }
6913                 
6914                 if(shCount >=5) {
6915                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6916                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6917                 }
6918                 
6919                 if(sign) {
6920                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6921                         emitpcode(POC_BTFSC, 
6922                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6923                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6924                 }
6925                 
6926                 break;
6927                 
6928         case 6:
6929                 if(same) {
6930                         
6931                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6932                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6933                         
6934                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6935                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6936                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6937                         emitpcode(POC_ANDLW,popGetLit(0x03));
6938                         if(sign) {
6939                                 emitpcode(POC_BTFSC, 
6940                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6941                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6942                         }
6943                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6944                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6945                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6946                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6947                 } else {
6948                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6949                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6950                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6951                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6952                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6953                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6954                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6955                         emitpcode(POC_ANDLW,popGetLit(0x03));
6956                         if(sign) {
6957                                 emitpcode(POC_BTFSC, 
6958                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6959                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6960                         }
6961                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6962                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6963                         
6964                         
6965                 }
6966                 
6967                 break;
6968         case 7:
6969                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6970                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6971                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6972                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6973                 if(sign) {
6974                         emitSKPNC;
6975                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6976                 } else 
6977                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6978   }
6979 }
6980
6981
6982 /*-----------------------------------------------------------------*/
6983 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6984 /*-----------------------------------------------------------------*/
6985 static void shiftLLeftOrResult (operand *left, int offl,
6986                                                                 operand *result, int offr, int shCount)
6987 {
6988         FENTRY;
6989         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6990         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6991         /* shift left accumulator */
6992         AccLsh(left,offl,shCount);
6993         /* or with result */
6994         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6995         /* back to result */
6996         aopPut(AOP(result),"a",offr);
6997 }
6998
6999 /*-----------------------------------------------------------------*/
7000 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7001 /*-----------------------------------------------------------------*/
7002 static void shiftRLeftOrResult (operand *left, int offl,
7003                                                                 operand *result, int offr, int shCount)
7004 {
7005         FENTRY;
7006         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7007         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
7008         /* shift right accumulator */
7009         AccRsh(left,offl,shCount);
7010         /* or with result */
7011         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
7012         /* back to result */
7013         aopPut(AOP(result),"a",offr);
7014 }
7015
7016 /*-----------------------------------------------------------------*/
7017 /* genlshOne - left shift a one byte quantity by known count       */
7018 /*-----------------------------------------------------------------*/
7019 static void genlshOne (operand *result, operand *left, int shCount)
7020 {       
7021         FENTRY;
7022         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7023         shiftL1Left2Result(left, LSB, result, LSB, shCount);
7024 }
7025
7026 /*-----------------------------------------------------------------*/
7027 /* genlshTwo - left shift two bytes by known amount != 0           */
7028 /*-----------------------------------------------------------------*/
7029 static void genlshTwo (operand *result,operand *left, int shCount)
7030 {
7031         int size;
7032         
7033         FENTRY;
7034         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7035         size = pic14_getDataSize(result);
7036         
7037         /* if shCount >= 8 */
7038         if (shCount >= 8) {
7039                 shCount -= 8 ;
7040                 
7041                 if (size > 1){
7042                         if (shCount)
7043                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7044                         else 
7045                                 movLeft2Result(left, LSB, result, MSB16);
7046                 }
7047                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
7048         }
7049         
7050         /*  1 <= shCount <= 7 */
7051         else {  
7052                 if(size == 1)
7053                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
7054                 else 
7055                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7056         }
7057 }
7058
7059 /*-----------------------------------------------------------------*/
7060 /* shiftLLong - shift left one long from left to result            */
7061 /* offl = LSB or MSB16                                             */
7062 /*-----------------------------------------------------------------*/
7063 static void shiftLLong (operand *left, operand *result, int offr )
7064 {
7065         char *l;
7066         int size = AOP_SIZE(result);
7067         
7068         FENTRY;
7069         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7070         if(size >= LSB+offr){
7071                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7072                 MOVA(l);
7073                 pic14_emitcode("add","a,acc");
7074                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7075                         size >= MSB16+offr && offr != LSB )
7076                         pic14_emitcode("xch","a,%s",
7077                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7078                 else      
7079                         aopPut(AOP(result),"a",LSB+offr);
7080         }
7081         
7082         if(size >= MSB16+offr){
7083                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7084                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7085                         MOVA(l);
7086                 }
7087                 pic14_emitcode("rlc","a");
7088                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7089                         size >= MSB24+offr && offr != LSB)
7090                         pic14_emitcode("xch","a,%s",
7091                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7092                 else      
7093                         aopPut(AOP(result),"a",MSB16+offr);
7094         }
7095         
7096         if(size >= MSB24+offr){
7097                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7098                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7099                         MOVA(l);
7100                 }
7101                 pic14_emitcode("rlc","a");
7102                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
7103                         size >= MSB32+offr && offr != LSB )
7104                         pic14_emitcode("xch","a,%s",
7105                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7106                 else      
7107                         aopPut(AOP(result),"a",MSB24+offr);
7108         }
7109         
7110         if(size > MSB32+offr){
7111                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7112                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7113                         MOVA(l);  
7114                 }
7115                 pic14_emitcode("rlc","a");
7116                 aopPut(AOP(result),"a",MSB32+offr);
7117         }
7118         if(offr != LSB)
7119                 aopPut(AOP(result),zero,LSB);       
7120 }
7121
7122 /*-----------------------------------------------------------------*/
7123 /* genlshFour - shift four byte by a known amount != 0             */
7124 /*-----------------------------------------------------------------*/
7125 static void genlshFour (operand *result, operand *left, int shCount)
7126 {
7127         int size;
7128         
7129         FENTRY;
7130         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7131         size = AOP_SIZE(result);
7132         
7133         /* if shifting more that 3 bytes */
7134         if (shCount >= 24 ) {
7135                 shCount -= 24;
7136                 if (shCount)
7137                 /* lowest order of left goes to the highest
7138                 order of the destination */
7139                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7140                 else
7141                         movLeft2Result(left, LSB, result, MSB32);
7142                 aopPut(AOP(result),zero,LSB);
7143                 aopPut(AOP(result),zero,MSB16);
7144                 aopPut(AOP(result),zero,MSB32);
7145                 return;
7146         }
7147         
7148         /* more than two bytes */
7149         else if ( shCount >= 16 ) {
7150                 /* lower order two bytes goes to higher order two bytes */
7151                 shCount -= 16;
7152                 /* if some more remaining */
7153                 if (shCount)
7154                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7155                 else {
7156                         movLeft2Result(left, MSB16, result, MSB32);
7157                         movLeft2Result(left, LSB, result, MSB24);
7158                 }
7159                 aopPut(AOP(result),zero,MSB16);
7160                 aopPut(AOP(result),zero,LSB);
7161                 return;
7162         }    
7163         
7164         /* if more than 1 byte */
7165         else if ( shCount >= 8 ) {
7166                 /* lower order three bytes goes to higher order  three bytes */
7167                 shCount -= 8;
7168                 if(size == 2){
7169                         if(shCount)
7170                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7171                         else
7172                                 movLeft2Result(left, LSB, result, MSB16);
7173                 }
7174                 else{   /* size = 4 */
7175                         if(shCount == 0){
7176                                 movLeft2Result(left, MSB24, result, MSB32);
7177                                 movLeft2Result(left, MSB16, result, MSB24);
7178                                 movLeft2Result(left, LSB, result, MSB16);
7179                                 aopPut(AOP(result),zero,LSB);
7180                         }
7181                         else if(shCount == 1)
7182                                 shiftLLong(left, result, MSB16);
7183                         else{
7184                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7185                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7186                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7187                                 aopPut(AOP(result),zero,LSB);
7188                         }
7189                 }
7190         }
7191         
7192         /* 1 <= shCount <= 7 */
7193         else if(shCount <= 2){
7194                 shiftLLong(left, result, LSB);
7195                 if(shCount == 2)
7196                         shiftLLong(result, result, LSB);
7197         }
7198         /* 3 <= shCount <= 7, optimize */
7199         else{
7200                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7201                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7202                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7203         }
7204 }
7205
7206 /*-----------------------------------------------------------------*/
7207 /* genLeftShiftLiteral - left shifting by known count              */
7208 /*-----------------------------------------------------------------*/
7209 static void genLeftShiftLiteral (operand *left,
7210                                                                  operand *right,
7211                                                                  operand *result,
7212                                                                  iCode *ic)
7213 {    
7214         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7215         int size;
7216         
7217         FENTRY;
7218         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7219         freeAsmop(right,NULL,ic,TRUE);
7220         
7221         aopOp(left,ic,FALSE);
7222         aopOp(result,ic,FALSE);
7223         
7224         size = getSize(operandType(result));
7225         
7226 #if VIEW_SIZE
7227         pic14_emitcode("; shift left ","result %d, left %d",size,
7228                 AOP_SIZE(left));
7229 #endif
7230         
7231         /* I suppose that the left size >= result size */
7232         if(shCount == 0){
7233                 while(size--){
7234                         movLeft2Result(left, size, result, size);
7235                 }
7236         }
7237         
7238         else if(shCount >= (size * 8))
7239                 while(size--)
7240                         aopPut(AOP(result),zero,size);
7241                 else{
7242                         switch (size) {
7243                         case 1:
7244                                 genlshOne (result,left,shCount);
7245                                 break;
7246                                 
7247                         case 2:
7248                         case 3:
7249                                 genlshTwo (result,left,shCount);
7250                                 break;
7251                                 
7252                         case 4:
7253                                 genlshFour (result,left,shCount);
7254                                 break;
7255                         }
7256                 }
7257                 freeAsmop(left,NULL,ic,TRUE);
7258                 freeAsmop(result,NULL,ic,TRUE);
7259 }
7260
7261 /*-----------------------------------------------------------------*
7262 * genMultiAsm - repeat assembly instruction for size of register.
7263 * if endian == 1, then the high byte (i.e base address + size of 
7264 * register) is used first else the low byte is used first;
7265 *-----------------------------------------------------------------*/
7266 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7267 {
7268         
7269         int offset = 0;
7270         
7271         FENTRY;
7272         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7273         
7274         if(!reg)
7275                 return;
7276         
7277         if(!endian) {
7278                 endian = 1;
7279         } else {
7280                 endian = -1;
7281                 offset = size-1;
7282         }
7283         
7284         while(size--) {
7285                 emitpcode(poc,    popGet(AOP(reg),offset));
7286                 offset += endian;
7287         }
7288         
7289 }
7290 /*-----------------------------------------------------------------*/
7291 /* genLeftShift - generates code for left shifting                 */
7292 /*-----------------------------------------------------------------*/
7293 static void genLeftShift (iCode *ic)
7294 {
7295         operand *left,*right, *result;
7296         int size, offset;
7297         unsigned long lit = 0L;
7298         char *l;
7299         symbol *tlbl , *tlbl1;
7300         pCodeOp *pctemp;
7301         
7302         FENTRY;
7303         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7304         
7305         right = IC_RIGHT(ic);
7306         left  = IC_LEFT(ic);
7307         result = IC_RESULT(ic);
7308         
7309         aopOp(right,ic,FALSE);
7310         
7311         /* if the shift count is known then do it 
7312         as efficiently as possible */
7313         if (AOP_TYPE(right) == AOP_LIT) {
7314                 genLeftShiftLiteral (left,right,result,ic);
7315                 return ;
7316         }
7317         
7318         /* shift count is unknown then we have to form 
7319         a loop get the loop count in B : Note: we take
7320         only the lower order byte since shifting
7321         more that 32 bits make no sense anyway, ( the
7322         largest size of an object can be only 32 bits ) */  
7323         
7324         
7325         aopOp(left,ic,FALSE);
7326         aopOp(result,ic,FALSE);
7327         
7328         /* now move the left to the result if they are not the
7329         same */
7330         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7331                 AOP_SIZE(result) > 1) {
7332                 
7333                 size = AOP_SIZE(result);
7334                 offset=0;
7335                 while (size--) {
7336                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7337                         if (*l == '@' && (IS_AOP_PREG(result))) {
7338                                 
7339                                 pic14_emitcode("mov","a,%s",l);
7340                                 aopPut(AOP(result),"a",offset);
7341                         } else {
7342                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7343                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7344                                 //aopPut(AOP(result),l,offset);
7345                         }
7346                         offset++;
7347                 }
7348         }
7349         
7350         if(AOP_TYPE(left) == AOP_LIT)
7351                 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7352
7353         size = AOP_SIZE(result);
7354         
7355         /* if it is only one byte then */
7356         if (size == 1) {
7357                 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7358                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7359                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7360                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7361                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7362                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7363                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7364                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7365                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7366                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7367                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7368                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7369                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7370                 } else {
7371                         
7372                         tlbl = newiTempLabel(NULL);
7373                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7374                                 if (AOP_TYPE(left) == AOP_LIT)
7375                                         emitpcode(POC_MOVLW,  popGetLit(lit));
7376                                 else
7377                                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7378                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7379                         }
7380                         
7381                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7382                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7383                         emitpLabel(tlbl->key);
7384                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7385                         emitpcode(POC_ADDLW,  popGetLit(1));
7386                         emitSKPC;
7387                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7388                 }
7389                 goto release ;
7390         }
7391         
7392         if (pic14_sameRegs(AOP(left),AOP(result))) {
7393                 
7394                 tlbl = newiTempLabel(NULL);
7395                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7396                 genMultiAsm(POC_RRF, result, size,1);
7397                 emitpLabel(tlbl->key);
7398                 genMultiAsm(POC_RLF, result, size,0);
7399                 emitpcode(POC_ADDLW,  popGetLit(1));
7400                 emitSKPC;
7401                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7402                 goto release;
7403         }
7404         
7405         //tlbl = newiTempLabel(NULL);
7406         //offset = 0 ;   
7407         //tlbl1 = newiTempLabel(NULL);
7408         
7409         //reAdjustPreg(AOP(result));    
7410         
7411         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7412         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7413         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7414         //MOVA(l);
7415         //pic14_emitcode("add","a,acc");         
7416         //aopPut(AOP(result),"a",offset++);
7417         //while (--size) {
7418         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7419         //  MOVA(l);
7420         //  pic14_emitcode("rlc","a");         
7421         //  aopPut(AOP(result),"a",offset++);
7422         //}
7423         //reAdjustPreg(AOP(result));
7424         
7425         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7426         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7427         
7428         
7429         tlbl = newiTempLabel(NULL);
7430         tlbl1= newiTempLabel(NULL);
7431         
7432         size = AOP_SIZE(result);
7433         offset = 1;
7434         
7435         pctemp = popGetTempReg();  /* grab a temporary working register. */
7436         
7437         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7438         
7439         /* offset should be 0, 1 or 3 */
7440         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7441         emitSKPNZ;
7442         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7443         
7444         emitpcode(POC_MOVWF, pctemp);
7445         
7446         
7447         emitpLabel(tlbl->key);
7448         
7449         emitCLRC;
7450         emitpcode(POC_RLF,  popGet(AOP(result),0));
7451         while(--size)
7452                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7453         
7454         emitpcode(POC_DECFSZ,  pctemp);
7455         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7456         emitpLabel(tlbl1->key);
7457         
7458         popReleaseTempReg(pctemp);
7459         
7460         
7461 release:
7462         freeAsmop (right,NULL,ic,TRUE);
7463         freeAsmop(left,NULL,ic,TRUE);
7464         freeAsmop(result,NULL,ic,TRUE);
7465 }
7466
7467 /*-----------------------------------------------------------------*/
7468 /* genrshOne - right shift a one byte quantity by known count      */
7469 /*-----------------------------------------------------------------*/
7470 static void genrshOne (operand *result, operand *left,
7471                                            int shCount, int sign)
7472 {
7473         FENTRY;
7474         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7475         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7476 }
7477
7478 /*-----------------------------------------------------------------*/
7479 /* genrshTwo - right shift two bytes by known amount != 0          */
7480 /*-----------------------------------------------------------------*/
7481 static void genrshTwo (operand *result,operand *left,
7482                                            int shCount, int sign)
7483 {
7484         FENTRY;
7485         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7486         /* if shCount >= 8 */
7487         if (shCount >= 8) {
7488                 shCount -= 8 ;
7489                 if (shCount)
7490                         shiftR1Left2Result(left, MSB16, result, LSB,
7491                         shCount, sign);
7492                 else
7493                         movLeft2Result(left, MSB16, result, LSB);
7494                 
7495                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7496                 
7497                 if(sign) {
7498                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7499                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7500                 }
7501         }
7502         
7503         /*  1 <= shCount <= 7 */
7504         else
7505                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7506 }
7507
7508 /*-----------------------------------------------------------------*/
7509 /* shiftRLong - shift right one long from left to result           */
7510 /* offl = LSB or MSB16                                             */
7511 /*-----------------------------------------------------------------*/
7512 static void shiftRLong (operand *left, int offl,
7513                                                 operand *result, int sign)
7514 {
7515         FENTRY;
7516         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7517         if(!sign)
7518                 pic14_emitcode("clr","c");
7519         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7520         if(sign)
7521                 pic14_emitcode("mov","c,acc.7");
7522         pic14_emitcode("rrc","a");
7523         aopPut(AOP(result),"a",MSB32-offl);
7524         if(offl == MSB16)
7525                 /* add sign of "a" */
7526                 addSign(result, MSB32, sign);
7527         
7528         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7529         pic14_emitcode("rrc","a");
7530         aopPut(AOP(result),"a",MSB24-offl);
7531         
7532         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7533         pic14_emitcode("rrc","a");
7534         aopPut(AOP(result),"a",MSB16-offl);
7535         
7536         if(offl == LSB){
7537                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7538                 pic14_emitcode("rrc","a");
7539                 aopPut(AOP(result),"a",LSB);
7540         }
7541 }
7542
7543 /*-----------------------------------------------------------------*/
7544 /* genrshFour - shift four byte by a known amount != 0             */
7545 /*-----------------------------------------------------------------*/
7546 static void genrshFour (operand *result, operand *left,
7547                                                 int shCount, int sign)
7548 {
7549         FENTRY;
7550         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7551         /* if shifting more that 3 bytes */
7552         if(shCount >= 24 ) {
7553                 shCount -= 24;
7554                 if(shCount)
7555                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7556                 else
7557                         movLeft2Result(left, MSB32, result, LSB);
7558                 
7559                 addSign(result, MSB16, sign);
7560         }
7561         else if(shCount >= 16){
7562                 shCount -= 16;
7563                 if(shCount)
7564                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7565                 else{
7566                         movLeft2Result(left, MSB24, result, LSB);
7567                         movLeft2Result(left, MSB32, result, MSB16);
7568                 }
7569                 addSign(result, MSB24, sign);
7570         }
7571         else if(shCount >= 8){
7572                 shCount -= 8;
7573                 if(shCount == 1)
7574                         shiftRLong(left, MSB16, result, sign);
7575                 else if(shCount == 0){
7576                         movLeft2Result(left, MSB16, result, LSB);
7577                         movLeft2Result(left, MSB24, result, MSB16);
7578                         movLeft2Result(left, MSB32, result, MSB24);
7579                         addSign(result, MSB32, sign);
7580                 }
7581                 else{
7582                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7583                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7584                         /* the last shift is signed */
7585                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7586                         addSign(result, MSB32, sign);
7587                 }
7588         }
7589         else{   /* 1 <= shCount <= 7 */
7590                 if(shCount <= 2){
7591                         shiftRLong(left, LSB, result, sign);
7592                         if(shCount == 2)
7593                                 shiftRLong(result, LSB, result, sign);
7594                 }
7595                 else{
7596                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7597                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7598                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7599                 }
7600         }
7601 }
7602
7603 /*-----------------------------------------------------------------*/
7604 /* genRightShiftLiteral - right shifting by known count            */
7605 /*-----------------------------------------------------------------*/
7606 static void genRightShiftLiteral (operand *left,
7607                                                                   operand *right,
7608                                                                   operand *result,
7609                                                                   iCode *ic,
7610                                                                   int sign)
7611 {    
7612         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7613         int lsize,res_size;
7614         
7615         FENTRY;
7616         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7617         freeAsmop(right,NULL,ic,TRUE);
7618         
7619         aopOp(left,ic,FALSE);
7620         aopOp(result,ic,FALSE);
7621         
7622 #if VIEW_SIZE
7623         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7624                 AOP_SIZE(left));
7625 #endif
7626         
7627         lsize = pic14_getDataSize(left);
7628         res_size = pic14_getDataSize(result);
7629         /* test the LEFT size !!! */
7630         
7631         /* I suppose that the left size >= result size */
7632         if(shCount == 0){
7633                 while(res_size--)
7634                         movLeft2Result(left, lsize, result, res_size);
7635         }
7636         
7637         else if(shCount >= (lsize * 8)){
7638                 
7639                 if(res_size == 1) {
7640                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7641                         if(sign) {
7642                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7643                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7644                         }
7645                 } else {
7646                         
7647                         if(sign) {
7648                                 emitpcode(POC_MOVLW, popGetLit(0));
7649                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7650                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7651                                 while(res_size--)
7652                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7653                                 
7654                         } else {
7655                                 
7656                                 while(res_size--)
7657                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7658                         }
7659                 }
7660         } else {
7661                 
7662                 switch (res_size) {
7663                 case 1:
7664                         genrshOne (result,left,shCount,sign);
7665                         break;
7666                         
7667                 case 2:
7668                         genrshTwo (result,left,shCount,sign);
7669                         break;
7670                         
7671                 case 4:
7672                         genrshFour (result,left,shCount,sign);
7673                         break;
7674                 default :
7675                         break;
7676                 }
7677                 
7678         }
7679         
7680         freeAsmop(left,NULL,ic,TRUE);
7681         freeAsmop(result,NULL,ic,TRUE);
7682 }
7683
7684 /*-----------------------------------------------------------------*/
7685 /* genSignedRightShift - right shift of signed number              */
7686 /*-----------------------------------------------------------------*/
7687 static void genSignedRightShift (iCode *ic)
7688 {
7689         operand *right, *left, *result;
7690         int size, offset;
7691         //  char *l;
7692         symbol *tlbl, *tlbl1 ;
7693         pCodeOp *pctemp;
7694         
7695         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7696         
7697         /* we do it the hard way put the shift count in b
7698         and loop thru preserving the sign */
7699         FENTRY;
7700         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7701         
7702         right = IC_RIGHT(ic);
7703         left  = IC_LEFT(ic);
7704         result = IC_RESULT(ic);
7705         
7706         aopOp(right,ic,FALSE);  
7707         aopOp(left,ic,FALSE);
7708         aopOp(result,ic,FALSE);
7709         
7710         
7711         if ( AOP_TYPE(right) == AOP_LIT) {
7712                 genRightShiftLiteral (left,right,result,ic,1);
7713                 return ;
7714         }
7715         /* shift count is unknown then we have to form 
7716         a loop get the loop count in B : Note: we take
7717         only the lower order byte since shifting
7718         more that 32 bits make no sense anyway, ( the
7719         largest size of an object can be only 32 bits ) */  
7720         
7721         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7722         //pic14_emitcode("inc","b");
7723         //freeAsmop (right,NULL,ic,TRUE);
7724         //aopOp(left,ic,FALSE);
7725         //aopOp(result,ic,FALSE);
7726         
7727         /* now move the left to the result if they are not the
7728         same */
7729         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7730                 AOP_SIZE(result) > 1) {
7731                 
7732                 size = AOP_SIZE(result);
7733                 offset=0;
7734                 while (size--) { 
7735                         /*
7736                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7737                         if (*l == '@' && IS_AOP_PREG(result)) {
7738                                 pic14_emitcode("mov","a,%s",l);
7739                                 aopPut(AOP(result),"a",offset);
7740                         } else
7741                         aopPut(AOP(result),l,offset);
7742                         */
7743                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7744                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7745                         
7746                         offset++;
7747                 }
7748         }
7749         
7750         /* mov the highest order bit to OVR */    
7751         tlbl = newiTempLabel(NULL);
7752         tlbl1= newiTempLabel(NULL);
7753         
7754         size = AOP_SIZE(result);
7755         offset = size - 1;
7756         
7757         pctemp = popGetTempReg();  /* grab a temporary working register. */
7758         
7759         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7760         
7761         /* offset should be 0, 1 or 3 */
7762         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7763         emitSKPNZ;
7764         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7765         
7766         emitpcode(POC_MOVWF, pctemp);
7767         
7768         
7769         emitpLabel(tlbl->key);
7770         
7771         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7772         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7773         
7774         while(--size) {
7775                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7776         }
7777         
7778         emitpcode(POC_DECFSZ,  pctemp);
7779         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7780         emitpLabel(tlbl1->key);
7781         
7782         popReleaseTempReg(pctemp);
7783 #if 0
7784         size = AOP_SIZE(result);
7785         offset = size - 1;
7786         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7787         pic14_emitcode("rlc","a");
7788         pic14_emitcode("mov","ov,c");
7789         /* if it is only one byte then */
7790         if (size == 1) {
7791                 l = aopGet(AOP(left),0,FALSE,FALSE);
7792                 MOVA(l);
7793                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7794                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7795                 pic14_emitcode("mov","c,ov");
7796                 pic14_emitcode("rrc","a");
7797                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7798                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7799                 aopPut(AOP(result),"a",0);
7800                 goto release ;
7801         }
7802         
7803         reAdjustPreg(AOP(result));
7804         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7805         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7806         pic14_emitcode("mov","c,ov");
7807         while (size--) {
7808                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7809                 MOVA(l);
7810                 pic14_emitcode("rrc","a");         
7811                 aopPut(AOP(result),"a",offset--);
7812         }
7813         reAdjustPreg(AOP(result));
7814         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7815         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7816         
7817 release:
7818 #endif
7819         
7820         freeAsmop(left,NULL,ic,TRUE);
7821         freeAsmop(result,NULL,ic,TRUE);
7822         freeAsmop(right,NULL,ic,TRUE);
7823 }
7824
7825 /*-----------------------------------------------------------------*/
7826 /* genRightShift - generate code for right shifting                */
7827 /*-----------------------------------------------------------------*/
7828 static void genRightShift (iCode *ic)
7829 {
7830         operand *right, *left, *result;
7831         sym_link *retype ;
7832         int size, offset;
7833         char *l;
7834         symbol *tlbl, *tlbl1 ;
7835         
7836         FENTRY;
7837         /* if signed then we do it the hard way preserve the
7838         sign bit moving it inwards */
7839         retype = getSpec(operandType(IC_RESULT(ic)));
7840         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7841         
7842         if (!SPEC_USIGN(retype)) {
7843                 genSignedRightShift (ic);
7844                 return ;
7845         }
7846         
7847         /* signed & unsigned types are treated the same : i.e. the
7848         signed is NOT propagated inwards : quoting from the
7849         ANSI - standard : "for E1 >> E2, is equivalent to division
7850         by 2**E2 if unsigned or if it has a non-negative value,
7851         otherwise the result is implementation defined ", MY definition
7852         is that the sign does not get propagated */
7853         
7854         right = IC_RIGHT(ic);
7855         left  = IC_LEFT(ic);
7856         result = IC_RESULT(ic);
7857         
7858         aopOp(right,ic,FALSE);
7859         
7860         /* if the shift count is known then do it 
7861         as efficiently as possible */
7862         if (AOP_TYPE(right) == AOP_LIT) {
7863                 genRightShiftLiteral (left,right,result,ic, 0);
7864                 return ;
7865         }
7866         
7867         /* shift count is unknown then we have to form 
7868         a loop get the loop count in B : Note: we take
7869         only the lower order byte since shifting
7870         more that 32 bits make no sense anyway, ( the
7871         largest size of an object can be only 32 bits ) */  
7872         
7873         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7874         pic14_emitcode("inc","b");
7875         aopOp(left,ic,FALSE);
7876         aopOp(result,ic,FALSE);
7877         
7878         /* now move the left to the result if they are not the
7879         same */
7880         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7881                 AOP_SIZE(result) > 1) {
7882                 
7883                 size = AOP_SIZE(result);
7884                 offset=0;
7885                 while (size--) {
7886                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7887                         if (*l == '@' && IS_AOP_PREG(result)) {
7888                                 
7889                                 pic14_emitcode("mov","a,%s",l);
7890                                 aopPut(AOP(result),"a",offset);
7891                         } else
7892                                 aopPut(AOP(result),l,offset);
7893                         offset++;
7894                 }
7895         }
7896         
7897         tlbl = newiTempLabel(NULL);
7898         tlbl1= newiTempLabel(NULL);
7899         size = AOP_SIZE(result);
7900         offset = size - 1;
7901         
7902         /* if it is only one byte then */
7903         if (size == 1) {
7904                 
7905                 tlbl = newiTempLabel(NULL);
7906                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7907                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7908                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7909                 }
7910                 
7911                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7912                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7913                 emitpLabel(tlbl->key);
7914                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7915                 emitpcode(POC_ADDLW,  popGetLit(1));
7916                 emitSKPC;
7917                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7918                 
7919                 goto release ;
7920         }
7921         
7922         reAdjustPreg(AOP(result));
7923         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7924         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7925         CLRC;
7926         while (size--) {
7927                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7928                 MOVA(l);
7929                 pic14_emitcode("rrc","a");         
7930                 aopPut(AOP(result),"a",offset--);
7931         }
7932         reAdjustPreg(AOP(result));
7933         
7934         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7935         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7936         
7937 release:
7938         freeAsmop(left,NULL,ic,TRUE);
7939         freeAsmop (right,NULL,ic,TRUE);
7940         freeAsmop(result,NULL,ic,TRUE);
7941 }
7942
7943 /*-----------------------------------------------------------------*/
7944 /* genUnpackBits - generates code for unpacking bits               */
7945 /*-----------------------------------------------------------------*/
7946 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7947 {    
7948         int shCnt;
7949         int offset = 0;       /* result byte offset */
7950         int rsize;            /* result size */
7951         int rlen = 0;         /* remaining bitfield length */
7952         sym_link *etype;      /* bitfield type information */
7953         int blen;             /* bitfield length */
7954         int bstr;             /* bitfield starting bit within byte */
7955
7956         FENTRY;
7957         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7958         etype = getSpec(operandType(result));
7959         rsize = getSize (operandType (result));
7960         blen = SPEC_BLEN (etype);
7961         bstr = SPEC_BSTR (etype);
7962         
7963         /* single bit field case */
7964         if (blen == 1) {
7965                 if (ifx) { /* that is for an if statement */
7966                         pCodeOp *pcop;
7967                         resolvedIfx rIfx;
7968                         resolveIfx(&rIfx,ifx);
7969                         if (ptype == -1) /* direct */
7970                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7971                         else
7972                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7973                         emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7974                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7975                         ifx->generated=1;
7976                 } else {
7977                         pCodeOp *pcop;
7978                         if (ptype == -1) /* direct */
7979                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7980                         else
7981                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7982                         emitpcode(POC_BTFSC,pcop);
7983                         emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7984
7985                         if (ptype == -1) /* direct */
7986                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7987                         else
7988                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7989                         emitpcode(POC_BTFSS,pcop);
7990                         emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7991                 }
7992                 return;
7993         }
7994
7995         /* read the first byte  */
7996         switch (ptype) {
7997                 
7998         case POINTER:
7999         case IPOINTER:
8000 //              pic14_emitcode("mov","a,@%s",rname);
8001                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8002                 break;
8003                 
8004         case PPOINTER:
8005                 pic14_emitcode("movx","a,@%s",rname);
8006                 break;
8007                 
8008         case FPOINTER:
8009                 pic14_emitcode("movx","a,@dptr");
8010                 break;
8011                 
8012         case CPOINTER:
8013                 pic14_emitcode("clr","a");
8014                 pic14_emitcode("movc","a","@a+dptr");
8015                 break;
8016                 
8017         case GPOINTER:
8018                 pic14_emitcode("lcall","__gptrget");
8019                 break;
8020         }
8021
8022         /* if we have bitdisplacement then it fits   */
8023         /* into this byte completely or if length is */
8024         /* less than a byte                          */
8025         if ((shCnt = SPEC_BSTR(etype)) || blen <= 8)  {
8026                 
8027                 /* shift right acc */
8028                 AccRsh(left,0,shCnt);
8029                 
8030                 pic14_emitcode("anl","a,#0x%02x",
8031                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8032                 aopPut(AOP(result),"a",offset);
8033                 return ;
8034         }
8035         
8036         /* bit field did not fit in a byte  */
8037         rlen = SPEC_BLEN(etype) - 8;
8038         aopPut(AOP(result),"a",offset++);
8039         
8040         while (1)  {
8041                 
8042                 switch (ptype) {
8043                 case POINTER:
8044                 case IPOINTER:
8045                         pic14_emitcode("inc","%s",rname);
8046                         pic14_emitcode("mov","a,@%s",rname);
8047                         break;
8048                         
8049                 case PPOINTER:
8050                         pic14_emitcode("inc","%s",rname);
8051                         pic14_emitcode("movx","a,@%s",rname);
8052                         break;
8053                         
8054                 case FPOINTER:
8055                         pic14_emitcode("inc","dptr");
8056                         pic14_emitcode("movx","a,@dptr");
8057                         break;
8058                         
8059                 case CPOINTER:
8060                         pic14_emitcode("clr","a");
8061                         pic14_emitcode("inc","dptr");
8062                         pic14_emitcode("movc","a","@a+dptr");
8063                         break;
8064                         
8065                 case GPOINTER:
8066                         pic14_emitcode("inc","dptr");
8067                         pic14_emitcode("lcall","__gptrget");
8068                         break;
8069                 }
8070                 
8071                 rlen -= 8;            
8072                 /* if we are done */
8073                 if ( rlen <= 0 )
8074                         break ;
8075                 
8076                 aopPut(AOP(result),"a",offset++);
8077                 
8078         }
8079         
8080         if (rlen) {
8081                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8082                 aopPut(AOP(result),"a",offset);        
8083         }
8084         
8085         return ;
8086 }
8087
8088 #if 1
8089 /*-----------------------------------------------------------------*/
8090 /* genDataPointerGet - generates code when ptr offset is known     */
8091 /*-----------------------------------------------------------------*/
8092 static void genDataPointerGet (operand *left, 
8093         operand *result, 
8094         iCode *ic)
8095 {
8096         int size , offset = 0;
8097                 
8098         FENTRY;
8099         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8100         
8101         
8102         /* optimization - most of the time, left and result are the same
8103         * address, but different types. for the pic code, we could omit
8104         * the following
8105         */
8106         aopOp(result,ic,TRUE);
8107         
8108         if (pic14_sameRegs (AOP(left), AOP(result)))
8109                 return;
8110         
8111         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8112         
8113         //emitpcode(POC_MOVFW, popGet(AOP(left),0));
8114         
8115         size = AOP_SIZE(result);
8116         if (size > AOP_SIZE(left)) size = AOP_SIZE(left);
8117         
8118         while (size--) {
8119                 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
8120                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8121                 offset++;
8122         }
8123         
8124         freeAsmop(left,NULL,ic,TRUE);
8125         freeAsmop(result,NULL,ic,TRUE);
8126 }
8127 #endif
8128 /*-----------------------------------------------------------------*/
8129 /* genNearPointerGet - pic14_emitcode for near pointer fetch       */
8130 /*-----------------------------------------------------------------*/
8131 static void genNearPointerGet (operand *left, 
8132                                                            operand *result, 
8133                                                            iCode *ic)
8134 {
8135         asmop *aop = NULL;
8136         sym_link *ltype = operandType(left);
8137         sym_link *rtype = operandType(result);
8138         sym_link *retype= getSpec(rtype);      /* bitfield type information */
8139         int direct = 0;
8140
8141         FENTRY;
8142         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8143         
8144         
8145         aopOp(left,ic,FALSE);
8146         
8147         /* if left is rematerialisable and
8148         result is not bit variable type and
8149         the left is pointer to data space i.e
8150         lower 128 bytes of space */
8151         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8152                 !IS_BITVAR(retype)         &&
8153                 DCL_TYPE(ltype) == POINTER) {
8154                 genDataPointerGet (left,result,ic);
8155                 return ;
8156         }
8157         
8158         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8159         aopOp (result,ic,FALSE);
8160         
8161         /* Check if can access directly instead of via a pointer */
8162         if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
8163                 direct = 1;
8164         }
8165
8166         /* If the pointer value is not in a the FSR then need to put it in */
8167         if (!AOP_INPREG(AOP(left)) && !direct) {
8168                 /* otherwise get a free pointer register */
8169                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8170                 if (PCOP(AOP(result))->type == PO_LITERAL) 
8171                         emitpcode(POC_MOVLW, popGet(AOP(left),0));
8172                 else
8173                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
8174                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8175         }
8176         
8177         
8178 //      sym_link *etype;
8179         /* if bitfield then unpack the bits */
8180         if (IS_BITFIELD(retype)) 
8181                 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8182         else {
8183                 /* we have can just get the values */
8184                 int size = AOP_SIZE(result);
8185                 int offset = 0 ;  
8186                 
8187                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8188                 
8189                 while(size--) {
8190                         if (direct)
8191                                 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8192                         else
8193                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8194                         if (AOP_TYPE(result) == AOP_LIT) {
8195                                 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8196                         } else {
8197                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8198                         }
8199                         if (size && !direct)
8200                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8201                         offset++;
8202                 }
8203         }
8204         
8205         /* now some housekeeping stuff */
8206         if (aop) {
8207                 /* we had to allocate for this iCode */
8208                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8209                 freeAsmop(NULL,aop,ic,TRUE);
8210         } else { 
8211                 /* we did not allocate which means left
8212                 already in a pointer register, then
8213                 if size > 0 && this could be used again
8214                 we have to point it back to where it 
8215                 belongs */
8216                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8217                 if (AOP_SIZE(result) > 1 &&
8218                         !OP_SYMBOL(left)->remat &&
8219                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8220                         ic->depth )) {
8221                         int size = AOP_SIZE(result) - 1;
8222                         while (size--)
8223                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8224                 }
8225         }
8226         
8227         /* done */
8228         freeAsmop(left,NULL,ic,TRUE);
8229         freeAsmop(result,NULL,ic,TRUE);
8230
8231 }
8232
8233 /*-----------------------------------------------------------------*/
8234 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8235 /*-----------------------------------------------------------------*/
8236 static void genPagedPointerGet (operand *left, 
8237                                                                 operand *result, 
8238                                                                 iCode *ic)
8239 {
8240         asmop *aop = NULL;
8241         regs *preg = NULL ;
8242         char *rname ;
8243         sym_link *rtype, *retype;    
8244         
8245         FENTRY;
8246         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8247         
8248         rtype = operandType(result);
8249         retype= getSpec(rtype);
8250         
8251         aopOp(left,ic,FALSE);
8252         
8253         /* if the value is already in a pointer register
8254         then don't need anything more */
8255         if (!AOP_INPREG(AOP(left))) {
8256                 /* otherwise get a free pointer register */
8257                 aop = newAsmop(0);
8258                 preg = getFreePtr(ic,&aop,FALSE);
8259                 pic14_emitcode("mov","%s,%s",
8260                         preg->name,
8261                         aopGet(AOP(left),0,FALSE,TRUE));
8262                 rname = preg->name ;
8263         } else
8264                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8265         
8266         freeAsmop(left,NULL,ic,TRUE);
8267         aopOp (result,ic,FALSE);
8268         
8269         /* if bitfield then unpack the bits */
8270         if (IS_BITFIELD(retype)) 
8271                 genUnpackBits (result,left,rname,PPOINTER,0);
8272         else {
8273                 /* we have can just get the values */
8274                 int size = AOP_SIZE(result);
8275                 int offset = 0 ;  
8276                 
8277                 while (size--) {
8278                         
8279                         pic14_emitcode("movx","a,@%s",rname);
8280                         aopPut(AOP(result),"a",offset);
8281                         
8282                         offset++ ;
8283                         
8284                         if (size)
8285                                 pic14_emitcode("inc","%s",rname);
8286                 }
8287         }
8288         
8289         /* now some housekeeping stuff */
8290         if (aop) {
8291                 /* we had to allocate for this iCode */
8292                 freeAsmop(NULL,aop,ic,TRUE);
8293         } else { 
8294         /* we did not allocate which means left
8295         already in a pointer register, then
8296         if size > 0 && this could be used again
8297         we have to point it back to where it 
8298                 belongs */
8299                 if (AOP_SIZE(result) > 1 &&
8300                         !OP_SYMBOL(left)->remat &&
8301                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8302                         ic->depth )) {
8303                         int size = AOP_SIZE(result) - 1;
8304                         while (size--)
8305                                 pic14_emitcode("dec","%s",rname);
8306                 }
8307         }
8308         
8309         /* done */
8310         freeAsmop(result,NULL,ic,TRUE);
8311         
8312         
8313 }
8314
8315 /*-----------------------------------------------------------------*/
8316 /* genFarPointerGet - gget value from far space                    */
8317 /*-----------------------------------------------------------------*/
8318 static void genFarPointerGet (operand *left,
8319                                                           operand *result, iCode *ic)
8320 {
8321         int size, offset ;
8322         sym_link *retype = getSpec(operandType(result));
8323         
8324         FENTRY;
8325         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8326         
8327         aopOp(left,ic,FALSE);
8328         
8329         /* if the operand is already in dptr 
8330         then we do nothing else we move the value to dptr */
8331         if (AOP_TYPE(left) != AOP_STR) {
8332                 /* if this is remateriazable */
8333                 if (AOP_TYPE(left) == AOP_IMMD)
8334                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8335                 else { /* we need to get it byte by byte */
8336                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8337                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8338                         if (options.model == MODEL_FLAT24)
8339                         {
8340                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8341                         }
8342                 }
8343         }
8344         /* so dptr know contains the address */
8345         freeAsmop(left,NULL,ic,TRUE);
8346         aopOp(result,ic,FALSE);
8347         
8348         /* if bit then unpack */
8349         if (IS_BITFIELD(retype)) 
8350                 genUnpackBits(result,left,"dptr",FPOINTER,0);
8351         else {
8352                 size = AOP_SIZE(result);
8353                 offset = 0 ;
8354                 
8355                 while (size--) {
8356                         pic14_emitcode("movx","a,@dptr");
8357                         aopPut(AOP(result),"a",offset++);
8358                         if (size)
8359                                 pic14_emitcode("inc","dptr");
8360                 }
8361         }
8362         
8363         freeAsmop(result,NULL,ic,TRUE);
8364 }
8365 #if 0
8366 /*-----------------------------------------------------------------*/
8367 /* genCodePointerGet - get value from code space                  */
8368 /*-----------------------------------------------------------------*/
8369 static void genCodePointerGet (operand *left,
8370                                                            operand *result, iCode *ic)
8371 {
8372         int size, offset ;
8373         sym_link *retype = getSpec(operandType(result));
8374         
8375         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8376         
8377         aopOp(left,ic,FALSE);
8378         
8379         /* if the operand is already in dptr 
8380         then we do nothing else we move the value to dptr */
8381         if (AOP_TYPE(left) != AOP_STR) {
8382                 /* if this is remateriazable */
8383                 if (AOP_TYPE(left) == AOP_IMMD)
8384                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8385                 else { /* we need to get it byte by byte */
8386                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8387                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8388                         if (options.model == MODEL_FLAT24)
8389                         {
8390                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8391                         }
8392                 }
8393         }
8394         /* so dptr know contains the address */
8395         freeAsmop(left,NULL,ic,TRUE);
8396         aopOp(result,ic,FALSE);
8397         
8398         /* if bit then unpack */
8399         if (IS_BITFIELD(retype)) 
8400                 genUnpackBits(result,left,"dptr",CPOINTER,0);
8401         else {
8402                 size = AOP_SIZE(result);
8403                 offset = 0 ;
8404                 
8405                 while (size--) {
8406                         pic14_emitcode("clr","a");
8407                         pic14_emitcode("movc","a,@a+dptr");
8408                         aopPut(AOP(result),"a",offset++);
8409                         if (size)
8410                                 pic14_emitcode("inc","dptr");
8411                 }
8412         }
8413         
8414         freeAsmop(result,NULL,ic,TRUE);
8415 }
8416 #endif
8417 /*-----------------------------------------------------------------*/
8418 /* genGenPointerGet - gget value from generic pointer space        */
8419 /*-----------------------------------------------------------------*/
8420 static void genGenPointerGet (operand *left,
8421                                                           operand *result, iCode *ic)
8422 {
8423         int size, offset ;
8424         sym_link *retype = getSpec(operandType(result));
8425         
8426         FENTRY;
8427         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8428         aopOp(left,ic,FALSE);
8429         aopOp(result,ic,FALSE);
8430         
8431         
8432         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8433         
8434         /* if the operand is already in dptr 
8435         then we do nothing else we move the value to dptr */
8436         //  if (AOP_TYPE(left) != AOP_STR) {
8437         /* if this is remateriazable */
8438         if (AOP_TYPE(left) == AOP_IMMD) {
8439                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8440                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8441         }
8442         else { /* we need to get it byte by byte */
8443                 
8444                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8445                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8446                 
8447                 size = AOP_SIZE(result);
8448                 offset = 0 ;
8449                 
8450                 while(size--) {
8451                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8452                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8453                         if(size)
8454                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8455                 }
8456                 goto release;
8457         }
8458         //}
8459         /* so dptr know contains the address */
8460         
8461         /* if bit then unpack */
8462         //if (IS_BITFIELD(retype)) 
8463         //  genUnpackBits(result,"dptr",GPOINTER);
8464         
8465 release:
8466         freeAsmop(left,NULL,ic,TRUE);
8467         freeAsmop(result,NULL,ic,TRUE);
8468         
8469 }
8470
8471 /*-----------------------------------------------------------------*/
8472 /* genConstPointerGet - get value from const generic pointer space */
8473 /*-----------------------------------------------------------------*/
8474 static void genConstPointerGet (operand *left,
8475                                                                 operand *result, iCode *ic)
8476 {
8477         //sym_link *retype = getSpec(operandType(result));
8478         symbol *albl = newiTempLabel(NULL);
8479         symbol *blbl = newiTempLabel(NULL);
8480         PIC_OPCODE poc;
8481         pCodeOp *pcop;
8482         
8483         FENTRY;
8484         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8485         aopOp(left,ic,FALSE);
8486         aopOp(result,ic,FALSE);
8487         
8488         
8489         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8490         
8491         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8492         
8493         emitpcode(POC_CALL,popGetLabel(albl->key));
8494         pcop = popGetLabel(blbl->key);
8495         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8496         emitpcode(POC_GOTO,pcop);
8497         emitpLabel(albl->key);
8498         
8499         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8500         
8501         emitpcode(poc,popGet(AOP(left),1));
8502         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8503         emitpcode(poc,popGet(AOP(left),0));
8504         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8505         
8506         emitpLabel(blbl->key);
8507         
8508         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8509         
8510         
8511         freeAsmop(left,NULL,ic,TRUE);
8512         freeAsmop(result,NULL,ic,TRUE);
8513         
8514 }
8515 /*-----------------------------------------------------------------*/
8516 /* genPointerGet - generate code for pointer get                   */
8517 /*-----------------------------------------------------------------*/
8518 static void genPointerGet (iCode *ic)
8519 {
8520         operand *left, *result ;
8521         sym_link *type, *etype;
8522         int p_type;
8523         
8524         FENTRY;
8525         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8526         
8527         left = IC_LEFT(ic);
8528         result = IC_RESULT(ic) ;
8529         
8530         /* depending on the type of pointer we need to
8531         move it to the correct pointer register */
8532         type = operandType(left);
8533         etype = getSpec(type);
8534         
8535         if (IS_PTR_CONST(type))
8536                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8537         
8538         /* if left is of type of pointer then it is simple */
8539         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8540                 p_type = DCL_TYPE(type);
8541         else {
8542                 /* we have to go by the storage class */
8543                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8544                 
8545                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8546                 
8547                 if (SPEC_OCLS(etype)->codesp ) {
8548                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8549                         //p_type = CPOINTER ; 
8550                 }
8551                 else
8552                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8553                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8554                         /*p_type = FPOINTER ;*/ 
8555                         else
8556                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8557                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8558                                 /*        p_type = PPOINTER; */
8559                                 else
8560                                         if (SPEC_OCLS(etype) == idata )
8561                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8562                                         /*      p_type = IPOINTER; */
8563                                         else
8564                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8565                                         /*      p_type = POINTER ; */
8566         }
8567         
8568         /* now that we have the pointer type we assign
8569         the pointer values */
8570         switch (p_type) {
8571                 
8572         case POINTER: 
8573         case IPOINTER:
8574                 genNearPointerGet (left,result,ic);
8575                 break;
8576                 
8577         case PPOINTER:
8578                 genPagedPointerGet(left,result,ic);
8579                 break;
8580                 
8581         case FPOINTER:
8582                 genFarPointerGet (left,result,ic);
8583                 break;
8584                 
8585         case CPOINTER:
8586                 genConstPointerGet (left,result,ic);
8587                 //pic14_emitcodePointerGet (left,result,ic);
8588                 break;
8589                 
8590         case GPOINTER:
8591                 if (IS_PTR_CONST(type))
8592                         genConstPointerGet (left,result,ic);
8593                 else
8594                         genGenPointerGet (left,result,ic);
8595                 break;
8596         }
8597         
8598 }
8599
8600 /*-----------------------------------------------------------------*/
8601 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into  */
8602 /* A through a pointer register (R0, R1, or DPTR). The original    */
8603 /* value of A can be preserved in B.                               */
8604 /* PIC has to use INDF register.                                   */
8605 /*-----------------------------------------------------------------*/
8606 static void
8607 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8608 {
8609     FENTRY;
8610     switch (p_type)
8611     {
8612     case IPOINTER:
8613     case POINTER:
8614                 if (preserveAinB)
8615                         pic14_emitcode ("mov", "b,a");
8616 //              pic14_emitcode ("mov", "a,@%s", rname);
8617                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8618                 break;
8619                 
8620     case PPOINTER:
8621                 if (preserveAinB)
8622                         pic14_emitcode ("mov", "b,a");
8623                 pic14_emitcode ("movx", "a,@%s", rname);
8624                 break;
8625                 
8626     case FPOINTER:
8627                 if (preserveAinB)
8628                         pic14_emitcode ("mov", "b,a");
8629                 pic14_emitcode ("movx", "a,@dptr");
8630                 break;
8631                 
8632     case CPOINTER:
8633                 if (preserveAinB)
8634                         pic14_emitcode ("mov", "b,a");
8635                 pic14_emitcode ("clr", "a");
8636                 pic14_emitcode ("movc", "a,@a+dptr");
8637                 break;
8638                 
8639     case GPOINTER:
8640                 if (preserveAinB)
8641         {
8642                         pic14_emitcode ("push", "b");
8643                         pic14_emitcode ("push", "acc");
8644         }
8645                 pic14_emitcode ("lcall", "__gptrget");
8646                 if (preserveAinB)
8647                         pic14_emitcode ("pop", "b");
8648                 break;
8649     }
8650 }
8651
8652 /*-----------------------------------------------------------------*/
8653 /* emitPtrByteSet - emits code to set a byte from src through a    */
8654 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR).       */
8655 /*-----------------------------------------------------------------*/
8656 static void
8657 emitPtrByteSet (char *rname, int p_type, char *src)
8658 {
8659     FENTRY;
8660     switch (p_type)
8661     {
8662     case IPOINTER:
8663     case POINTER:
8664                 if (*src=='@')
8665         {
8666                         MOVA (src);
8667                         pic14_emitcode ("mov", "@%s,a", rname);
8668         }
8669                 else
8670 //                      pic14_emitcode ("mov", "@%s,%s", rname, src);
8671                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8672                 break;
8673                 
8674     case PPOINTER:
8675                 MOVA (src);
8676                 pic14_emitcode ("movx", "@%s,a", rname);
8677                 break;
8678                 
8679     case FPOINTER:
8680                 MOVA (src);
8681                 pic14_emitcode ("movx", "@dptr,a");
8682                 break;
8683                 
8684     case GPOINTER:
8685                 MOVA (src);
8686                 pic14_emitcode ("lcall", "__gptrput");
8687                 break;
8688     }
8689 }
8690
8691 /*-----------------------------------------------------------------*/
8692 /* genPackBits - generates code for packed bit storage             */
8693 /*-----------------------------------------------------------------*/
8694 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8695 {
8696         int offset = 0;       /* source byte offset */
8697         int rlen = 0;         /* remaining bitfield length */
8698         int blen;             /* bitfield length */
8699         int bstr;             /* bitfield starting bit within byte */
8700         int litval;           /* source literal value (if AOP_LIT) */
8701         unsigned char mask;   /* bitmask within current byte */
8702
8703         FENTRY;
8704         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8705         
8706         blen = SPEC_BLEN (etype);
8707         bstr = SPEC_BSTR (etype);
8708         
8709         /* If the bitfield length is less than a byte */
8710         if (blen < 8)
8711     {
8712                 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8713                         (unsigned char) (0xFF >> (8 - bstr)));
8714                 
8715                 if (AOP_TYPE (right) == AOP_LIT)
8716         {
8717                         /* Case with a bitfield length <8 and literal source
8718                         */
8719                         int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8720                         if (blen == 1) {
8721                                 if (p_type == -1) {
8722                                         pCodeOp *pcop;
8723                                         if (AOP(result)->type == AOP_PCODE)
8724                                                 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8725                                         else
8726                                                 pcop = popGet(AOP(result),0);
8727                                         emitpcode(lit?POC_BSF:POC_BCF,pcop);
8728                                 } else {
8729                                         emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8730                                 }
8731                                 return;
8732                         } else {
8733                                 litval = lit << bstr;
8734                                 litval &= (~mask) & 0xff;
8735                                 if (p_type == -1)
8736                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8737                                 else
8738                                         emitPtrByteGet (rname, p_type, FALSE);
8739                                 if ((mask|litval)!=0xff)
8740                                         emitpcode(POC_ANDLW,popGetLit(mask));
8741                                 if (litval)
8742                                         emitpcode(POC_IORLW,popGetLit(litval));
8743                         }
8744         }
8745                 else
8746         {
8747                         if (blen==1) {
8748                                 if (p_type == -1) {
8749                                         /* 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 */
8750                                         emitpcode(POC_RLF,popGet(AOP(right),0));
8751                                         emitSKPC;
8752                                         emitpcode(POC_BCF,popGet(AOP(result),0));
8753                                         emitSKPNC;
8754                                         emitpcode(POC_BSF,popGet(AOP(result),0));
8755                                 } else if (p_type!=GPOINTER) {
8756                                         /* Case with a bitfield length == 1 and no generic pointer
8757                                         */
8758                                         if (AOP_TYPE (right) == AOP_CRY)
8759                                                 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8760                                         else
8761                                         {
8762                                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8763                                                 pic14_emitcode ("rrc","a");
8764                                         }
8765                                         emitPtrByteGet (rname, p_type, FALSE);
8766                                         pic14_emitcode ("mov","acc.%d,c",bstr);
8767                                 }
8768             }
8769                         else
8770             {
8771                                 //bool pushedB;
8772                                 /* Case with a bitfield length < 8 and arbitrary source
8773                                 */
8774                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8775                                 /* shift and mask source value */
8776                                 AccLsh (right,0,bstr);
8777                                 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8778                                 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8779                                 
8780                                 //pushedB = pushB ();
8781                                 if (p_type == -1)
8782                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8783                                 else
8784                                         emitPtrByteGet (rname, p_type, TRUE);
8785                                 
8786                                 pic14_emitcode ("anl", "a,#0x%02x", mask);
8787                                 pic14_emitcode ("orl", "a,b");
8788                                 emitpcode(POC_ANDLW,popGetLit(mask));
8789                                 emitpcode(POC_IORFW,popGet(AOP(right),0));
8790                                 if (p_type == GPOINTER)
8791                                         pic14_emitcode ("pop", "b");
8792                                 
8793                                 //popB (pushedB);
8794                         }
8795         }
8796                 
8797                 if (p_type == -1)
8798                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8799                 else
8800                         emitPtrByteSet (rname, p_type, "a");
8801                 return;
8802     }
8803         
8804         /* Bit length is greater than 7 bits. In this case, copy  */
8805         /* all except the partial byte at the end                 */
8806         for (rlen=blen;rlen>=8;rlen-=8)
8807     {
8808                 emitPtrByteSet (rname, p_type,
8809                         aopGet (AOP (right), offset++, FALSE, TRUE) );
8810                 if (rlen>8)
8811                         pic14_emitcode ("inc", "%s", rname);
8812     }
8813         
8814         /* If there was a partial byte at the end */
8815         if (rlen)
8816     {
8817                 mask = (((unsigned char) -1 << rlen) & 0xff);
8818                 
8819                 if (AOP_TYPE (right) == AOP_LIT)
8820         {
8821                 /* Case with partial byte and literal source
8822                         */
8823                         litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8824                         litval >>= (blen-rlen);
8825                         litval &= (~mask) & 0xff;
8826                         emitPtrByteGet (rname, p_type, FALSE);
8827                         if ((mask|litval)!=0xff)
8828                                 pic14_emitcode ("anl","a,#0x%02x", mask);
8829                         if (litval)
8830                                 pic14_emitcode ("orl","a,#0x%02x", litval);
8831         }
8832                 else
8833         {
8834                         //bool pushedB;
8835                         /* Case with partial byte and arbitrary source
8836                         */
8837                         MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8838                         pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8839                         
8840                         //pushedB = pushB ();
8841                         /* transfer A to B and get next byte */
8842                         emitPtrByteGet (rname, p_type, TRUE);
8843                         
8844                         pic14_emitcode ("anl", "a,#0x%02x", mask);
8845                         pic14_emitcode ("orl", "a,b");
8846                         if (p_type == GPOINTER)
8847                                 pic14_emitcode ("pop", "b");
8848                         
8849                         //popB (pushedB);
8850         }
8851                 emitPtrByteSet (rname, p_type, "a");
8852     }
8853         
8854 }
8855
8856 /*-----------------------------------------------------------------*/
8857 /* SetIrp - Set IRP bit                                            */
8858 /*-----------------------------------------------------------------*/
8859 void SetIrp(operand *result) {
8860         FENTRY;
8861         if (AOP_TYPE(result) == AOP_LIT) {
8862                 unsigned lit = (unsigned)operandLitValue(result);
8863                 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8864         } else {
8865                 if (PCOP(AOP(result))->type == PO_LITERAL) {
8866                         int addrs = PCOL(AOP(result))->lit;
8867                         emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8868                 } else {
8869                         emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8870                         if(AOP_SIZE(result) > 1) {
8871                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8872                                 emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8873                         }
8874                 }
8875         }
8876 }
8877
8878 /*-----------------------------------------------------------------*/
8879 /* genDataPointerSet - remat pointer to data space                 */
8880 /*-----------------------------------------------------------------*/
8881 static void genDataPointerSet(operand *right,
8882         operand *result,
8883         iCode *ic)
8884 {
8885         int size, offset = 0 ;
8886         char *l, buffer[256];
8887         
8888         FENTRY;
8889         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8890         aopOp(right,ic,FALSE);
8891         
8892         l = aopGet(AOP(result),0,FALSE,TRUE);
8893         size = AOP_SIZE(right);
8894         /*
8895         if ( AOP_TYPE(result) == AOP_PCODE) {
8896         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8897         AOP(result)->aopu.pcop->name,
8898         PCOI(AOP(result)->aopu.pcop)->offset);
8899         }
8900         */
8901         
8902         // tsd, was l+1 - the underline `_' prefix was being stripped
8903         while (size--) {
8904                 emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
8905                 if (offset) {
8906                         sprintf(buffer,"(%s + %d)",l,offset);
8907                         fprintf(stderr,"%s:%i: oops  %s (%i, AOP_LIT=%i)\n",__FILE__,__LINE__,buffer, AOP_TYPE(right), AOP_LIT);
8908                 } else
8909                         sprintf(buffer,"%s",l);
8910                 
8911                 if (AOP_TYPE(right) == AOP_LIT) {
8912                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8913                         lit = lit >> (8*offset);
8914                         if(lit&0xff) {
8915                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8916                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8917                         } else {
8918                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8919                         }
8920                 } else {
8921                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8922                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8923                 }
8924                 
8925                 offset++;
8926         }
8927         
8928         freeAsmop(right,NULL,ic,TRUE);
8929         freeAsmop(result,NULL,ic,TRUE);
8930 }
8931
8932 /*-----------------------------------------------------------------*/
8933 /* genNearPointerSet - pic14_emitcode for near pointer put         */
8934 /*-----------------------------------------------------------------*/
8935 static void genNearPointerSet (operand *right,
8936                                                            operand *result, 
8937                                                            iCode *ic)
8938 {
8939         asmop *aop = NULL;
8940         sym_link *ptype = operandType(result);
8941         sym_link *retype = getSpec(operandType(right));
8942         sym_link *letype = getSpec(ptype);
8943         int direct = 0;
8944         
8945         
8946         FENTRY;
8947         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8948         aopOp(result,ic,FALSE);
8949         
8950         
8951         /* if the result is rematerializable &
8952         in data space & not a bit variable */
8953         //if (AOP_TYPE(result) == AOP_IMMD &&
8954         if (AOP_TYPE(result) == AOP_PCODE &&
8955                 DCL_TYPE(ptype) == POINTER   &&
8956                 !IS_BITVAR (retype) &&
8957                 !IS_BITVAR (letype)) {
8958                 genDataPointerSet (right,result,ic);
8959                 freeAsmop(result,NULL,ic,TRUE);
8960                 return;
8961         }
8962
8963         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8964         aopOp(right,ic,FALSE);
8965         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8966         
8967         /* Check if can access directly instead of via a pointer */
8968         if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8969                 direct = 1;
8970         }
8971
8972         /* If the pointer value is not in a the FSR then need to put it in */
8973         if (!AOP_INPREG(AOP(result)) && !direct) {
8974                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8975                 if (PCOP(AOP(result))->type == PO_LITERAL) 
8976                         emitpcode(POC_MOVLW, popGet(AOP(result),0));
8977                 else
8978                         emitpcode(POC_MOVFW, popGet(AOP(result),0));
8979                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8980         }
8981
8982         /* Must set/reset IRP bit for use with FSR. */
8983         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8984         if (!direct)
8985                 SetIrp(result);
8986
8987         /* if bitfield then unpack the bits */
8988         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8989                 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8990         } else {
8991                 /* we have can just get the values */
8992                 int size = AOP_SIZE(right);
8993                 int offset = 0 ;    
8994                 
8995                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8996                 while (size--) {
8997                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8998                         if (*l == '@' ) {
8999                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9000                         } else {
9001                                 if (AOP_TYPE(right) == AOP_LIT) {
9002                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9003                                 } else {
9004                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9005                                 }
9006                                 if (direct)
9007                                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
9008                                 else
9009                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9010                         }
9011                         if (size && !direct)
9012                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9013                         offset++;
9014                 }
9015         }
9016         
9017         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9018         /* now some housekeeping stuff */
9019         if (aop) {
9020                 /* we had to allocate for this iCode */
9021                 freeAsmop(NULL,aop,ic,TRUE);
9022         } else { 
9023                 /* we did not allocate which means left
9024                 already in a pointer register, then
9025                 if size > 0 && this could be used again
9026                 we have to point it back to where it 
9027                 belongs */
9028                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9029                 if (AOP_SIZE(right) > 1 &&
9030                         !OP_SYMBOL(result)->remat &&
9031                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
9032                         ic->depth )) {
9033                         int size = AOP_SIZE(right) - 1;
9034                         while (size--)
9035                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
9036                 }
9037         }
9038         
9039         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9040         /* done */
9041
9042         freeAsmop(right,NULL,ic,TRUE);
9043         freeAsmop(result,NULL,ic,TRUE);
9044 }
9045
9046 /*-----------------------------------------------------------------*/
9047 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
9048 /*-----------------------------------------------------------------*/
9049 static void genPagedPointerSet (operand *right,
9050                                                                 operand *result, 
9051                                                                 iCode *ic)
9052 {
9053         asmop *aop = NULL;
9054         regs *preg = NULL ;
9055         char *rname , *l;
9056         sym_link *retype;
9057         
9058         FENTRY;
9059         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9060         
9061         retype= getSpec(operandType(right));
9062         
9063         aopOp(result,ic,FALSE);
9064         
9065         /* if the value is already in a pointer register
9066         then don't need anything more */
9067         if (!AOP_INPREG(AOP(result))) {
9068                 /* otherwise get a free pointer register */
9069                 aop = newAsmop(0);
9070                 preg = getFreePtr(ic,&aop,FALSE);
9071                 pic14_emitcode("mov","%s,%s",
9072                         preg->name,
9073                         aopGet(AOP(result),0,FALSE,TRUE));
9074                 rname = preg->name ;
9075         } else
9076                 rname = aopGet(AOP(result),0,FALSE,FALSE);
9077         
9078         freeAsmop(result,NULL,ic,TRUE);
9079         aopOp (right,ic,FALSE);
9080         
9081         /* if bitfield then unpack the bits */
9082         if (IS_BITFIELD(retype)) 
9083                 genPackBits (retype,result,right,rname,PPOINTER);
9084         else {
9085                 /* we have can just get the values */
9086                 int size = AOP_SIZE(right);
9087                 int offset = 0 ;  
9088                 
9089                 while (size--) {
9090                         l = aopGet(AOP(right),offset,FALSE,TRUE);
9091                         
9092                         MOVA(l);
9093                         pic14_emitcode("movx","@%s,a",rname);
9094                         
9095                         if (size)
9096                                 pic14_emitcode("inc","%s",rname);
9097                         
9098                         offset++;
9099                 }
9100         }
9101         
9102         /* now some housekeeping stuff */
9103         if (aop) {
9104                 /* we had to allocate for this iCode */
9105                 freeAsmop(NULL,aop,ic,TRUE);
9106         } else { 
9107         /* we did not allocate which means left
9108         already in a pointer register, then
9109         if size > 0 && this could be used again
9110         we have to point it back to where it 
9111                 belongs */
9112                 if (AOP_SIZE(right) > 1 &&
9113                         !OP_SYMBOL(result)->remat &&
9114                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
9115                         ic->depth )) {
9116                         int size = AOP_SIZE(right) - 1;
9117                         while (size--)
9118                                 pic14_emitcode("dec","%s",rname);
9119                 }
9120         }
9121         
9122         /* done */
9123         freeAsmop(right,NULL,ic,TRUE);
9124         
9125         
9126 }
9127
9128 /*-----------------------------------------------------------------*/
9129 /* genFarPointerSet - set value from far space                     */
9130 /*-----------------------------------------------------------------*/
9131 static void genFarPointerSet (operand *right,
9132                                                           operand *result, iCode *ic)
9133 {
9134         int size, offset ;
9135         sym_link *retype = getSpec(operandType(right));
9136         
9137         FENTRY;
9138         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9139         aopOp(result,ic,FALSE);
9140         
9141         /* if the operand is already in dptr 
9142         then we do nothing else we move the value to dptr */
9143         if (AOP_TYPE(result) != AOP_STR) {
9144                 /* if this is remateriazable */
9145                 if (AOP_TYPE(result) == AOP_IMMD)
9146                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9147                 else { /* we need to get it byte by byte */
9148                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
9149                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
9150                         if (options.model == MODEL_FLAT24)
9151                         {
9152                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
9153                         }
9154                 }
9155         }
9156         /* so dptr know contains the address */
9157         freeAsmop(result,NULL,ic,TRUE);
9158         aopOp(right,ic,FALSE);
9159         
9160         /* if bit then unpack */
9161         if (IS_BITFIELD(retype)) 
9162                 genPackBits(retype,result,right,"dptr",FPOINTER);
9163         else {
9164                 size = AOP_SIZE(right);
9165                 offset = 0 ;
9166                 
9167                 while (size--) {
9168                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
9169                         MOVA(l);
9170                         pic14_emitcode("movx","@dptr,a");
9171                         if (size)
9172                                 pic14_emitcode("inc","dptr");
9173                 }
9174         }
9175         
9176         freeAsmop(right,NULL,ic,TRUE);
9177 }
9178
9179 /*-----------------------------------------------------------------*/
9180 /* genGenPointerSet - set value from generic pointer space         */
9181 /*-----------------------------------------------------------------*/
9182 static void genGenPointerSet (operand *right,
9183                                                           operand *result, iCode *ic)
9184 {
9185         sym_link *ptype = operandType(result);
9186         sym_link *retype = getSpec(operandType(right));
9187         sym_link *letype = getSpec (ptype);
9188         
9189         FENTRY;
9190         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9191         
9192         aopOp(result,ic,FALSE);
9193         aopOp(right,ic,FALSE);
9194         
9195         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9196         
9197         /* if the operand is already in dptr 
9198         then we do nothing else we move the value to dptr */
9199         if (AOP_TYPE(result) != AOP_STR) {
9200                 /* if this is remateriazable */
9201                 if (AOP_TYPE(result) == AOP_IMMD) {
9202                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9203                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9204                 }
9205                 else {
9206                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
9207                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9208
9209                         /* Must set/reset IRP bit for use with FSR. */
9210                         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9211                         SetIrp(result);
9212                 }
9213         }
9214
9215         /* if bitfield then unpack the bits */
9216         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9217                 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9218         } else {
9219                 /* we have can just get the values */
9220                 int size = AOP_SIZE(right);
9221                 int offset = 0 ;    
9222                 
9223                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9224                 while (size--) {
9225                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9226                         if (*l == '@' ) {
9227                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9228                         } else {
9229                                 if (AOP_TYPE(right) == AOP_LIT) {
9230                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9231                                 } else {
9232                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9233                                 }
9234                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9235                         }
9236                         if (size)
9237                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9238                         offset++;
9239                 }
9240         }
9241         
9242         freeAsmop(right,NULL,ic,TRUE);
9243         freeAsmop(result,NULL,ic,TRUE);
9244 }
9245
9246 /*-----------------------------------------------------------------*/
9247 /* genPointerSet - stores the value into a pointer location        */
9248 /*-----------------------------------------------------------------*/
9249 static void genPointerSet (iCode *ic)
9250 {    
9251         operand *right, *result ;
9252         sym_link *type, *etype;
9253         int p_type;
9254         
9255         FENTRY;
9256         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9257         
9258         right = IC_RIGHT(ic);
9259         result = IC_RESULT(ic) ;
9260         
9261         /* depending on the type of pointer we need to
9262         move it to the correct pointer register */
9263         type = operandType(result);
9264         etype = getSpec(type);
9265         /* if left is of type of pointer then it is simple */
9266         if (IS_PTR(type) && !IS_FUNC(type->next)) {
9267                 p_type = DCL_TYPE(type);
9268         }
9269         else {
9270                 /* we have to go by the storage class */
9271                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9272                 
9273                 /*  if (SPEC_OCLS(etype)->codesp ) { */
9274                 /*      p_type = CPOINTER ;  */
9275                 /*  } */
9276                 /*  else */
9277                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9278                 /*    p_type = FPOINTER ; */
9279                 /*      else */
9280                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9281                 /*        p_type = PPOINTER ; */
9282                 /*    else */
9283                 /*        if (SPEC_OCLS(etype) == idata ) */
9284                 /*      p_type = IPOINTER ; */
9285                 /*        else */
9286                 /*      p_type = POINTER ; */
9287         }
9288         
9289         /* now that we have the pointer type we assign
9290         the pointer values */
9291         switch (p_type) {
9292                 
9293         case POINTER:
9294         case IPOINTER:
9295                 genNearPointerSet (right,result,ic);
9296                 break;
9297                 
9298         case PPOINTER:
9299                 genPagedPointerSet (right,result,ic);
9300                 break;
9301                 
9302         case FPOINTER:
9303                 genFarPointerSet (right,result,ic);
9304                 break;
9305                 
9306         case GPOINTER:
9307                 genGenPointerSet (right,result,ic);
9308                 break;
9309                 
9310         default:
9311                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9312                         "genPointerSet: illegal pointer type");
9313         }
9314 }
9315
9316 /*-----------------------------------------------------------------*/
9317 /* genIfx - generate code for Ifx statement                        */
9318 /*-----------------------------------------------------------------*/
9319 static void genIfx (iCode *ic, iCode *popIc)
9320 {
9321         operand *cond = IC_COND(ic);
9322         int isbit =0;
9323         
9324         FENTRY;
9325         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9326         
9327         aopOp(cond,ic,FALSE);
9328         
9329         /* get the value into acc */
9330         if (AOP_TYPE(cond) != AOP_CRY)
9331                 pic14_toBoolean(cond);
9332         else
9333                 isbit = 1;
9334         /* the result is now in the accumulator */
9335         freeAsmop(cond,NULL,ic,TRUE);
9336         
9337         /* if there was something to be popped then do it */
9338         if (popIc)
9339                 genIpop(popIc);
9340         
9341         /* if the condition is  a bit variable */
9342         if (isbit && IS_ITEMP(cond) && 
9343                 SPIL_LOC(cond)) {
9344                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9345                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9346         }
9347         else {
9348                 if (isbit && !IS_ITEMP(cond))
9349                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9350                 else
9351                         genIfxJump(ic,"a");
9352         }
9353         ic->generated = 1;
9354         
9355 }
9356
9357 /*-----------------------------------------------------------------*/
9358 /* genAddrOf - generates code for address of                       */
9359 /*-----------------------------------------------------------------*/
9360 static void genAddrOf (iCode *ic)
9361 {
9362         operand *right, *result, *left;
9363         int size, offset ;
9364         
9365         FENTRY;
9366         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9367         
9368         
9369         //aopOp(IC_RESULT(ic),ic,FALSE);
9370         
9371         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9372         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9373         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9374         
9375         DEBUGpic14_AopType(__LINE__,left,right,result);
9376         
9377         size = AOP_SIZE(IC_RESULT(ic));
9378         offset = 0;
9379         
9380         while (size--) {
9381                 /* fixing bug #863624, reported from (errolv) */
9382                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9383                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9384                 
9385 #if 0
9386                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9387                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9388 #endif
9389                 offset++;
9390         }
9391         
9392         freeAsmop(left,NULL,ic,FALSE);
9393         freeAsmop(result,NULL,ic,TRUE);
9394         
9395 }
9396
9397 #if 0
9398 /*-----------------------------------------------------------------*/
9399 /* genFarFarAssign - assignment when both are in far space         */
9400 /*-----------------------------------------------------------------*/
9401 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9402 {
9403         int size = AOP_SIZE(right);
9404         int offset = 0;
9405         char *l ;
9406         /* first push the right side on to the stack */
9407         while (size--) {
9408                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9409                 MOVA(l);
9410                 pic14_emitcode ("push","acc");
9411         }
9412         
9413         freeAsmop(right,NULL,ic,FALSE);
9414         /* now assign DPTR to result */
9415         aopOp(result,ic,FALSE);
9416         size = AOP_SIZE(result);
9417         while (size--) {
9418                 pic14_emitcode ("pop","acc");
9419                 aopPut(AOP(result),"a",--offset);
9420         }
9421         freeAsmop(result,NULL,ic,FALSE);
9422         
9423 }
9424 #endif
9425
9426 /*-----------------------------------------------------------------*/
9427 /* genAssign - generate code for assignment                        */
9428 /*-----------------------------------------------------------------*/
9429 static void genAssign (iCode *ic)
9430 {
9431         operand *result, *right;
9432         int size, offset,know_W;
9433         unsigned long lit = 0L;
9434         
9435         result = IC_RESULT(ic);
9436         right  = IC_RIGHT(ic) ;
9437         
9438         FENTRY;
9439         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9440         
9441         /* if they are the same */
9442         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9443                 return ;
9444         
9445         aopOp(right,ic,FALSE);
9446         aopOp(result,ic,TRUE);
9447         
9448         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9449         
9450         /* if they are the same registers */
9451         if (pic14_sameRegs(AOP(right),AOP(result)))
9452                 goto release;
9453         
9454         /* if the result is a bit */
9455         if (AOP_TYPE(result) == AOP_CRY) {
9456                 
9457         /* if the right size is a literal then
9458                 we know what the value is */
9459                 if (AOP_TYPE(right) == AOP_LIT) {
9460                         
9461                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9462                                 popGet(AOP(result),0));
9463                         
9464                         if (((int) operandLitValue(right))) 
9465                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9466                                 AOP(result)->aopu.aop_dir,
9467                                 AOP(result)->aopu.aop_dir);
9468                         else
9469                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9470                                 AOP(result)->aopu.aop_dir,
9471                                 AOP(result)->aopu.aop_dir);
9472                         goto release;
9473                 }
9474                 
9475                 /* the right is also a bit variable */
9476                 if (AOP_TYPE(right) == AOP_CRY) {
9477                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9478                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9479                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9480                         
9481                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9482                                 AOP(result)->aopu.aop_dir,
9483                                 AOP(result)->aopu.aop_dir);
9484                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9485                                 AOP(right)->aopu.aop_dir,
9486                                 AOP(right)->aopu.aop_dir);
9487                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9488                                 AOP(result)->aopu.aop_dir,
9489                                 AOP(result)->aopu.aop_dir);
9490                         goto release ;
9491                 }
9492                 
9493                 /* we need to or */
9494                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9495                 pic14_toBoolean(right);
9496                 emitSKPZ;
9497                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9498                 //aopPut(AOP(result),"a",0);
9499                 goto release ;
9500         }
9501         
9502         /* bit variables done */
9503         /* general case */
9504         size = AOP_SIZE(result);
9505         offset = 0 ;
9506         if(AOP_TYPE(right) == AOP_LIT)
9507                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9508         
9509         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9510                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9511                 if(aopIdx(AOP(result),0) == 4) {
9512                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9513                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9514                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9515                         goto release;
9516                 } else
9517                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9518         }
9519         
9520         know_W=-1;
9521         while (size--) {
9522                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9523                 if(AOP_TYPE(right) == AOP_LIT) {
9524                         if(lit&0xff) {
9525                                 if(know_W != (int)(lit&0xff))
9526                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9527                                 know_W = lit&0xff;
9528                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9529                         } else
9530                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9531                         
9532                         lit >>= 8;
9533                         
9534                 } else if (AOP_TYPE(right) == AOP_CRY) {
9535                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9536                         if(offset == 0) {
9537                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9538                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9539                         }
9540                 } else {
9541                         mov2w (AOP(right), offset);
9542                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9543                 }
9544                 
9545                 offset++;
9546         }
9547         
9548         
9549 release:
9550         freeAsmop (right,NULL,ic,FALSE);
9551         freeAsmop (result,NULL,ic,TRUE);
9552 }   
9553
9554 /*-----------------------------------------------------------------*/
9555 /* genJumpTab - genrates code for jump table                       */
9556 /*-----------------------------------------------------------------*/
9557 static void genJumpTab (iCode *ic)
9558 {
9559         symbol *jtab;
9560         char *l;
9561         
9562         FENTRY;
9563         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9564         
9565         aopOp(IC_JTCOND(ic),ic,FALSE);
9566         /* get the condition into accumulator */
9567         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9568         MOVA(l);
9569         /* multiply by three */
9570         pic14_emitcode("add","a,acc");
9571         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9572         
9573         jtab = newiTempLabel(NULL);
9574         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9575         pic14_emitcode("jmp","@a+dptr");
9576         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9577         
9578         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9579         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9580         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9581         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9582         emitSKPNC;
9583         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9584         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9585         emitpLabel(jtab->key);
9586         
9587         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9588         
9589         /* now generate the jump labels */
9590         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9591         jtab = setNextItem(IC_JTLABELS(ic))) {
9592                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9593                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9594                 
9595         }
9596         
9597 }
9598
9599 /*-----------------------------------------------------------------*/
9600 /* genMixedOperation - gen code for operators between mixed types  */
9601 /*-----------------------------------------------------------------*/
9602 /*
9603 TSD - Written for the PIC port - but this unfortunately is buggy.
9604 This routine is good in that it is able to efficiently promote 
9605 types to different (larger) sizes. Unfortunately, the temporary
9606 variables that are optimized out by this routine are sometimes
9607 used in other places. So until I know how to really parse the 
9608 iCode tree, I'm going to not be using this routine :(.
9609 */
9610 static int genMixedOperation (iCode *ic)
9611 {
9612         FENTRY;
9613 #if 0
9614         operand *result = IC_RESULT(ic);
9615         sym_link *ctype = operandType(IC_LEFT(ic));
9616         operand *right = IC_RIGHT(ic);
9617         int ret = 0;
9618         int big,small;
9619         int offset;
9620         
9621         iCode *nextic;
9622         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9623         
9624         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9625         
9626         nextic = ic->next;
9627         if(!nextic)
9628                 return 0;
9629         
9630         nextright = IC_RIGHT(nextic);
9631         nextleft  = IC_LEFT(nextic);
9632         nextresult = IC_RESULT(nextic);
9633         
9634         aopOp(right,ic,FALSE);
9635         aopOp(result,ic,FALSE);
9636         aopOp(nextright,  nextic, FALSE);
9637         aopOp(nextleft,   nextic, FALSE);
9638         aopOp(nextresult, nextic, FALSE);
9639         
9640         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9641                 
9642                 operand *t = right;
9643                 right = nextright;
9644                 nextright = t; 
9645                 
9646                 pic14_emitcode(";remove right +","");
9647                 
9648         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9649         /*
9650         operand *t = right;
9651         right = nextleft;
9652         nextleft = t; 
9653                 */
9654                 pic14_emitcode(";remove left +","");
9655         } else
9656                 return 0;
9657         
9658         big = AOP_SIZE(nextleft);
9659         small = AOP_SIZE(nextright);
9660         
9661         switch(nextic->op) {
9662                 
9663         case '+':
9664                 pic14_emitcode(";optimize a +","");
9665                 /* if unsigned or not an integral type */
9666                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9667                         pic14_emitcode(";add a bit to something","");
9668                 } else {
9669                         
9670                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9671                         
9672                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9673                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9674                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9675                         } else
9676                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9677                         
9678                         offset = 0;
9679                         while(--big) {
9680                                 
9681                                 offset++;
9682                                 
9683                                 if(--small) {
9684                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9685                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9686                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9687                                         }
9688                                         
9689                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9690                                         emitSKPNC;
9691                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9692                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9693                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9694                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9695                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9696                                         
9697                                 } else {
9698                                         pic14_emitcode("rlf","known_zero,w");
9699                                         
9700                                         /*
9701                                         if right is signed
9702                                         btfsc  right,7
9703                                         addlw ff
9704                                         */
9705                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9706                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9707                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9708                                         } else {
9709                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9710                                         }
9711                                 }
9712                         }
9713                         ret = 1;
9714                 }
9715         }
9716         ret = 1;
9717         
9718 release:
9719         freeAsmop(right,NULL,ic,TRUE);
9720         freeAsmop(result,NULL,ic,TRUE);
9721         freeAsmop(nextright,NULL,ic,TRUE);
9722         freeAsmop(nextleft,NULL,ic,TRUE);
9723         if(ret)
9724                 nextic->generated = 1;
9725         
9726         return ret;
9727 #else
9728         return 0;
9729 #endif
9730 }
9731 /*-----------------------------------------------------------------*/
9732 /* genCast - gen code for casting                                  */
9733 /*-----------------------------------------------------------------*/
9734 static void genCast (iCode *ic)
9735 {
9736         operand *result = IC_RESULT(ic);
9737         sym_link *ctype = operandType(IC_LEFT(ic));
9738         sym_link *rtype = operandType(IC_RIGHT(ic));
9739         operand *right = IC_RIGHT(ic);
9740         int size, offset ;
9741         
9742         FENTRY;
9743         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9744         /* if they are equivalent then do nothing */
9745         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9746                 return ;
9747         
9748         aopOp(right,ic,FALSE) ;
9749         aopOp(result,ic,FALSE);
9750         
9751         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9752         
9753         /* if the result is a bit */
9754         if (AOP_TYPE(result) == AOP_CRY) {
9755         /* if the right size is a literal then
9756                 we know what the value is */
9757                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9758                 if (AOP_TYPE(right) == AOP_LIT) {
9759                         
9760                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9761                                 popGet(AOP(result),0));
9762                         
9763                         if (((int) operandLitValue(right))) 
9764                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9765                                 AOP(result)->aopu.aop_dir,
9766                                 AOP(result)->aopu.aop_dir);
9767                         else
9768                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9769                                 AOP(result)->aopu.aop_dir,
9770                                 AOP(result)->aopu.aop_dir);
9771                         
9772                         goto release;
9773                 }
9774                 
9775                 /* the right is also a bit variable */
9776                 if (AOP_TYPE(right) == AOP_CRY) {
9777                         
9778                         emitCLRC;
9779                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9780                         
9781                         pic14_emitcode("clrc","");
9782                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9783                                 AOP(right)->aopu.aop_dir,
9784                                 AOP(right)->aopu.aop_dir);
9785                         aopPut(AOP(result),"c",0);
9786                         goto release ;
9787                 }
9788                 
9789                 /* we need to or */
9790                 if (AOP_TYPE(right) == AOP_REG) {
9791                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9792                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9793                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9794                 }
9795                 pic14_toBoolean(right);
9796                 aopPut(AOP(result),"a",0);
9797                 goto release ;
9798         }
9799         
9800         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9801                 int offset = 1;
9802                 size = AOP_SIZE(result);
9803                 
9804                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9805                 
9806                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9807                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9808                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9809                 
9810                 while (size--)
9811                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9812                 
9813                 goto release;
9814         }
9815         
9816         /* if they are the same size : or less */
9817         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9818                 
9819                 /* if they are in the same place */
9820                 if (pic14_sameRegs(AOP(right),AOP(result)))
9821                         goto release;
9822                 
9823                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9824                 if (IS_PTR_CONST(rtype))
9825                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9826                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9827                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9828                 
9829                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9830                         emitpcode(POC_MOVLW, popGetAddr(AOP(right),0));
9831                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9832                         emitpcode(POC_MOVLW, popGetAddr(AOP(right),1));
9833                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9834                         if(AOP_SIZE(result) <2)
9835                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9836                         
9837                 } else {
9838                         
9839                         /* if they in different places then copy */
9840                         size = AOP_SIZE(result);
9841                         offset = 0 ;
9842                         while (size--) {
9843                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9844                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9845                                 
9846                                 //aopPut(AOP(result),
9847                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9848                                 // offset);
9849                                 
9850                                 offset++;
9851                         }
9852                 }
9853                 goto release;
9854         }
9855         
9856         
9857         /* if the result is of type pointer */
9858         if (IS_PTR(ctype)) {
9859                 
9860                 int p_type;
9861                 sym_link *type = operandType(right);
9862                 sym_link *etype = getSpec(type);
9863                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9864                 
9865                 /* pointer to generic pointer */
9866                 if (IS_GENPTR(ctype)) {
9867                         char *l = zero;
9868                         
9869                         if (IS_PTR(type)) 
9870                                 p_type = DCL_TYPE(type);
9871                         else {
9872                                 /* we have to go by the storage class */
9873                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9874                                 
9875                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9876                                 /*        p_type = CPOINTER ;  */
9877                                 /*    else */
9878                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9879                                 /*      p_type = FPOINTER ; */
9880                                 /*        else */
9881                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9882                                 /*          p_type = PPOINTER; */
9883                                 /*      else */
9884                                 /*          if (SPEC_OCLS(etype) == idata ) */
9885                                 /*        p_type = IPOINTER ; */
9886                                 /*          else */
9887                                 /*        p_type = POINTER ; */
9888                         }
9889                         
9890                         /* the first two bytes are known */
9891                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9892                         size = GPTRSIZE - 1; 
9893                         offset = 0 ;
9894                         while (size--) {
9895                                 if(offset < AOP_SIZE(right)) {
9896                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9897                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9898                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9899                                                 emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset));
9900                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9901                                         } else { 
9902                                                 aopPut(AOP(result),
9903                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9904                                                         offset);
9905                                         }
9906                                 } else 
9907                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9908                                 offset++;
9909                         }
9910                         /* the last byte depending on type */
9911                         switch (p_type) {
9912                         case IPOINTER:
9913                         case POINTER:
9914                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9915                                 break;
9916                         case FPOINTER:
9917                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9918                                 l = one;
9919                                 break;
9920                         case CPOINTER:
9921                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9922                                 l = "#0x02";
9923                                 break;        
9924                         case PPOINTER:
9925                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9926                                 l = "#0x03";
9927                                 break;
9928                                 
9929                         default:
9930                                 /* this should never happen */
9931                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9932                                         "got unknown pointer type");
9933                                 exit(1);
9934                         }
9935                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9936                         goto release ;
9937                 }
9938                 
9939                 /* just copy the pointers */
9940                 size = AOP_SIZE(result);
9941                 offset = 0 ;
9942                 while (size--) {
9943                         aopPut(AOP(result),
9944                                 aopGet(AOP(right),offset,FALSE,FALSE),
9945                                 offset);
9946                         offset++;
9947                 }
9948                 goto release ;
9949         }
9950         
9951         
9952         
9953         /* so we now know that the size of destination is greater
9954         than the size of the source.
9955         Now, if the next iCode is an operator then we might be
9956         able to optimize the operation without performing a cast.
9957         */
9958         if(genMixedOperation(ic))
9959                 goto release;
9960         
9961         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9962         
9963         /* we move to result for the size of source */
9964         size = AOP_SIZE(right);
9965         offset = 0 ;
9966         while (size--) {
9967                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9968                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9969                 offset++;
9970         }
9971         
9972         /* now depending on the sign of the destination */
9973         size = AOP_SIZE(result) - AOP_SIZE(right);
9974         /* if unsigned or not an integral type */
9975         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9976                 while (size--)
9977                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9978         } else {
9979                 /* we need to extend the sign :{ */
9980                 
9981                 if(size == 1) {
9982                         /* Save one instruction of casting char to int */
9983                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9984                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9985                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9986                 } else {
9987                         emitpcodeNULLop(POC_CLRW);
9988                         
9989                         if(offset)
9990                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9991                         else
9992                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9993                         
9994                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9995                         
9996                         while (size--)
9997                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9998                 }
9999         }
10000         
10001 release:
10002         freeAsmop(right,NULL,ic,TRUE);
10003         freeAsmop(result,NULL,ic,TRUE);
10004         
10005 }
10006
10007 /*-----------------------------------------------------------------*/
10008 /* genDjnz - generate decrement & jump if not zero instrucion      */
10009 /*-----------------------------------------------------------------*/
10010 static int genDjnz (iCode *ic, iCode *ifx)
10011 {
10012         symbol *lbl, *lbl1;
10013         FENTRY;
10014         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10015         
10016         if (!ifx)
10017                 return 0;
10018         
10019                 /* if the if condition has a false label
10020         then we cannot save */
10021         if (IC_FALSE(ifx))
10022                 return 0;
10023         
10024                 /* if the minus is not of the form 
10025         a = a - 1 */
10026         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10027                 !IS_OP_LITERAL(IC_RIGHT(ic)))
10028                 return 0;
10029         
10030         if (operandLitValue(IC_RIGHT(ic)) != 1)
10031                 return 0;
10032         
10033                 /* if the size of this greater than one then no
10034         saving */
10035         if (getSize(operandType(IC_RESULT(ic))) > 1)
10036                 return 0;
10037         
10038         /* otherwise we can save BIG */
10039         lbl = newiTempLabel(NULL);
10040         lbl1= newiTempLabel(NULL);
10041         
10042         aopOp(IC_RESULT(ic),ic,FALSE);
10043         
10044         if (IS_AOP_PREG(IC_RESULT(ic))) {
10045                 pic14_emitcode("dec","%s",
10046                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10047                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10048                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
10049         } else {  
10050                 
10051                 
10052                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
10053                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
10054                 
10055                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10056                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10057                 
10058         }
10059         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10060         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
10061         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10062         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
10063         
10064         
10065         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10066         ifx->generated = 1;
10067         return 1;
10068 }
10069
10070 /*-----------------------------------------------------------------*/
10071 /* genReceive - generate code for a receive iCode                  */
10072 /*-----------------------------------------------------------------*/
10073 static void genReceive (iCode *ic)
10074 {
10075         FENTRY;
10076         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
10077         
10078         if (isOperandInFarSpace(IC_RESULT(ic)) &&
10079                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10080                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10081                 
10082                 int size = getSize(operandType(IC_RESULT(ic)));
10083                 int offset =  fReturnSizePic - size;
10084                 while (size--) {
10085                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
10086                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
10087                         offset++;
10088                 }
10089                 aopOp(IC_RESULT(ic),ic,FALSE);
10090                 size = AOP_SIZE(IC_RESULT(ic));
10091                 offset = 0;
10092                 while (size--) {
10093                         pic14_emitcode ("pop","acc");
10094                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10095                 }
10096                 
10097         } else {
10098                 _G.accInUse++;
10099                 aopOp(IC_RESULT(ic),ic,FALSE);
10100                 _G.accInUse--;
10101                 assignResultValue(IC_RESULT(ic));
10102         }
10103         
10104         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10105 }
10106
10107 /*-----------------------------------------------------------------*/
10108 /* genDummyRead - generate code for dummy read of volatiles        */
10109 /*-----------------------------------------------------------------*/
10110 static void
10111 genDummyRead (iCode * ic)
10112 {
10113         FENTRY;
10114         pic14_emitcode ("; genDummyRead","");
10115         pic14_emitcode ("; not implemented","");
10116         
10117         ic = ic;
10118 }
10119
10120 /*-----------------------------------------------------------------*/
10121 /* genpic14Code - generate code for pic14 based controllers        */
10122 /*-----------------------------------------------------------------*/
10123 /*
10124 * At this point, ralloc.c has gone through the iCode and attempted
10125 * to optimize in a way suitable for a PIC. Now we've got to generate
10126 * PIC instructions that correspond to the iCode.
10127 *
10128 * Once the instructions are generated, we'll pass through both the
10129 * peep hole optimizer and the pCode optimizer.
10130 *-----------------------------------------------------------------*/
10131
10132 void genpic14Code (iCode *lic)
10133 {
10134         iCode *ic;
10135         int cln = 0;
10136         
10137         FENTRY;
10138         lineHead = lineCurr = NULL;
10139         
10140         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
10141         addpBlock(pb);
10142         
10143         /* if debug information required */
10144         if (options.debug && currFunc) { 
10145                 if (currFunc) {
10146                         debugFile->writeFunction (currFunc, lic);
10147                 }
10148         }
10149         
10150         
10151         for (ic = lic ; ic ; ic = ic->next ) {
10152                 
10153                 //DEBUGpic14_emitcode(";ic","");
10154                 //fprintf (stderr, "in ic loop\n");
10155                 //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
10156                 //ic->lineno, printCLine(ic->filename, ic->lineno));
10157                 
10158                 if (!options.noCcodeInAsm && (cln != ic->lineno)) {
10159                   cln = ic->lineno;
10160                   //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
10161                   emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln));
10162                 }
10163                 
10164                 if (options.iCodeInAsm) {
10165                   emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
10166                 }
10167                 /* if the result is marked as
10168                 spilt and rematerializable or code for
10169                 this has already been generated then
10170                 do nothing */
10171                 if (resultRemat(ic) || ic->generated ) 
10172                         continue ;
10173                 
10174                 /* depending on the operation */
10175                 switch (ic->op) {
10176                 case '!' :
10177                         genNot(ic);
10178                         break;
10179                         
10180                 case '~' :
10181                         genCpl(ic);
10182                         break;
10183                         
10184                 case UNARYMINUS:
10185                         genUminus (ic);
10186                         break;
10187                         
10188                 case IPUSH:
10189                         genIpush (ic);
10190                         break;
10191                         
10192                 case IPOP:
10193                         /* IPOP happens only when trying to restore a 
10194                         spilt live range, if there is an ifx statement
10195                         following this pop then the if statement might
10196                         be using some of the registers being popped which
10197                         would destory the contents of the register so
10198                         we need to check for this condition and handle it */
10199                         if (ic->next            && 
10200                                 ic->next->op == IFX &&
10201                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10202                                 genIfx (ic->next,ic);
10203                         else
10204                                 genIpop (ic);
10205                         break; 
10206                         
10207                 case CALL:
10208                         genCall (ic);
10209                         break;
10210                         
10211                 case PCALL:
10212                         genPcall (ic);
10213                         break;
10214                         
10215                 case FUNCTION:
10216                         genFunction (ic);
10217                         break;
10218                         
10219                 case ENDFUNCTION:
10220                         genEndFunction (ic);
10221                         break;
10222                         
10223                 case RETURN:
10224                         genRet (ic);
10225                         break;
10226                         
10227                 case LABEL:
10228                         genLabel (ic);
10229                         break;
10230                         
10231                 case GOTO:
10232                         genGoto (ic);
10233                         break;
10234                         
10235                 case '+' :
10236                         genPlus (ic) ;
10237                         break;
10238                         
10239                 case '-' :
10240                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10241                                 genMinus (ic);
10242                         break;
10243                         
10244                 case '*' :
10245                         genMult (ic);
10246                         break;
10247                         
10248                 case '/' :
10249                         genDiv (ic) ;
10250                         break;
10251                         
10252                 case '%' :
10253                         genMod (ic);
10254                         break;
10255                         
10256                 case '>' :
10257                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
10258                         break;
10259                         
10260                 case '<' :
10261                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10262                         break;
10263                         
10264                 case LE_OP:
10265                 case GE_OP:
10266                 case NE_OP:
10267                         
10268                         /* note these two are xlated by algebraic equivalence
10269                         during parsing SDCC.y */
10270                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10271                                 "got '>=' or '<=' shouldn't have come here");
10272                         break;  
10273                         
10274                 case EQ_OP:
10275                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10276                         break;      
10277                         
10278                 case AND_OP:
10279                         genAndOp (ic);
10280                         break;
10281                         
10282                 case OR_OP:
10283                         genOrOp (ic);
10284                         break;
10285                         
10286                 case '^' :
10287                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10288                         break;
10289                         
10290                 case '|' :
10291                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10292                         break;
10293                         
10294                 case BITWISEAND:
10295                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10296                         break;
10297                         
10298                 case INLINEASM:
10299                         genInline (ic);
10300                         break;
10301                         
10302                 case RRC:
10303                         genRRC (ic);
10304                         break;
10305                         
10306                 case RLC:
10307                         genRLC (ic);
10308                         break;
10309                         
10310                 case GETHBIT:
10311                         genGetHbit (ic);
10312                         break;
10313                         
10314                 case LEFT_OP:
10315                         genLeftShift (ic);
10316                         break;
10317                         
10318                 case RIGHT_OP:
10319                         genRightShift (ic);
10320                         break;
10321                         
10322                 case GET_VALUE_AT_ADDRESS:
10323                         genPointerGet(ic);
10324                         break;
10325                         
10326                 case '=' :
10327                         if (POINTER_SET(ic))
10328                                 genPointerSet(ic);
10329                         else
10330                                 genAssign(ic);
10331                         break;
10332                         
10333                 case IFX:
10334                         genIfx (ic,NULL);
10335                         break;
10336                         
10337                 case ADDRESS_OF:
10338                         genAddrOf (ic);
10339                         break;
10340                         
10341                 case JUMPTABLE:
10342                         genJumpTab (ic);
10343                         break;
10344                         
10345                 case CAST:
10346                         genCast (ic);
10347                         break;
10348                         
10349                 case RECEIVE:
10350                         genReceive(ic);
10351                         break;
10352                         
10353                 case SEND:
10354                         addSet(&_G.sendSet,ic);
10355                         break;
10356                         
10357                 case DUMMY_READ_VOLATILE:
10358                         genDummyRead (ic);
10359                         break;
10360                         
10361                 default :
10362                         ic = ic;
10363                 }
10364         }
10365
10366         
10367         /* now we are ready to call the
10368         peep hole optimizer */
10369         if (!options.nopeep) {
10370                 peepHole (&lineHead);
10371         }
10372         /* now do the actual printing */
10373         printLine (lineHead,codeOutFile);
10374         
10375 #ifdef PCODE_DEBUG
10376         DFPRINTF((stderr,"printing pBlock\n\n"));
10377         printpBlock(stdout,pb);
10378 #endif
10379         
10380         return;
10381 }