Lined up indentation.
[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
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
51
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
55
56 /* max_key keeps track of the largest label number used in 
57 a function. This is then used to adjust the label offset
58 for the next function.
59 */
60 static int max_key=0;
61 static int GpsuedoStkPtr=0;
62
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
67
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69
70 /* this is the down and dirty file with all kinds of 
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
74
75 static char *zero = "#0x00";
76 static char *one  = "#0x01";
77 static char *spname = "sp";
78
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
83
84 static char *accUse[] = {"a","b"};
85
86 //static short rbank = -1;
87
88 static struct {
89         short r0Pushed;
90         short r1Pushed;
91         short accInUse;
92         short inLine;
93         short debugLine;
94         short nRegsSaved;
95         set *sendSet;
96 } _G;
97
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
100 */
101 typedef struct resolvedIfx {
102         symbol *lbl;     /* pointer to a label */
103         int condition;   /* true or false ifx */
104         int generated;   /* set true when the code associated with the ifx
105                           * is generated */
106 } resolvedIfx;
107
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
112
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
115
116 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
120
121 static  pBlock *pb;
122
123 /*-----------------------------------------------------------------*/
124 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
125 /*                 exponent of 2 is returned, otherwise -1 is      */
126 /*                 returned.                                       */
127 /* note that this is similar to the function `powof2' in SDCCsymt  */
128 /* if(n == 2^y)                                                    */
129 /*   return y;                                                     */
130 /* return -1;                                                      */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
133 {
134         if(num) {
135                 if( (num & (num-1)) == 0) {
136                         int nshifts = -1;
137                         while(num) {
138                                 num>>=1;
139                                 nshifts++;
140                         }
141                         return nshifts;
142                 }
143         }
144         
145         return -1;
146 }
147
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 {
150         
151         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152                 line_no,
153                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
156                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
158                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159                 ((result) ? AOP_SIZE(result) : 0));
160         
161 }
162
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 {
165         
166         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167                 line_no,
168                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                 ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
172                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
174         
175 }
176
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 {
179         va_list ap;
180         char lb[INITIAL_INLINEASM];  
181         char *lbp = lb;
182         
183         if(!debug_verbose)
184                 return;
185         
186         va_start(ap,fmt);   
187         
188         if (inst && *inst) {
189                 if (fmt && *fmt)
190                         sprintf(lb,"%s\t",inst);
191                 else
192                         sprintf(lb,"%s",inst);
193                 vsprintf(lb+(strlen(lb)),fmt,ap);
194         }  else
195                 vsprintf(lb,fmt,ap);
196         
197         while (isspace(*lbp)) lbp++;
198         
199         if (lbp && *lbp) 
200                 lineCurr = (lineCurr ?
201                 connectLine(lineCurr,newLineNode(lb)) :
202         (lineHead = newLineNode(lb)));
203         lineCurr->isInline = _G.inLine;
204         lineCurr->isDebug  = _G.debugLine;
205         
206         addpCode2pBlock(pb,newpCodeCharP(lb));
207         
208         va_end(ap);
209 }
210
211
212 void emitpLabel(int key)
213 {
214         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 }
216
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 {
219         if(pcop)
220                 addpCode2pBlock(pb,newpCode(poc,pcop));
221         else
222                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
223 }
224
225 void emitpcodeNULLop(PIC_OPCODE poc)
226 {
227         
228         addpCode2pBlock(pb,newpCode(poc,NULL));
229         
230 }
231
232
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple    */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
237 {
238         va_list ap;
239         char lb[INITIAL_INLINEASM];  
240         char *lbp = lb;
241         
242         va_start(ap,fmt);   
243         
244         if (inst && *inst) {
245                 if (fmt && *fmt)
246                         sprintf(lb,"%s\t",inst);
247                 else
248                         sprintf(lb,"%s",inst);
249                 vsprintf(lb+(strlen(lb)),fmt,ap);
250         }  else
251                 vsprintf(lb,fmt,ap);
252         
253         while (isspace(*lbp)) lbp++;
254         
255         if (lbp && *lbp) 
256                 lineCurr = (lineCurr ?
257                 connectLine(lineCurr,newLineNode(lb)) :
258         (lineHead = newLineNode(lb)));
259         lineCurr->isInline = _G.inLine;
260         lineCurr->isDebug  = _G.debugLine;
261         
262         if(debug_verbose)
263                 addpCode2pBlock(pb,newpCodeCharP(lb));
264         
265         va_end(ap);
266 }
267
268
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
273 {
274         bool r0iu = FALSE , r1iu = FALSE;
275         bool r0ou = FALSE , r1ou = FALSE;
276         
277         /* the logic: if r0 & r1 used in the instruction
278         then we are in trouble otherwise */
279         
280         /* first check if r0 & r1 are used by this
281         instruction, in which case we are in trouble */
282         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
284         {
285                 goto endOfWorld;      
286         }
287         
288         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
290         
291         /* if no usage of r0 then return it */
292         if (!r0iu && !r0ou) {
293                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294                 (*aopp)->type = AOP_R0;
295                 
296                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
297         }
298         
299         /* if no usage of r1 then return it */
300         if (!r1iu && !r1ou) {
301                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302                 (*aopp)->type = AOP_R1;
303                 
304                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
305         }    
306         
307         /* now we know they both have usage */
308         /* if r0 not used in this instruction */
309         if (!r0iu) {
310                 /* push it if not already pushed */
311                 if (!_G.r0Pushed) {
312                         //pic14_emitcode ("push","%s",
313                         //          pic14_regWithIdx(R0_IDX)->dname);
314                         _G.r0Pushed++ ;
315                 }
316                 
317                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318                 (*aopp)->type = AOP_R0;
319                 
320                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
321         }
322         
323         /* if r1 not used then */
324         
325         if (!r1iu) {
326                 /* push it if not already pushed */
327                 if (!_G.r1Pushed) {
328                         //pic14_emitcode ("push","%s",
329                         //          pic14_regWithIdx(R1_IDX)->dname);
330                         _G.r1Pushed++ ;
331                 }
332                 
333                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334                 (*aopp)->type = AOP_R1;
335                 return pic14_regWithIdx(R1_IDX);
336         }
337         
338 endOfWorld :
339         /* I said end of world but not quite end of world yet */
340         /* if this is a result then we can push it on the stack*/
341         if (result) {
342                 (*aopp)->type = AOP_STK;    
343                 return NULL;
344         }
345         
346         /* other wise this is true end of the world */
347         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348                 "getFreePtr should never reach here");
349         exit(0);
350 }
351
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp                                  */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
356 {
357         asmop *aop;
358         
359         aop = Safe_calloc(1,sizeof(asmop));
360         aop->type = type;
361         return aop;
362 }
363
364 static void genSetDPTR(int n)
365 {
366         if (!n)
367         {
368                 pic14_emitcode(";", "Select standard DPTR");
369                 pic14_emitcode("mov", "dps, #0x00");
370         }
371         else
372         {
373                 pic14_emitcode(";", "Select alternate DPTR");
374                 pic14_emitcode("mov", "dps, #0x01");
375         }
376 }
377
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for  */
380 /*              generating code                                    */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 {
384         if(!resIfx) 
385                 return;
386         
387         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
388         
389         resIfx->condition = 1;    /* assume that the ifx is true */
390         resIfx->generated = 0;    /* indicate that the ifx has not been used */
391         
392         if(!ifx) {
393                 resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
394                                                                                         /*
395                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
397                 */
398         } else {
399                 if(IC_TRUE(ifx)) {
400                         resIfx->lbl = IC_TRUE(ifx);
401                 } else {
402                         resIfx->lbl = IC_FALSE(ifx);
403                         resIfx->condition = 0;
404                 }
405                 /*
406                 if(IC_TRUE(ifx)) 
407                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
408                 if(IC_FALSE(ifx)) 
409                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
410                 */
411         }
412         
413         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
414         
415 }
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type               */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
420 {
421         
422         return PTR_TYPE(SPEC_OCLS(etype));
423         
424 }
425
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol                                   */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
430 {
431         asmop *aop;
432         memmap *space= SPEC_OCLS(sym->etype);
433         
434         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435         /* if already has one */
436         if (sym->aop)
437                 return sym->aop;
438         
439         /* assign depending on the storage class */
440         /* if it is on the stack or indirectly addressable */
441         /* space we need to assign either r0 or r1 to it   */    
442         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443                 sym->aop = aop = newAsmop(0);
444                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445                 aop->size = getSize(sym->type);
446                 
447                 /* now assign the address of the variable to 
448                 the pointer register */
449                 if (aop->type != AOP_STK) {
450                         
451                         if (sym->onStack) {
452                                 if ( _G.accInUse )
453                                         pic14_emitcode("push","acc");
454                                 
455                                 pic14_emitcode("mov","a,_bp");
456                                 pic14_emitcode("add","a,#0x%02x",
457                                         ((sym->stack < 0) ?
458                                         ((char)(sym->stack - _G.nRegsSaved )) :
459                                 ((char)sym->stack)) & 0xff);
460                                 pic14_emitcode("mov","%s,a",
461                                         aop->aopu.aop_ptr->name);
462                                 
463                                 if ( _G.accInUse )
464                                         pic14_emitcode("pop","acc");
465                         } else
466                                 pic14_emitcode("mov","%s,#%s",
467                                 aop->aopu.aop_ptr->name,
468                                 sym->rname);
469                         aop->paged = space->paged;
470                 } else
471                         aop->aopu.aop_stk = sym->stack;
472                 return aop;
473         }
474         
475         if (sym->onStack && options.stack10bit)
476         {
477         /* It's on the 10 bit stack, which is located in
478         * far data space.
479                 */
480                 
481                 //DEBUGpic14_emitcode(";","%d",__LINE__);
482                 
483                 if ( _G.accInUse )
484                         pic14_emitcode("push","acc");
485                 
486                 pic14_emitcode("mov","a,_bp");
487                 pic14_emitcode("add","a,#0x%02x",
488                         ((sym->stack < 0) ?
489                         ((char)(sym->stack - _G.nRegsSaved )) :
490                 ((char)sym->stack)) & 0xff);
491                 
492                 genSetDPTR(1);
493                 pic14_emitcode ("mov","dpx1,#0x40");
494                 pic14_emitcode ("mov","dph1,#0x00");
495                 pic14_emitcode ("mov","dpl1, a");
496                 genSetDPTR(0);
497                 
498                 if ( _G.accInUse )
499                         pic14_emitcode("pop","acc");
500                 
501                 sym->aop = aop = newAsmop(AOP_DPTR2);
502                 aop->size = getSize(sym->type); 
503                 return aop;
504         }
505         
506         //DEBUGpic14_emitcode(";","%d",__LINE__);
507         /* if in bit space */
508         if (IN_BITSPACE(space)) {
509                 sym->aop = aop = newAsmop (AOP_CRY);
510                 aop->aopu.aop_dir = sym->rname ;
511                 aop->size = getSize(sym->type);
512                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
513                 return aop;
514         }
515         /* if it is in direct space */
516         if (IN_DIRSPACE(space)) {
517                 sym->aop = aop = newAsmop (AOP_DIR);
518                 aop->aopu.aop_dir = sym->rname ;
519                 aop->size = getSize(sym->type);
520                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
521                 return aop;
522         }
523         
524         /* special case for a function */
525         if (IS_FUNC(sym->type)) {   
526                 
527                 sym->aop = aop = newAsmop(AOP_PCODE);
528                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
529                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
530                 PCOI(aop->aopu.pcop)->_function = 1;
531                 PCOI(aop->aopu.pcop)->index = 0;
532                 aop->size = FPTRSIZE; 
533                 /*
534                 sym->aop = aop = newAsmop(AOP_IMMD);    
535                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536                 strcpy(aop->aopu.aop_immd,sym->rname);
537                 aop->size = FPTRSIZE; 
538                 */
539                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
540                 return aop;
541         }
542         
543         
544         /* only remaining is far space */
545         /* in which case DPTR gets the address */
546         sym->aop = aop = newAsmop(AOP_PCODE);
547         
548         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
549         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
550         PCOI(aop->aopu.pcop)->index = 0;
551         
552         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
553                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
554         
555         allocDirReg (IC_LEFT(ic));
556         
557         aop->size = FPTRSIZE; 
558         /*
559         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
560         sym->aop = aop = newAsmop(AOP_DPTR);
561         pic14_emitcode ("mov","dptr,#%s", sym->rname);
562         aop->size = getSize(sym->type);
563         
564           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
565         */
566         
567         /* if it is in code space */
568         if (IN_CODESPACE(space))
569                 aop->code = 1;
570         
571         return aop;     
572 }
573
574 /*-----------------------------------------------------------------*/
575 /* aopForRemat - rematerialzes an object                           */
576 /*-----------------------------------------------------------------*/
577 static asmop *aopForRemat (operand *op) // x symbol *sym)
578 {
579         symbol *sym = OP_SYMBOL(op);
580         iCode *ic = NULL;
581         asmop *aop = newAsmop(AOP_PCODE);
582         int val = 0;
583         int offset = 0;
584         
585         ic = sym->rematiCode;
586         
587         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
588         if(IS_OP_POINTER(op)) {
589                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
590         }
591         for (;;) {
592                 if (ic->op == '+') {
593                         val += (int) operandLitValue(IC_RIGHT(ic));
594                 } else if (ic->op == '-') {
595                         val -= (int) operandLitValue(IC_RIGHT(ic));
596                 } else
597                         break;
598                 
599                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
600         }
601         
602         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
603         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
604         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
605         PCOI(aop->aopu.pcop)->index = val;
606         
607         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
608                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
609                 val, IS_PTR_CONST(operandType(op)));
610         
611         //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
612         
613         allocDirReg (IC_LEFT(ic));
614         
615         return aop;        
616 }
617
618 int aopIdx (asmop *aop, int offset)
619 {
620         if(!aop)
621                 return -1;
622         
623         if(aop->type !=  AOP_REG)
624                 return -2;
625         
626         return aop->aopu.aop_reg[offset]->rIdx;
627         
628 }
629 /*-----------------------------------------------------------------*/
630 /* regsInCommon - two operands have some registers in common       */
631 /*-----------------------------------------------------------------*/
632 static bool regsInCommon (operand *op1, operand *op2)
633 {
634         symbol *sym1, *sym2;
635         int i;
636         
637         /* if they have registers in common */
638         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
639                 return FALSE ;
640         
641         sym1 = OP_SYMBOL(op1);
642         sym2 = OP_SYMBOL(op2);
643         
644         if (sym1->nRegs == 0 || sym2->nRegs == 0)
645                 return FALSE ;
646         
647         for (i = 0 ; i < sym1->nRegs ; i++) {
648                 int j;
649                 if (!sym1->regs[i])
650                         continue ;
651                 
652                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
653                         if (!sym2->regs[j])
654                                 continue ;
655                         
656                         if (sym2->regs[j] == sym1->regs[i])
657                                 return TRUE ;
658                 }
659         }
660         
661         return FALSE ;
662 }
663
664 /*-----------------------------------------------------------------*/
665 /* operandsEqu - equivalent                                        */
666 /*-----------------------------------------------------------------*/
667 static bool operandsEqu ( operand *op1, operand *op2)
668 {
669         symbol *sym1, *sym2;
670         
671         /* if they not symbols */
672         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
673                 return FALSE;
674         
675         sym1 = OP_SYMBOL(op1);
676         sym2 = OP_SYMBOL(op2);
677         
678         /* if both are itemps & one is spilt
679         and the other is not then false */
680         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
681                 sym1->isspilt != sym2->isspilt )
682                 return FALSE ;
683         
684         /* if they are the same */
685         if (sym1 == sym2)
686                 return TRUE ;
687         
688         if (strcmp(sym1->rname,sym2->rname) == 0)
689                 return TRUE;
690         
691         
692         /* if left is a tmp & right is not */
693         if (IS_ITEMP(op1)  && 
694                 !IS_ITEMP(op2) &&
695                 sym1->isspilt  &&
696                 (sym1->usl.spillLoc == sym2))
697                 return TRUE;
698         
699         if (IS_ITEMP(op2)  && 
700                 !IS_ITEMP(op1) &&
701                 sym2->isspilt  &&
702                 sym1->level > 0 &&
703                 (sym2->usl.spillLoc == sym1))
704                 return TRUE ;
705         
706         return FALSE ;
707 }
708
709 /*-----------------------------------------------------------------*/
710 /* pic14_sameRegs - two asmops have the same registers                   */
711 /*-----------------------------------------------------------------*/
712 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
713 {
714         int i;
715         
716         if (aop1 == aop2)
717                 return TRUE ;
718         
719         if (aop1->type != AOP_REG ||
720                 aop2->type != AOP_REG )
721                 return FALSE ;
722         
723         if (aop1->size != aop2->size )
724                 return FALSE ;
725         
726         for (i = 0 ; i < aop1->size ; i++ )
727                 if (aop1->aopu.aop_reg[i] !=
728                         aop2->aopu.aop_reg[i] )
729                         return FALSE ;
730                 
731                 return TRUE ;
732 }
733
734 /*-----------------------------------------------------------------*/
735 /* aopOp - allocates an asmop for an operand  :                    */
736 /*-----------------------------------------------------------------*/
737 void aopOp (operand *op, iCode *ic, bool result)
738 {
739         asmop *aop;
740         symbol *sym;
741         int i;
742         
743         if (!op)
744                 return ;
745         
746         //    DEBUGpic14_emitcode(";","%d",__LINE__);
747         /* if this a literal */
748         if (IS_OP_LITERAL(op)) {
749                 op->aop = aop = newAsmop(AOP_LIT);
750                 aop->aopu.aop_lit = op->operand.valOperand;
751                 aop->size = getSize(operandType(op));
752                 return;
753         }
754         
755         {
756                 sym_link *type = operandType(op);
757                 if(IS_PTR_CONST(type))
758                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
759         }
760         
761         /* if already has a asmop then continue */
762         if (op->aop)
763                 return ;
764         
765         /* if the underlying symbol has a aop */
766         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
767                 DEBUGpic14_emitcode(";","%d",__LINE__);
768                 op->aop = OP_SYMBOL(op)->aop;
769                 return;
770         }
771         
772         /* if this is a true symbol */
773         if (IS_TRUE_SYMOP(op)) {    
774                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
775                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
776                 return ;
777         }
778         
779         /* this is a temporary : this has
780         only four choices :
781         a) register
782         b) spillocation
783         c) rematerialize 
784         d) conditional   
785         e) can be a return use only */
786         
787         sym = OP_SYMBOL(op);
788         
789         
790         /* if the type is a conditional */
791         if (sym->regType == REG_CND) {
792                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
793                 aop->size = 0;
794                 return;
795         }
796         
797         /* if it is spilt then two situations
798         a) is rematerialize 
799         b) has a spill location */
800         if (sym->isspilt || sym->nRegs == 0) {
801                 
802                 DEBUGpic14_emitcode(";","%d",__LINE__);
803                 /* rematerialize it NOW */
804                 if (sym->remat) {
805                         
806                         sym->aop = op->aop = aop =
807                                 aopForRemat (op);
808                         aop->size = getSize(sym->type);
809                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
810                         return;
811                 }
812                 
813                 if (sym->accuse) {
814                         int i;
815                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
816                         aop->size = getSize(sym->type);
817                         for ( i = 0 ; i < 2 ; i++ )
818                                 aop->aopu.aop_str[i] = accUse[i];
819                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
820                         return;  
821                 }
822                 
823                 if (sym->ruonly ) {
824                         if(sym->isptr) {  // && sym->uptr 
825                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
826                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
827                                 
828                                 //PCOI(aop->aopu.pcop)->_const = 0;
829                                 //PCOI(aop->aopu.pcop)->index = 0;
830                                 /*
831                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
832                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
833                                 */
834                                 //allocDirReg (IC_LEFT(ic));
835                                 
836                                 aop->size = getSize(sym->type);
837                                 DEBUGpic14_emitcode(";","%d",__LINE__);
838                                 return;
839                                 
840                         } else {
841                                 
842                                 unsigned i;
843                                 
844                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
845                                 aop->size = getSize(sym->type);
846                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
847                                         aop->aopu.aop_str[i] = fReturn[i];
848                                 
849                                 DEBUGpic14_emitcode(";","%d",__LINE__);
850                                 return;
851                         }
852                 }
853                 
854                 /* else spill location  */
855                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
856                         /* force a new aop if sizes differ */
857                         sym->usl.spillLoc->aop = NULL;
858                 }
859                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
860                         __FUNCTION__,__LINE__,
861                         sym->usl.spillLoc->rname,
862                         sym->rname, sym->usl.spillLoc->offset);
863                 
864                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
865                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
866                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
867                         getSize(sym->type), 
868                         sym->usl.spillLoc->offset);
869                 aop->size = getSize(sym->type);
870                 
871                 return;
872         }
873         
874         {
875                 sym_link *type = operandType(op);
876                 if(IS_PTR_CONST(type)) 
877                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
878         }
879         
880         /* must be in a register */
881         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
882         sym->aop = op->aop = aop = newAsmop(AOP_REG);
883         aop->size = sym->nRegs;
884         for ( i = 0 ; i < sym->nRegs ;i++)
885                 aop->aopu.aop_reg[i] = sym->regs[i];
886 }
887
888 /*-----------------------------------------------------------------*/
889 /* freeAsmop - free up the asmop given to an operand               */
890 /*----------------------------------------------------------------*/
891 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
892 {   
893         asmop *aop ;
894         
895         if (!op)
896                 aop = aaop;
897         else 
898                 aop = op->aop;
899         
900         if (!aop)
901                 return ;
902         
903         if (aop->freed)
904                 goto dealloc; 
905         
906         aop->freed = 1;
907         
908         /* depending on the asmop type only three cases need work AOP_RO
909         , AOP_R1 && AOP_STK */
910 #if 0
911         switch (aop->type) {
912         case AOP_R0 :
913                 if (_G.r0Pushed ) {
914                         if (pop) {
915                                 pic14_emitcode ("pop","ar0");     
916                                 _G.r0Pushed--;
917                         }
918                 }
919                 bitVectUnSetBit(ic->rUsed,R0_IDX);
920                 break;
921                 
922         case AOP_R1 :
923                 if (_G.r1Pushed ) {
924                         if (pop) {
925                                 pic14_emitcode ("pop","ar1");
926                                 _G.r1Pushed--;
927                         }
928                 }
929                 bitVectUnSetBit(ic->rUsed,R1_IDX);          
930                 break;
931                 
932         case AOP_STK :
933                 {
934                         int sz = aop->size;    
935                         int stk = aop->aopu.aop_stk + aop->size;
936                         bitVectUnSetBit(ic->rUsed,R0_IDX);
937                         bitVectUnSetBit(ic->rUsed,R1_IDX);          
938                         
939                         getFreePtr(ic,&aop,FALSE);
940                         
941                         if (options.stack10bit)
942                         {
943                                 /* I'm not sure what to do here yet... */
944                                 /* #STUB */
945                                 fprintf(stderr, 
946                                         "*** Warning: probably generating bad code for "
947                                         "10 bit stack mode.\n");
948                         }
949                         
950                         if (stk) {
951                                 pic14_emitcode ("mov","a,_bp");
952                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
953                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
954                         } else {
955                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
956                         }
957                         
958                         while (sz--) {
959                                 pic14_emitcode("pop","acc");
960                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
961                                 if (!sz) break;
962                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
963                         }
964                         op->aop = aop;
965                         freeAsmop(op,NULL,ic,TRUE);
966                         if (_G.r0Pushed) {
967                                 pic14_emitcode("pop","ar0");
968                                 _G.r0Pushed--;
969                         }
970                         
971                         if (_G.r1Pushed) {
972                                 pic14_emitcode("pop","ar1");
973                                 _G.r1Pushed--;
974                         }       
975                 }
976         }
977 #endif
978         
979 dealloc:
980         /* all other cases just dealloc */
981         if (op ) {
982                 op->aop = NULL;
983                 if (IS_SYMOP(op)) {
984                         OP_SYMBOL(op)->aop = NULL;    
985                         /* if the symbol has a spill */
986                         if (SPIL_LOC(op))
987                                 SPIL_LOC(op)->aop = NULL;
988                 }
989         }
990 }
991
992 /*-----------------------------------------------------------------*/
993 /* aopGet - for fetching value of the aop                          */
994 /*-----------------------------------------------------------------*/
995 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
996 {
997         char *s = buffer ;
998         char *rs;
999         
1000         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1001         /* offset is greater than
1002         size then zero */
1003         if (offset > (aop->size - 1) &&
1004                 aop->type != AOP_LIT)
1005                 return zero;
1006         
1007         /* depending on type */
1008         switch (aop->type) {
1009                 
1010         case AOP_R0:
1011         case AOP_R1:
1012                 DEBUGpic14_emitcode(";","%d",__LINE__);
1013                 /* if we need to increment it */       
1014                 while (offset > aop->coff) {        
1015                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1016                         aop->coff++;
1017                 }
1018                 
1019                 while (offset < aop->coff) {
1020                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1021                         aop->coff--;
1022                 }
1023                 
1024                 aop->coff = offset ;
1025                 if (aop->paged) {
1026                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1027                         return (dname ? "acc" : "a");
1028                 }       
1029                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1030                 rs = Safe_calloc(1,strlen(s)+1);
1031                 strcpy(rs,s);   
1032                 return rs;
1033                 
1034         case AOP_DPTR:
1035         case AOP_DPTR2:
1036                 DEBUGpic14_emitcode(";","%d",__LINE__);
1037                 if (aop->type == AOP_DPTR2)
1038                 {
1039                         genSetDPTR(1);
1040                 }
1041                 
1042                 while (offset > aop->coff) {
1043                         pic14_emitcode ("inc","dptr");
1044                         aop->coff++;
1045                 }
1046                 
1047                 while (offset < aop->coff) {        
1048                         pic14_emitcode("lcall","__decdptr");
1049                         aop->coff--;
1050                 }
1051                 
1052                 aop->coff = offset;
1053                 if (aop->code) {
1054                         pic14_emitcode("clr","a");
1055                         pic14_emitcode("movc","a,@a+dptr");
1056                 }
1057                 else {
1058                         pic14_emitcode("movx","a,@dptr");
1059                 }
1060                 
1061                 if (aop->type == AOP_DPTR2)
1062                 {
1063                         genSetDPTR(0);
1064                 }
1065                 
1066                 return (dname ? "acc" : "a");
1067                 
1068                 
1069         case AOP_IMMD:
1070                 if (bit16) 
1071                         sprintf (s,"%s",aop->aopu.aop_immd);
1072                 else
1073                         if (offset) 
1074                                 sprintf(s,"(%s >> %d)",
1075                                 aop->aopu.aop_immd,
1076                                 offset*8);
1077                         else
1078                                 sprintf(s,"%s",
1079                                 aop->aopu.aop_immd);
1080                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1081                         rs = Safe_calloc(1,strlen(s)+1);
1082                         strcpy(rs,s);   
1083                         return rs;
1084                         
1085         case AOP_DIR:
1086                 if (offset) {
1087                         sprintf(s,"(%s + %d)",
1088                                 aop->aopu.aop_dir,
1089                                 offset);
1090                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1091                 } else
1092                         sprintf(s,"%s",aop->aopu.aop_dir);
1093                 rs = Safe_calloc(1,strlen(s)+1);
1094                 strcpy(rs,s);   
1095                 return rs;
1096                 
1097         case AOP_REG:
1098                 //if (dname) 
1099                 //    return aop->aopu.aop_reg[offset]->dname;
1100                 //else
1101                 return aop->aopu.aop_reg[offset]->name;
1102                 
1103         case AOP_CRY:
1104                 //pic14_emitcode(";","%d",__LINE__);
1105                 return aop->aopu.aop_dir;
1106                 
1107         case AOP_ACC:
1108                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1109                 return "AOP_accumulator_bug";
1110                 
1111         case AOP_LIT:
1112                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1113                 rs = Safe_calloc(1,strlen(s)+1);
1114                 strcpy(rs,s);   
1115                 return rs;
1116                 
1117         case AOP_STR:
1118                 aop->coff = offset ;
1119                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1120                         dname)
1121                         return "acc";
1122                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1123                 
1124                 return aop->aopu.aop_str[offset];
1125                 
1126         case AOP_PCODE:
1127                 {
1128                         pCodeOp *pcop = aop->aopu.pcop;
1129                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1130                         if(pcop->name) {
1131                                 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1132                                 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1133                                 sprintf(s,"%s", pcop->name);
1134                         } else
1135                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1136                         
1137                 }
1138                 rs = Safe_calloc(1,strlen(s)+1);
1139                 strcpy(rs,s);   
1140                 return rs;
1141                 
1142         }
1143         
1144         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1145                 "aopget got unsupported aop->type");
1146         exit(0);
1147 }
1148
1149
1150 /*-----------------------------------------------------------------*/
1151 /* popGetTempReg - create a new temporary pCodeOp                  */
1152 /*-----------------------------------------------------------------*/
1153 pCodeOp *popGetTempReg(void)
1154 {
1155         
1156         pCodeOp *pcop;
1157         
1158         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1159         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1160                 PCOR(pcop)->r->wasUsed=1;
1161                 PCOR(pcop)->r->isFree=0;
1162         }
1163         
1164         return pcop;
1165 }
1166
1167 /*-----------------------------------------------------------------*/
1168 /* popGetTempReg - create a new temporary pCodeOp                  */
1169 /*-----------------------------------------------------------------*/
1170 void popReleaseTempReg(pCodeOp *pcop)
1171 {
1172         
1173         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1174                 PCOR(pcop)->r->isFree = 1;
1175         
1176 }
1177 /*-----------------------------------------------------------------*/
1178 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1179 /*-----------------------------------------------------------------*/
1180 pCodeOp *popGetLabel(unsigned int key)
1181 {
1182         
1183         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1184         
1185         if(key>(unsigned int)max_key)
1186                 max_key = key;
1187         
1188         return newpCodeOpLabel(NULL,key+100+labelOffset);
1189 }
1190
1191 /*-------------------------------------------------------------------*/
1192 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1193 /*-------------------------------------------------------------------*/
1194 pCodeOp *popGetHighLabel(unsigned int key)
1195 {
1196         pCodeOp *pcop;
1197         pcop = popGetLabel(key);
1198         PCOLAB(pcop)->offset = 1;
1199         return pcop;
1200 }
1201
1202 /*-----------------------------------------------------------------*/
1203 /* popGet - asm operator to pcode operator conversion              */
1204 /*-----------------------------------------------------------------*/
1205 pCodeOp *popGetLit(unsigned int lit)
1206 {
1207         
1208         return newpCodeOpLit(lit);
1209 }
1210
1211
1212 /*-----------------------------------------------------------------*/
1213 /* popGetImmd - asm operator to pcode immediate conversion         */
1214 /*-----------------------------------------------------------------*/
1215 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1216 {
1217         
1218         return newpCodeOpImmd(name, offset,index, 0, is_func);
1219 }
1220
1221
1222 /*-----------------------------------------------------------------*/
1223 /* popGet - asm operator to pcode operator conversion              */
1224 /*-----------------------------------------------------------------*/
1225 pCodeOp *popGetWithString(char *str, int isExtern)
1226 {
1227         pCodeOp *pcop;
1228         
1229         
1230         if(!str) {
1231                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1232                 exit (1);
1233         }
1234         
1235         pcop = newpCodeOp(str,PO_STR);
1236         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1237         
1238         return pcop;
1239 }
1240
1241 /*-----------------------------------------------------------------*/
1242 /* popRegFromString -                                              */
1243 /*-----------------------------------------------------------------*/
1244 pCodeOp *popRegFromString(char *str, int size, int offset)
1245 {
1246         
1247         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1248         pcop->type = PO_DIR;
1249         
1250         DEBUGpic14_emitcode(";","%d",__LINE__);
1251         
1252         if(!str)
1253                 str = "BAD_STRING";
1254         
1255         pcop->name = Safe_calloc(1,strlen(str)+1);
1256         strcpy(pcop->name,str);
1257         
1258         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1259         
1260         PCOR(pcop)->r = dirregWithName(pcop->name);
1261         if(PCOR(pcop)->r == NULL) {
1262                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1263                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1264                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1265         } else {
1266                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1267         }
1268         PCOR(pcop)->instance = offset;
1269         
1270         return pcop;
1271 }
1272
1273 /*-----------------------------------------------------------------*/
1274 /*-----------------------------------------------------------------*/
1275 pCodeOp *popRegFromIdx(int rIdx)
1276 {
1277         pCodeOp *pcop;
1278         
1279         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1280                 __FUNCTION__,__LINE__,rIdx);
1281         
1282         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1283         
1284         PCOR(pcop)->rIdx = rIdx;
1285         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1286         PCOR(pcop)->r->isFree = 0;
1287         PCOR(pcop)->r->wasUsed = 1;
1288         
1289         pcop->type = PCOR(pcop)->r->pc_type;
1290         
1291         
1292         return pcop;
1293 }
1294
1295 /*-----------------------------------------------------------------*/
1296 /* popGet - asm operator to pcode operator conversion              */
1297 /*-----------------------------------------------------------------*/
1298 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1299 {
1300         //char *s = buffer ;
1301         //char *rs;
1302         
1303         pCodeOp *pcop;
1304         
1305         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1306         /* offset is greater than
1307         size then zero */
1308         
1309         if (offset > (aop->size - 1) &&
1310                 aop->type != AOP_LIT)
1311                 return NULL;  //zero;
1312         
1313         /* depending on type */
1314         switch (aop->type) {
1315                 
1316         case AOP_R0:
1317         case AOP_R1:
1318         case AOP_DPTR:
1319         case AOP_DPTR2:
1320         case AOP_ACC:
1321                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1322                 return NULL;
1323                 
1324         case AOP_IMMD:
1325                 DEBUGpic14_emitcode(";","%d",__LINE__);
1326                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1327                 
1328         case AOP_DIR:
1329                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1330 #if 0
1331                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1332                 pcop->type = PO_DIR;
1333                 
1334                 /*
1335                 if (offset)
1336                 sprintf(s,"(%s + %d)",
1337                 aop->aopu.aop_dir,
1338                 offset);
1339                 else
1340                 sprintf(s,"%s",aop->aopu.aop_dir);
1341                 pcop->name = Safe_calloc(1,strlen(s)+1);
1342                 strcpy(pcop->name,s);   
1343                 */
1344                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1345                 strcpy(pcop->name,aop->aopu.aop_dir);   
1346                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1347                 if(PCOR(pcop)->r == NULL) {
1348                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1349                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1350                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1351                 } else {
1352                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1353                 }
1354                 PCOR(pcop)->instance = offset;
1355                 
1356                 return pcop;
1357 #endif
1358                 
1359         case AOP_REG:
1360                 {
1361                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1362                         
1363                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1364                         PCOR(pcop)->rIdx = rIdx;
1365                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1366                         PCOR(pcop)->r->wasUsed=1;
1367                         PCOR(pcop)->r->isFree=0;
1368                         
1369                         PCOR(pcop)->instance = offset;
1370                         pcop->type = PCOR(pcop)->r->pc_type;
1371                         //rs = aop->aopu.aop_reg[offset]->name;
1372                         DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1373                         return pcop;
1374                 }
1375                 
1376         case AOP_CRY:
1377                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1378                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1379                 //if(PCOR(pcop)->r == NULL)
1380                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1381                 return pcop;
1382                 
1383         case AOP_LIT:
1384                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1385                 
1386         case AOP_STR:
1387                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1388                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1389                 /*
1390                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1391                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1392                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1393                 pcop->type = PCOR(pcop)->r->pc_type;
1394                 pcop->name = PCOR(pcop)->r->name;
1395                 
1396                   return pcop;
1397                 */
1398                 
1399         case AOP_PCODE:
1400                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1401                         __LINE__, 
1402                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1403                 pcop = pCodeOpCopy(aop->aopu.pcop);
1404                 PCOI(pcop)->offset = offset;
1405                 return pcop;
1406         }
1407         
1408         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1409                 "popGet got unsupported aop->type");
1410         exit(0);
1411 }
1412 /*-----------------------------------------------------------------*/
1413 /* aopPut - puts a string for a aop                                */
1414 /*-----------------------------------------------------------------*/
1415 void aopPut (asmop *aop, char *s, int offset)
1416 {
1417         char *d = buffer ;
1418         symbol *lbl ;
1419         
1420         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1421         
1422         if (aop->size && offset > ( aop->size - 1)) {
1423                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1424                         "aopPut got offset > aop->size");
1425                 exit(0);
1426         }
1427         
1428         /* will assign value to value */
1429         /* depending on where it is ofcourse */
1430         switch (aop->type) {
1431         case AOP_DIR:
1432                 if (offset) {
1433                         sprintf(d,"(%s + %d)",
1434                                 aop->aopu.aop_dir,offset);
1435                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1436                         
1437                 } else
1438                         sprintf(d,"%s",aop->aopu.aop_dir);
1439                 
1440                 if (strcmp(d,s)) {
1441                         DEBUGpic14_emitcode(";","%d",__LINE__);
1442                         if(strcmp(s,"W"))
1443                                 pic14_emitcode("movf","%s,w",s);
1444                         pic14_emitcode("movwf","%s",d);
1445                         
1446                         if(strcmp(s,"W")) {
1447                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1448                                 if(offset >= aop->size) {
1449                                         emitpcode(POC_CLRF,popGet(aop,offset));
1450                                         break;
1451                                 } else
1452                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1453                         }
1454                         
1455                         emitpcode(POC_MOVWF,popGet(aop,offset));
1456                         
1457                         
1458                 }
1459                 break;
1460                 
1461         case AOP_REG:
1462                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1463                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1464                         /*
1465                         if (*s == '@'           ||
1466                         strcmp(s,"r0") == 0 ||
1467                         strcmp(s,"r1") == 0 ||
1468                         strcmp(s,"r2") == 0 ||
1469                         strcmp(s,"r3") == 0 ||
1470                         strcmp(s,"r4") == 0 ||
1471                         strcmp(s,"r5") == 0 ||
1472                         strcmp(s,"r6") == 0 || 
1473                         strcmp(s,"r7") == 0 )
1474                         pic14_emitcode("mov","%s,%s  ; %d",
1475                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1476                         else
1477                         */
1478                         
1479                         if(strcmp(s,"W")==0 )
1480                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1481                         
1482                         pic14_emitcode("movwf","%s",
1483                                 aop->aopu.aop_reg[offset]->name);
1484                         
1485                         if(strcmp(s,zero)==0) {
1486                                 emitpcode(POC_CLRF,popGet(aop,offset));
1487                                 
1488                         } else if(strcmp(s,"W")==0) {
1489                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1490                                 pcop->type = PO_GPR_REGISTER;
1491                                 
1492                                 PCOR(pcop)->rIdx = -1;
1493                                 PCOR(pcop)->r = NULL;
1494                                 
1495                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1496                                 pcop->name = Safe_strdup(s);
1497                                 emitpcode(POC_MOVFW,pcop);
1498                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1499                         } else if(strcmp(s,one)==0) {
1500                                 emitpcode(POC_CLRF,popGet(aop,offset));
1501                                 emitpcode(POC_INCF,popGet(aop,offset));
1502                         } else {
1503                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1504                         }
1505                 }
1506                 break;
1507                 
1508         case AOP_DPTR:
1509         case AOP_DPTR2:
1510                 
1511                 if (aop->type == AOP_DPTR2)
1512                 {
1513                         genSetDPTR(1);
1514                 }
1515                 
1516                 if (aop->code) {
1517                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1518                                 "aopPut writting to code space");
1519                         exit(0);
1520                 }
1521                 
1522                 while (offset > aop->coff) {
1523                         aop->coff++;
1524                         pic14_emitcode ("inc","dptr");
1525                 }
1526                 
1527                 while (offset < aop->coff) {
1528                         aop->coff-- ;
1529                         pic14_emitcode("lcall","__decdptr");
1530                 }
1531                 
1532                 aop->coff = offset;
1533                 
1534                 /* if not in accumulater */
1535                 MOVA(s);
1536                 
1537                 pic14_emitcode ("movx","@dptr,a");
1538                 
1539                 if (aop->type == AOP_DPTR2)
1540                 {
1541                         genSetDPTR(0);
1542                 }
1543                 break;
1544                 
1545         case AOP_R0:
1546         case AOP_R1:
1547                 while (offset > aop->coff) {
1548                         aop->coff++;
1549                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1550                 }
1551                 while (offset < aop->coff) {
1552                         aop->coff-- ;
1553                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1554                 }
1555                 aop->coff = offset;
1556                 
1557                 if (aop->paged) {
1558                         MOVA(s);           
1559                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1560                         
1561                 } else
1562                         if (*s == '@') {
1563                                 MOVA(s);
1564                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1565                         } else
1566                                 if (strcmp(s,"r0") == 0 ||
1567                                         strcmp(s,"r1") == 0 ||
1568                                         strcmp(s,"r2") == 0 ||
1569                                         strcmp(s,"r3") == 0 ||
1570                                         strcmp(s,"r4") == 0 ||
1571                                         strcmp(s,"r5") == 0 ||
1572                                         strcmp(s,"r6") == 0 || 
1573                                         strcmp(s,"r7") == 0 ) {
1574                                         char buffer[10];
1575                                         sprintf(buffer,"a%s",s);
1576                                         pic14_emitcode("mov","@%s,%s",
1577                                                 aop->aopu.aop_ptr->name,buffer);
1578                                 } else
1579                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1580                                 
1581                                 break;
1582                                 
1583         case AOP_STK:
1584                 if (strcmp(s,"a") == 0)
1585                         pic14_emitcode("push","acc");
1586                 else
1587                         pic14_emitcode("push","%s",s);
1588                 
1589                 break;
1590                 
1591         case AOP_CRY:
1592                 /* if bit variable */
1593                 if (!aop->aopu.aop_dir) {
1594                         pic14_emitcode("clr","a");
1595                         pic14_emitcode("rlc","a");
1596                 } else {
1597                         if (s == zero) 
1598                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1599                         else
1600                                 if (s == one)
1601                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1602                                 else
1603                                         if (!strcmp(s,"c"))
1604                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1605                                         else {
1606                                                 lbl = newiTempLabel(NULL);
1607                                                 
1608                                                 if (strcmp(s,"a")) {
1609                                                         MOVA(s);
1610                                                 }
1611                                                 pic14_emitcode("clr","c");
1612                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1613                                                 pic14_emitcode("cpl","c");
1614                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1615                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1616                                         }
1617                 }
1618                 break;
1619                 
1620         case AOP_STR:
1621                 aop->coff = offset;
1622                 if (strcmp(aop->aopu.aop_str[offset],s))
1623                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1624                 break;
1625                 
1626         case AOP_ACC:
1627                 aop->coff = offset;
1628                 if (!offset && (strcmp(s,"acc") == 0))
1629                         break;
1630                 
1631                 if (strcmp(aop->aopu.aop_str[offset],s))
1632                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1633                 break;
1634                 
1635         default :
1636                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1637                         "aopPut got unsupported aop->type");
1638                 exit(0);    
1639         }    
1640         
1641 }
1642
1643 /*-----------------------------------------------------------------*/
1644 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1645 /*-----------------------------------------------------------------*/
1646 void mov2w (asmop *aop, int offset)
1647 {
1648         
1649         if(!aop)
1650                 return;
1651         
1652         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1653         
1654         if ( aop->type == AOP_PCODE ||
1655                 aop->type == AOP_LIT ||
1656                 aop->type == AOP_IMMD )
1657                 emitpcode(POC_MOVLW,popGet(aop,offset));
1658         else
1659                 emitpcode(POC_MOVFW,popGet(aop,offset));
1660         
1661 }
1662
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should        */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1667 {
1668         int size ;
1669         
1670         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1671         aop->coff = 0;
1672         if ((size = aop->size) <= 1)
1673                 return ;
1674         size-- ;
1675         switch (aop->type) {
1676         case AOP_R0 :
1677         case AOP_R1 :
1678                 while (size--)
1679                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1680                 break;          
1681         case AOP_DPTR :
1682         case AOP_DPTR2:
1683                 if (aop->type == AOP_DPTR2)
1684                 {
1685                         genSetDPTR(1);
1686                 } 
1687                 while (size--)
1688                 {
1689                         pic14_emitcode("lcall","__decdptr");
1690                 }
1691                 
1692                 if (aop->type == AOP_DPTR2)
1693                 {
1694                         genSetDPTR(0);
1695                 }
1696                 break;
1697                 
1698         }
1699         
1700 }
1701
1702
1703 #if 0
1704 /*-----------------------------------------------------------------*/
1705 /* opIsGptr: returns non-zero if the passed operand is             */   
1706 /* a generic pointer type.                                         */
1707 /*-----------------------------------------------------------------*/ 
1708 static int opIsGptr(operand *op)
1709 {
1710         sym_link *type = operandType(op);
1711         
1712         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1713         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1714         {
1715                 return 1;
1716         }
1717         return 0;        
1718 }
1719 #endif
1720
1721 /*-----------------------------------------------------------------*/
1722 /* pic14_getDataSize - get the operand data size                         */
1723 /*-----------------------------------------------------------------*/
1724 int pic14_getDataSize(operand *op)
1725 {
1726         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1727         
1728         
1729         return AOP_SIZE(op);
1730         
1731         // tsd- in the pic port, the genptr size is 1, so this code here
1732         // fails. ( in the 8051 port, the size was 4).
1733 #if 0
1734         int size;
1735         size = AOP_SIZE(op);
1736         if (size == GPTRSIZE)
1737         {
1738                 sym_link *type = operandType(op);
1739                 if (IS_GENPTR(type))
1740                 {
1741                 /* generic pointer; arithmetic operations
1742                 * should ignore the high byte (pointer type).
1743                         */
1744                         size--;
1745                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1746                 }
1747         }
1748         return size;
1749 #endif
1750 }
1751
1752 /*-----------------------------------------------------------------*/
1753 /* pic14_outAcc - output Acc                                             */
1754 /*-----------------------------------------------------------------*/
1755 void pic14_outAcc(operand *result)
1756 {
1757         int size,offset;
1758         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1759         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1760         
1761         
1762         size = pic14_getDataSize(result);
1763         if(size){
1764                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1765                 size--;
1766                 offset = 1;
1767                 /* unsigned or positive */
1768                 while(size--)
1769                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1770         }
1771         
1772 }
1773
1774 /*-----------------------------------------------------------------*/
1775 /* pic14_outBitC - output a bit C                                        */
1776 /*-----------------------------------------------------------------*/
1777 void pic14_outBitC(operand *result)
1778 {
1779         
1780         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1781         /* if the result is bit */
1782         if (AOP_TYPE(result) == AOP_CRY) 
1783                 aopPut(AOP(result),"c",0);
1784         else {
1785                 pic14_emitcode("clr","a  ; %d", __LINE__);
1786                 pic14_emitcode("rlc","a");
1787                 pic14_outAcc(result);
1788         }
1789 }
1790
1791 /*-----------------------------------------------------------------*/
1792 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1793 /*-----------------------------------------------------------------*/
1794 void pic14_toBoolean(operand *oper)
1795 {
1796         int size = AOP_SIZE(oper) - 1;
1797         int offset = 1;
1798         
1799         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1800         
1801         if ( AOP_TYPE(oper) != AOP_ACC) {
1802                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1803         }
1804         while (size--) {
1805                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1806         }
1807 }
1808
1809
1810 /*-----------------------------------------------------------------*/
1811 /* genNot - generate code for ! operation                          */
1812 /*-----------------------------------------------------------------*/
1813 static void genNot (iCode *ic)
1814 {
1815         symbol *tlbl;
1816         int size;
1817         
1818         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1819         /* assign asmOps to operand & result */
1820         aopOp (IC_LEFT(ic),ic,FALSE);
1821         aopOp (IC_RESULT(ic),ic,TRUE);
1822         
1823         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1824         /* if in bit space then a special case */
1825         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1826                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1827                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1828                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1829                 } else {
1830                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1831                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1832                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1833                 }
1834                 goto release;
1835         }
1836         
1837         size = AOP_SIZE(IC_LEFT(ic));
1838         if(size == 1) {
1839                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1840                 emitpcode(POC_ANDLW,popGetLit(1));
1841                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1842                 goto release;
1843         }
1844         pic14_toBoolean(IC_LEFT(ic));
1845         
1846         tlbl = newiTempLabel(NULL);
1847         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1848         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1849         pic14_outBitC(IC_RESULT(ic));
1850         
1851 release:    
1852         /* release the aops */
1853         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1854         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1855 }
1856
1857
1858 /*-----------------------------------------------------------------*/
1859 /* genCpl - generate code for complement                           */
1860 /*-----------------------------------------------------------------*/
1861 static void genCpl (iCode *ic)
1862 {
1863         operand *left, *result;
1864         int size, offset=0;  
1865         
1866         
1867         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1868         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1869         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1870         
1871         /* if both are in bit space then 
1872         a special case */
1873         if (AOP_TYPE(result) == AOP_CRY &&
1874                 AOP_TYPE(left) == AOP_CRY ) { 
1875                 
1876                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1877                 pic14_emitcode("cpl","c"); 
1878                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1879                 goto release; 
1880         } 
1881         
1882         size = AOP_SIZE(result);
1883         while (size--) {
1884                 
1885                 if(AOP_TYPE(left) == AOP_ACC) 
1886                         emitpcode(POC_XORLW, popGetLit(0xff));
1887                 else
1888                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1889                 
1890                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1891                 
1892         }
1893         
1894         
1895 release:
1896         /* release the aops */
1897         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1898         freeAsmop(result,NULL,ic,TRUE);
1899 }
1900
1901 /*-----------------------------------------------------------------*/
1902 /* genUminusFloat - unary minus for floating points                */
1903 /*-----------------------------------------------------------------*/
1904 static void genUminusFloat(operand *op,operand *result)
1905 {
1906         int size ,offset =0 ;
1907         char *l;
1908         
1909         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1910         /* for this we just need to flip the 
1911         first it then copy the rest in place */
1912         size = AOP_SIZE(op) - 1;
1913         l = aopGet(AOP(op),3,FALSE,FALSE);
1914         
1915         MOVA(l);    
1916         
1917         pic14_emitcode("cpl","acc.7");
1918         aopPut(AOP(result),"a",3);    
1919         
1920         while(size--) {
1921                 aopPut(AOP(result),
1922                         aopGet(AOP(op),offset,FALSE,FALSE),
1923                         offset);
1924                 offset++;
1925         }          
1926 }
1927
1928 /*-----------------------------------------------------------------*/
1929 /* genUminus - unary minus code generation                         */
1930 /*-----------------------------------------------------------------*/
1931 static void genUminus (iCode *ic)
1932 {
1933         int size, i;
1934         sym_link *optype, *rtype;
1935         
1936         
1937         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1938         /* assign asmops */
1939         aopOp(IC_LEFT(ic),ic,FALSE);
1940         aopOp(IC_RESULT(ic),ic,TRUE);
1941         
1942         /* if both in bit space then special
1943         case */
1944         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1945                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1946                 
1947                 emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1948                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1949                 emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1950                 
1951                 goto release; 
1952         } 
1953         
1954         optype = operandType(IC_LEFT(ic));
1955         rtype = operandType(IC_RESULT(ic));
1956         
1957         /* if float then do float stuff */
1958         if (IS_FLOAT(optype)) {
1959                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1960                 goto release;
1961         }
1962         
1963         /* otherwise subtract from zero by taking the 2's complement */
1964         size = AOP_SIZE(IC_LEFT(ic));
1965         
1966         for(i=0; i<size; i++) {
1967                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1968                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1969                 else {
1970                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1971                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1972                 }
1973         }
1974         
1975         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1976         for(i=1; i<size; i++) {
1977                 emitSKPNZ;
1978                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1979         }
1980         
1981 release:
1982         /* release the aops */
1983         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1984         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1985 }
1986
1987 /*-----------------------------------------------------------------*/
1988 /* saveRegisters - will look for a call and save the registers     */
1989 /*-----------------------------------------------------------------*/
1990 static void saveRegisters(iCode *lic) 
1991 {
1992         int i;
1993         iCode *ic;
1994         bitVect *rsave;
1995         sym_link *dtype;
1996         
1997         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1998         /* look for call */
1999         for (ic = lic ; ic ; ic = ic->next) 
2000                 if (ic->op == CALL || ic->op == PCALL)
2001                         break;
2002                 
2003                 if (!ic) {
2004                         fprintf(stderr,"found parameter push with no function call\n");
2005                         return ;
2006                 }
2007                 
2008                 /* if the registers have been saved already then
2009                 do nothing */
2010                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2011                         return ;
2012                 
2013                         /* find the registers in use at this time 
2014                 and push them away to safety */
2015                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2016                         ic->rUsed);
2017                 
2018                 ic->regsSaved = 1;
2019                 if (options.useXstack) {
2020                         if (bitVectBitValue(rsave,R0_IDX))
2021                                 pic14_emitcode("mov","b,r0");
2022                         pic14_emitcode("mov","r0,%s",spname);
2023                         for (i = 0 ; i < pic14_nRegs ; i++) {
2024                                 if (bitVectBitValue(rsave,i)) {
2025                                         if (i == R0_IDX)
2026                                                 pic14_emitcode("mov","a,b");
2027                                         else
2028                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2029                                         pic14_emitcode("movx","@r0,a");
2030                                         pic14_emitcode("inc","r0");
2031                                 }
2032                         }
2033                         pic14_emitcode("mov","%s,r0",spname);
2034                         if (bitVectBitValue(rsave,R0_IDX))
2035                                 pic14_emitcode("mov","r0,b");       
2036                 }// else
2037                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2038                 //    if (bitVectBitValue(rsave,i))
2039                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2040                 //}
2041                 
2042                 dtype = operandType(IC_LEFT(ic));
2043                 if (currFunc && dtype && 
2044                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2045                         IFFUNC_ISISR(currFunc->type) &&
2046                         !ic->bankSaved) 
2047                         
2048                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2049                 
2050 }
2051 /*-----------------------------------------------------------------*/
2052 /* unsaveRegisters - pop the pushed registers                      */
2053 /*-----------------------------------------------------------------*/
2054 static void unsaveRegisters (iCode *ic)
2055 {
2056         int i;
2057         bitVect *rsave;
2058         
2059         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2060         /* find the registers in use at this time 
2061         and push them away to safety */
2062         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2063                 ic->rUsed);
2064         
2065         if (options.useXstack) {
2066                 pic14_emitcode("mov","r0,%s",spname);   
2067                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2068                         if (bitVectBitValue(rsave,i)) {
2069                                 pic14_emitcode("dec","r0");
2070                                 pic14_emitcode("movx","a,@r0");
2071                                 if (i == R0_IDX)
2072                                         pic14_emitcode("mov","b,a");
2073                                 else
2074                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2075                         }           
2076                         
2077                 }
2078                 pic14_emitcode("mov","%s,r0",spname);
2079                 if (bitVectBitValue(rsave,R0_IDX))
2080                         pic14_emitcode("mov","r0,b");
2081         } //else
2082         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2083         //    if (bitVectBitValue(rsave,i))
2084         //      pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2085         //}
2086         
2087 }  
2088
2089
2090 /*-----------------------------------------------------------------*/
2091 /* pushSide -                                                      */
2092 /*-----------------------------------------------------------------*/
2093 static void pushSide(operand * oper, int size)
2094 {
2095 #if 0
2096         int offset = 0;
2097         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2098         while (size--) {
2099                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2100                 if (AOP_TYPE(oper) != AOP_REG &&
2101                         AOP_TYPE(oper) != AOP_DIR &&
2102                         strcmp(l,"a") ) {
2103                         pic14_emitcode("mov","a,%s",l);
2104                         pic14_emitcode("push","acc");
2105                 } else
2106                         pic14_emitcode("push","%s",l);
2107         }
2108 #endif
2109 }
2110
2111 /*-----------------------------------------------------------------*/
2112 /* assignResultValue -                                             */
2113 /*-----------------------------------------------------------------*/
2114 static void assignResultValue(operand * oper)
2115 {
2116         int size = AOP_SIZE(oper);
2117         
2118         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2119         
2120         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2121         
2122         while (size--) {
2123                 if (GpsuedoStkPtr++)
2124                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2125                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2126         }
2127 }
2128
2129
2130 /*-----------------------------------------------------------------*/
2131 /* genIpush - genrate code for pushing this gets a little complex  */
2132 /*-----------------------------------------------------------------*/
2133 static void genIpush (iCode *ic)
2134 {
2135         
2136         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2137 #if 0
2138         int size, offset = 0 ;
2139         char *l;
2140         
2141         
2142         /* if this is not a parm push : ie. it is spill push 
2143         and spill push is always done on the local stack */
2144         if (!ic->parmPush) {
2145                 
2146                 /* and the item is spilt then do nothing */
2147                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2148                         return ;
2149                 
2150                 aopOp(IC_LEFT(ic),ic,FALSE);
2151                 size = AOP_SIZE(IC_LEFT(ic));
2152                 /* push it on the stack */
2153                 while(size--) {
2154                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2155                         if (*l == '#') {
2156                                 MOVA(l);
2157                                 l = "acc";
2158                         }
2159                         pic14_emitcode("push","%s",l);
2160                 }
2161                 return ;        
2162         }
2163         
2164         /* this is a paramter push: in this case we call
2165         the routine to find the call and save those
2166         registers that need to be saved */   
2167         saveRegisters(ic);
2168         
2169         /* then do the push */
2170         aopOp(IC_LEFT(ic),ic,FALSE);
2171         
2172         
2173         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2174         size = AOP_SIZE(IC_LEFT(ic));
2175         
2176         while (size--) {
2177                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2178                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2179                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2180                         strcmp(l,"a") ) {
2181                         pic14_emitcode("mov","a,%s",l);
2182                         pic14_emitcode("push","acc");
2183                 } else
2184                         pic14_emitcode("push","%s",l);
2185         }       
2186         
2187         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2188 #endif
2189 }
2190
2191 /*-----------------------------------------------------------------*/
2192 /* genIpop - recover the registers: can happen only for spilling   */
2193 /*-----------------------------------------------------------------*/
2194 static void genIpop (iCode *ic)
2195 {
2196         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2197 #if 0
2198         int size,offset ;
2199         
2200         
2201         /* if the temp was not pushed then */
2202         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2203                 return ;
2204         
2205         aopOp(IC_LEFT(ic),ic,FALSE);
2206         size = AOP_SIZE(IC_LEFT(ic));
2207         offset = (size-1);
2208         while (size--) 
2209                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2210                 FALSE,TRUE));
2211         
2212         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2213 #endif
2214 }
2215
2216 /*-----------------------------------------------------------------*/
2217 /* unsaverbank - restores the resgister bank from stack            */
2218 /*-----------------------------------------------------------------*/
2219 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2220 {
2221         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2222 #if 0
2223         int i;
2224         asmop *aop ;
2225         regs *r = NULL;
2226         
2227         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2228         if (popPsw) {
2229                 if (options.useXstack) {
2230                         aop = newAsmop(0);
2231                         r = getFreePtr(ic,&aop,FALSE);
2232                         
2233                         
2234                         pic14_emitcode("mov","%s,_spx",r->name);
2235                         pic14_emitcode("movx","a,@%s",r->name);
2236                         pic14_emitcode("mov","psw,a");
2237                         pic14_emitcode("dec","%s",r->name);
2238                         
2239                 }else
2240                         pic14_emitcode ("pop","psw");
2241         }
2242         
2243         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2244                 if (options.useXstack) {       
2245                         pic14_emitcode("movx","a,@%s",r->name);
2246                         //pic14_emitcode("mov","(%s+%d),a",
2247                         //       regspic14[i].base,8*bank+regspic14[i].offset);
2248                         pic14_emitcode("dec","%s",r->name);
2249                         
2250                 } else 
2251                         pic14_emitcode("pop",""); //"(%s+%d)",
2252                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2253         }
2254         
2255         if (options.useXstack) {
2256                 
2257                 pic14_emitcode("mov","_spx,%s",r->name);
2258                 freeAsmop(NULL,aop,ic,TRUE);
2259                 
2260         }
2261 #endif 
2262 }
2263
2264 /*-----------------------------------------------------------------*/
2265 /* saverbank - saves an entire register bank on the stack          */
2266 /*-----------------------------------------------------------------*/
2267 static void saverbank (int bank, iCode *ic, bool pushPsw)
2268 {
2269         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2270 #if 0
2271         int i;
2272         asmop *aop ;
2273         regs *r = NULL;
2274         
2275         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2276         if (options.useXstack) {
2277                 
2278                 aop = newAsmop(0);
2279                 r = getFreePtr(ic,&aop,FALSE);  
2280                 pic14_emitcode("mov","%s,_spx",r->name);
2281                 
2282         }
2283         
2284         for (i = 0 ; i < pic14_nRegs ;i++) {
2285                 if (options.useXstack) {
2286                         pic14_emitcode("inc","%s",r->name);
2287                         //pic14_emitcode("mov","a,(%s+%d)",
2288                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2289                         pic14_emitcode("movx","@%s,a",r->name);           
2290                 } else 
2291                         pic14_emitcode("push","");// "(%s+%d)",
2292                 //regspic14[i].base,8*bank+regspic14[i].offset);
2293         }
2294         
2295         if (pushPsw) {
2296                 if (options.useXstack) {
2297                         pic14_emitcode("mov","a,psw");
2298                         pic14_emitcode("movx","@%s,a",r->name); 
2299                         pic14_emitcode("inc","%s",r->name);
2300                         pic14_emitcode("mov","_spx,%s",r->name);       
2301                         freeAsmop (NULL,aop,ic,TRUE);
2302                         
2303                 } else
2304                         pic14_emitcode("push","psw");
2305                 
2306                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2307         }
2308         ic->bankSaved = 1;
2309 #endif
2310 }
2311
2312 /*-----------------------------------------------------------------*/
2313 /* genCall - generates a call statement                            */
2314 /*-----------------------------------------------------------------*/
2315 static void genCall (iCode *ic)
2316 {
2317         sym_link *dtype;   
2318         symbol *sym;
2319         unsigned char *name;
2320         int isExtern;
2321         
2322         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2323         
2324         /* if caller saves & we have not saved then */
2325         if (!ic->regsSaved)
2326                 saveRegisters(ic);
2327         
2328                 /* if we are calling a function that is not using
2329                 the same register bank then we need to save the
2330         destination registers on the stack */
2331         dtype = operandType(IC_LEFT(ic));
2332         if (currFunc && dtype && 
2333                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2334                 IFFUNC_ISISR(currFunc->type) &&
2335                 !ic->bankSaved) 
2336                 
2337                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2338         
2339         /* if send set is not empty the assign */
2340         if (_G.sendSet) {
2341                 iCode *sic;
2342                 /* For the Pic port, there is no data stack.
2343                 * So parameters passed to functions are stored
2344                 * in registers. (The pCode optimizer will get
2345                 * rid of most of these :).
2346                 */
2347                 int psuedoStkPtr=-1;
2348                 int firstTimeThruLoop = 1;
2349                 
2350                 _G.sendSet = reverseSet(_G.sendSet);
2351                 
2352                 /* First figure how many parameters are getting passed */
2353                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2354                 sic = setNextItem(_G.sendSet)) {
2355                         
2356                         aopOp(IC_LEFT(sic),sic,FALSE);
2357                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2358                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2359                 }
2360                 
2361                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2362                 sic = setNextItem(_G.sendSet)) {
2363                         int size, offset = 0;
2364                         
2365                         aopOp(IC_LEFT(sic),sic,FALSE);
2366                         size = AOP_SIZE(IC_LEFT(sic));
2367                         
2368                         while (size--) {
2369                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2370                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2371                                 
2372                                 if(!firstTimeThruLoop) {
2373                                 /* If this is not the first time we've been through the loop
2374                                 * then we need to save the parameter in a temporary
2375                                 * register. The last byte of the last parameter is
2376                                         * passed in W. */
2377                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2378                                         
2379                                 }
2380                                 firstTimeThruLoop=0;
2381                                 
2382                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2383                                 offset++;
2384                         }
2385                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2386                 }
2387                 _G.sendSet = NULL;
2388         }
2389         /* make the call */
2390         sym = OP_SYMBOL(IC_LEFT(ic));
2391         name = sym->rname[0] ? sym->rname : sym->name;
2392         isExtern = IS_EXTERN(sym->etype);
2393         if (isExtern) {
2394                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2395         }
2396         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2397         if (isExtern) {
2398                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2399         }
2400         GpsuedoStkPtr=0;
2401         /* if we need assign a result value */
2402         if ((IS_ITEMP(IC_RESULT(ic)) && 
2403                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2404                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2405                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2406                 
2407                 _G.accInUse++;
2408                 aopOp(IC_RESULT(ic),ic,FALSE);
2409                 _G.accInUse--;
2410                 
2411                 assignResultValue(IC_RESULT(ic));
2412                 
2413                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2414                         AopType(AOP_TYPE(IC_RESULT(ic))));
2415                 
2416                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2417         }
2418         
2419         /* adjust the stack for parameters if 
2420         required */
2421         if (ic->parmBytes) {
2422                 int i;
2423                 if (ic->parmBytes > 3) {
2424                         pic14_emitcode("mov","a,%s",spname);
2425                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2426                         pic14_emitcode("mov","%s,a",spname);
2427                 } else 
2428                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2429                                 pic14_emitcode("dec","%s",spname);
2430                         
2431         }
2432         
2433         /* if register bank was saved then pop them */
2434         if (ic->bankSaved)
2435                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2436         
2437         /* if we hade saved some registers then unsave them */
2438         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2439                 unsaveRegisters (ic);
2440         
2441         
2442 }
2443
2444 /*-----------------------------------------------------------------*/
2445 /* genPcall - generates a call by pointer statement                */
2446 /*-----------------------------------------------------------------*/
2447 static void genPcall (iCode *ic)
2448 {
2449         sym_link *dtype;
2450         symbol *albl = newiTempLabel(NULL);
2451         symbol *blbl = newiTempLabel(NULL);
2452         PIC_OPCODE poc;
2453         pCodeOp *pcop;
2454         operand *left;
2455         
2456         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2457         /* if caller saves & we have not saved then */
2458         if (!ic->regsSaved)
2459                 saveRegisters(ic);
2460         
2461                 /* if we are calling a function that is not using
2462                 the same register bank then we need to save the
2463         destination registers on the stack */
2464         dtype = operandType(IC_LEFT(ic));
2465         if (currFunc && dtype && 
2466                 IFFUNC_ISISR(currFunc->type) &&
2467                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2468                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2469         
2470         left = IC_LEFT(ic);
2471         aopOp(left,ic,FALSE);
2472         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2473         
2474         pushSide(IC_LEFT(ic), FPTRSIZE);
2475         
2476         /* if send set is not empty, assign parameters */
2477         if (_G.sendSet) {
2478                 
2479                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2480                 /* no way to pass args - W always gets used to make the call */
2481         }
2482         /* first idea - factor out a common helper function and call it.
2483         But don't know how to get it generated only once in its own block
2484         
2485           if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2486           char *rname;
2487           char *buffer;
2488           rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2489           DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2490           buffer = Safe_calloc(1,strlen(rname)+16);
2491           sprintf(buffer, "%s_goto_helper", rname);
2492           addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2493           free(buffer);
2494           }
2495         */
2496         emitpcode(POC_CALL,popGetLabel(albl->key));
2497         pcop = popGetLabel(blbl->key);
2498         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2499         emitpcode(POC_GOTO,pcop);
2500         emitpLabel(albl->key);
2501         
2502         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2503         
2504         emitpcode(poc,popGet(AOP(left),1));
2505         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2506         emitpcode(poc,popGet(AOP(left),0));
2507         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2508         
2509         emitpLabel(blbl->key);
2510         
2511         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2512         
2513         /* if we need to assign a result value */
2514         if ((IS_ITEMP(IC_RESULT(ic)) &&
2515                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2516                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2517                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2518                 
2519                 _G.accInUse++;
2520                 aopOp(IC_RESULT(ic),ic,FALSE);
2521                 _G.accInUse--;
2522                 
2523                 assignResultValue(IC_RESULT(ic));
2524                 
2525                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2526         }
2527         
2528         /* if register bank was saved then unsave them */
2529         if (currFunc && dtype && 
2530                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2531                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2532         
2533                 /* if we hade saved some registers then
2534         unsave them */
2535         if (ic->regsSaved)
2536                 unsaveRegisters (ic);
2537         
2538 }
2539
2540 /*-----------------------------------------------------------------*/
2541 /* resultRemat - result  is rematerializable                       */
2542 /*-----------------------------------------------------------------*/
2543 static int resultRemat (iCode *ic)
2544 {
2545         //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2546         if (SKIP_IC(ic) || ic->op == IFX)
2547                 return 0;
2548         
2549         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2550                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2551                 if (sym->remat && !POINTER_SET(ic)) 
2552                         return 1;
2553         }
2554         
2555         return 0;
2556 }
2557
2558 #if defined(__BORLANDC__) || defined(_MSC_VER)
2559 #define STRCASECMP stricmp
2560 #else
2561 #define STRCASECMP strcasecmp
2562 #endif
2563
2564 #if 0
2565 /*-----------------------------------------------------------------*/
2566 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2567 /*-----------------------------------------------------------------*/
2568 static bool inExcludeList(char *s)
2569 {
2570         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2571         int i =0;
2572         
2573         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2574         if (options.excludeRegs[i] &&
2575                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2576                 return FALSE ;
2577         
2578         for ( i = 0 ; options.excludeRegs[i]; i++) {
2579                 if (options.excludeRegs[i] &&
2580                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2581                         return TRUE;
2582         }
2583         return FALSE ;
2584 }
2585 #endif
2586
2587 /*-----------------------------------------------------------------*/
2588 /* genFunction - generated code for function entry                 */
2589 /*-----------------------------------------------------------------*/
2590 static void genFunction (iCode *ic)
2591 {
2592         symbol *sym;
2593         sym_link *ftype;
2594         
2595         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2596         
2597         labelOffset += (max_key+4);
2598         max_key=0;
2599         GpsuedoStkPtr=0;
2600         _G.nRegsSaved = 0;
2601         /* create the function header */
2602         pic14_emitcode(";","-----------------------------------------");
2603         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2604         pic14_emitcode(";","-----------------------------------------");
2605         
2606         pic14_emitcode("","%s:",sym->rname);
2607         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2608         
2609         ftype = operandType(IC_LEFT(ic));
2610         
2611         /* if critical function then turn interrupts off */
2612         if (IFFUNC_ISCRITICAL(ftype))
2613                 pic14_emitcode("clr","ea");
2614         
2615                 /* here we need to generate the equates for the
2616         register bank if required */
2617 #if 0
2618         if (FUNC_REGBANK(ftype) != rbank) {
2619                 int i ;
2620                 
2621                 rbank = FUNC_REGBANK(ftype);
2622                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2623                         if (strcmp(regspic14[i].base,"0") == 0)
2624                                 pic14_emitcode("","%s = 0x%02x",
2625                                 regspic14[i].dname,
2626                                 8*rbank+regspic14[i].offset);
2627                         else
2628                                 pic14_emitcode ("","%s = %s + 0x%02x",
2629                                 regspic14[i].dname,
2630                                 regspic14[i].base,
2631                                 8*rbank+regspic14[i].offset);
2632                 }
2633         }
2634 #endif
2635         
2636         /* if this is an interrupt service routine */
2637         if (IFFUNC_ISISR(sym->type)) {
2638         /*  already done in pic14createInterruptVect() - delete me
2639         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2640         emitpcodeNULLop(POC_NOP);
2641         emitpcodeNULLop(POC_NOP);
2642         emitpcodeNULLop(POC_NOP);
2643                 */
2644                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2645                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2646                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2647                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2648                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2649                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2650                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2651                 
2652                 pBlockConvert2ISR(pb);
2653 #if 0  
2654                 if (!inExcludeList("acc"))          
2655                         pic14_emitcode ("push","acc");  
2656                 if (!inExcludeList("b"))
2657                         pic14_emitcode ("push","b");
2658                 if (!inExcludeList("dpl"))
2659                         pic14_emitcode ("push","dpl");
2660                 if (!inExcludeList("dph"))
2661                         pic14_emitcode ("push","dph");
2662                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2663                 {
2664                         pic14_emitcode ("push", "dpx");
2665                         /* Make sure we're using standard DPTR */
2666                         pic14_emitcode ("push", "dps");
2667                         pic14_emitcode ("mov", "dps, #0x00");
2668                         if (options.stack10bit)
2669                         {       
2670                                 /* This ISR could conceivably use DPTR2. Better save it. */
2671                                 pic14_emitcode ("push", "dpl1");
2672                                 pic14_emitcode ("push", "dph1");
2673                                 pic14_emitcode ("push", "dpx1");
2674                         }
2675                 }
2676                 /* if this isr has no bank i.e. is going to
2677                 run with bank 0 , then we need to save more
2678 registers :-) */
2679                 if (!FUNC_REGBANK(sym->type)) {
2680                         
2681                 /* if this function does not call any other
2682                 function then we can be economical and
2683                         save only those registers that are used */
2684                         if (! IFFUNC_HASFCALL(sym->type)) {
2685                                 int i;
2686                                 
2687                                 /* if any registers used */
2688                                 if (sym->regsUsed) {
2689                                         /* save the registers used */
2690                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2691                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2692                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2693                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                           
2694                                         }
2695                                 }
2696                                 
2697                         } else {
2698                         /* this function has  a function call cannot
2699                         determines register usage so we will have the
2700                                 entire bank */
2701                                 saverbank(0,ic,FALSE);
2702                         }           
2703                 }
2704 #endif
2705         } else {
2706         /* if callee-save to be used for this function
2707                 then save the registers being used in this function */
2708                 if (IFFUNC_CALLEESAVES(sym->type)) {
2709                         int i;
2710                         
2711                         /* if any registers used */
2712                         if (sym->regsUsed) {
2713                                 /* save the registers used */
2714                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2715                                         if (bitVectBitValue(sym->regsUsed,i) ||
2716                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2717                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2718                                                 _G.nRegsSaved++;
2719                                         }
2720                                 }
2721                         }
2722                 }
2723         }
2724         
2725         /* set the register bank to the desired value */
2726         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2727                 pic14_emitcode("push","psw");
2728                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2729         }
2730         
2731         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2732                 
2733                 if (options.useXstack) {
2734                         pic14_emitcode("mov","r0,%s",spname);
2735                         pic14_emitcode("mov","a,_bp");
2736                         pic14_emitcode("movx","@r0,a");
2737                         pic14_emitcode("inc","%s",spname);
2738                 }
2739                 else
2740                 {
2741                         /* set up the stack */
2742                         pic14_emitcode ("push","_bp");     /* save the callers stack  */
2743                 }
2744                 pic14_emitcode ("mov","_bp,%s",spname);
2745         }
2746         
2747         /* adjust the stack for the function */
2748         if (sym->stack) {
2749                 
2750                 int i = sym->stack;
2751                 if (i > 256 ) 
2752                         werror(W_STACK_OVERFLOW,sym->name);
2753                 
2754                 if (i > 3 && sym->recvSize < 4) {              
2755                         
2756                         pic14_emitcode ("mov","a,sp");
2757                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2758                         pic14_emitcode ("mov","sp,a");
2759                         
2760                 }
2761                 else
2762                         while(i--)
2763                                 pic14_emitcode("inc","sp");
2764         }
2765         
2766         if (sym->xstack) {
2767                 
2768                 pic14_emitcode ("mov","a,_spx");
2769                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2770                 pic14_emitcode ("mov","_spx,a");
2771         }    
2772         
2773 }
2774
2775 /*-----------------------------------------------------------------*/
2776 /* genEndFunction - generates epilogue for functions               */
2777 /*-----------------------------------------------------------------*/
2778 static void genEndFunction (iCode *ic)
2779 {
2780         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2781         
2782         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2783         
2784         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2785         {
2786                 pic14_emitcode ("mov","%s,_bp",spname);
2787         }
2788         
2789         /* if use external stack but some variables were
2790         added to the local stack then decrement the
2791         local stack */
2792         if (options.useXstack && sym->stack) {      
2793                 pic14_emitcode("mov","a,sp");
2794                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2795                 pic14_emitcode("mov","sp,a");
2796         }
2797         
2798         
2799         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2800                 if (options.useXstack) {
2801                         pic14_emitcode("mov","r0,%s",spname);
2802                         pic14_emitcode("movx","a,@r0");
2803                         pic14_emitcode("mov","_bp,a");
2804                         pic14_emitcode("dec","%s",spname);
2805                 }
2806                 else
2807                 {
2808                         pic14_emitcode ("pop","_bp");
2809                 }
2810         }
2811         
2812         /* restore the register bank  */    
2813         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2814                 pic14_emitcode ("pop","psw");
2815         
2816         if (IFFUNC_ISISR(sym->type)) {
2817                 
2818                 /* now we need to restore the registers */
2819                 /* if this isr has no bank i.e. is going to
2820                 run with bank 0 , then we need to save more
2821 registers :-) */
2822                 if (!FUNC_REGBANK(sym->type)) {
2823                         
2824                 /* if this function does not call any other
2825                 function then we can be economical and
2826                         save only those registers that are used */
2827                         if (! IFFUNC_HASFCALL(sym->type)) {
2828                                 int i;
2829                                 
2830                                 /* if any registers used */
2831                                 if (sym->regsUsed) {
2832                                         /* save the registers used */
2833                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2834                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2835                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2836                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2837                                         }
2838                                 }
2839                                 
2840                         } else {
2841                         /* this function has  a function call cannot
2842                         determines register usage so we will have the
2843                                 entire bank */
2844                                 unsaverbank(0,ic,FALSE);
2845                         }           
2846                 }
2847 #if 0
2848                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2849                 {
2850                         if (options.stack10bit)
2851                         {
2852                                 pic14_emitcode ("pop", "dpx1");
2853                                 pic14_emitcode ("pop", "dph1");
2854                                 pic14_emitcode ("pop", "dpl1");
2855                         }       
2856                         pic14_emitcode ("pop", "dps");
2857                         pic14_emitcode ("pop", "dpx");
2858                 }
2859                 if (!inExcludeList("dph"))
2860                         pic14_emitcode ("pop","dph");
2861                 if (!inExcludeList("dpl"))
2862                         pic14_emitcode ("pop","dpl");
2863                 if (!inExcludeList("b"))
2864                         pic14_emitcode ("pop","b");
2865                 if (!inExcludeList("acc"))
2866                         pic14_emitcode ("pop","acc");
2867                 
2868                 if (IFFUNC_ISCRITICAL(sym->type))
2869                         pic14_emitcode("setb","ea");
2870 #endif
2871                 
2872                 /* if debug then send end of function */
2873                 /*      if (options.debug && currFunc) { */
2874                 if (currFunc) {
2875                         _G.debugLine = 1;
2876                         pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2877                                 FileBaseName(ic->filename),currFunc->lastLine,
2878                                 ic->level,ic->block); 
2879                         if (IS_STATIC(currFunc->etype))     
2880                                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2881                         else
2882                                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2883                         _G.debugLine = 0;
2884                 }
2885                 
2886                 pic14_emitcode ("reti","");
2887                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2888                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2889                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2890                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2891                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2892                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2893                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2894                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2895                 emitpcodeNULLop(POC_RETFIE);
2896         }
2897         else {
2898                 if (IFFUNC_ISCRITICAL(sym->type))
2899                         pic14_emitcode("setb","ea");
2900                 
2901                 if (IFFUNC_CALLEESAVES(sym->type)) {
2902                         int i;
2903                         
2904                         /* if any registers used */
2905                         if (sym->regsUsed) {
2906                                 /* save the registers used */
2907                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2908                                         if (bitVectBitValue(sym->regsUsed,i) ||
2909                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2910                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2911                                 }
2912                         }
2913                         
2914                 }
2915                 
2916                 /* if debug then send end of function */
2917                 if (currFunc) {
2918                         _G.debugLine = 1;
2919                         pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2920                                 FileBaseName(ic->filename),currFunc->lastLine,
2921                                 ic->level,ic->block); 
2922                         if (IS_STATIC(currFunc->etype))     
2923                                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2924                         else
2925                                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2926                         _G.debugLine = 0;
2927                 }
2928                 
2929                 pic14_emitcode ("return","");
2930                 emitpcodeNULLop(POC_RETURN);
2931                 
2932                 /* Mark the end of a function */
2933                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2934         }
2935         
2936 }
2937
2938 /*-----------------------------------------------------------------*/
2939 /* genRet - generate code for return statement                     */
2940 /*-----------------------------------------------------------------*/
2941 static void genRet (iCode *ic)
2942 {
2943         int size,offset = 0 , pushed = 0;
2944         
2945         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2946         /* if we have no return value then
2947         just generate the "ret" */
2948         if (!IC_LEFT(ic)) 
2949                 goto jumpret;       
2950         
2951                 /* we have something to return then
2952         move the return value into place */
2953         aopOp(IC_LEFT(ic),ic,FALSE);
2954         size = AOP_SIZE(IC_LEFT(ic));
2955         
2956         while (size--) {
2957                 char *l ;
2958                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2959                         /* #NOCHANGE */
2960                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
2961                                 FALSE,TRUE);
2962                         pic14_emitcode("push","%s",l);
2963                         pushed++;
2964                 } else {
2965                         l = aopGet(AOP(IC_LEFT(ic)),offset,
2966                                 FALSE,FALSE);
2967                         if (strcmp(fReturn[offset],l)) {
2968                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
2969                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2970                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2971                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2972                                         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2973                                 }else {
2974                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2975                                 }
2976                                 if(size) {
2977                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2978                                 }
2979                                 offset++;
2980                         }
2981                 }
2982         }    
2983         
2984         if (pushed) {
2985                 while(pushed) {
2986                         pushed--;
2987                         if (strcmp(fReturn[pushed],"a"))
2988                                 pic14_emitcode("pop",fReturn[pushed]);
2989                         else
2990                                 pic14_emitcode("pop","acc");
2991                 }
2992         }
2993         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2994         
2995 jumpret:
2996 /* generate a jump to the return label
2997         if the next is not the return statement */
2998         if (!(ic->next && ic->next->op == LABEL &&
2999                 IC_LABEL(ic->next) == returnLabel)) {
3000                 
3001                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3002                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3003         }
3004         
3005 }
3006
3007 /*-----------------------------------------------------------------*/
3008 /* genLabel - generates a label                                    */
3009 /*-----------------------------------------------------------------*/
3010 static void genLabel (iCode *ic)
3011 {
3012         /* special case never generate */
3013         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3014         if (IC_LABEL(ic) == entryLabel)
3015                 return ;
3016         
3017         emitpLabel(IC_LABEL(ic)->key);
3018         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3019 }
3020
3021 /*-----------------------------------------------------------------*/
3022 /* genGoto - generates a goto                                      */
3023 /*-----------------------------------------------------------------*/
3024 //tsd
3025 static void genGoto (iCode *ic)
3026 {
3027         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3028         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3029 }
3030
3031
3032 /*-----------------------------------------------------------------*/
3033 /* genMultbits :- multiplication of bits                           */
3034 /*-----------------------------------------------------------------*/
3035 static void genMultbits (operand *left, 
3036                                                  operand *right, 
3037                                                  operand *result)
3038 {
3039         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3040         
3041         if(!pic14_sameRegs(AOP(result),AOP(right)))
3042                 emitpcode(POC_BSF,  popGet(AOP(result),0));
3043         
3044         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3045         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3046         emitpcode(POC_BCF,  popGet(AOP(result),0));
3047         
3048 }
3049
3050
3051 /*-----------------------------------------------------------------*/
3052 /* genMultOneByte : 8 bit multiplication & division                */
3053 /*-----------------------------------------------------------------*/
3054 static void genMultOneByte (operand *left,
3055                                                         operand *right,
3056                                                         operand *result)
3057 {
3058         sym_link *opetype = operandType(result);
3059         
3060         // symbol *lbl ;
3061         int size,offset;
3062         
3063         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3064         DEBUGpic14_AopType(__LINE__,left,right,result);
3065         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3066         
3067         /* (if two literals, the value is computed before) */
3068         /* if one literal, literal on the right */
3069         if (AOP_TYPE(left) == AOP_LIT){
3070                 operand *t = right;
3071                 right = left;
3072                 left = t;
3073         }
3074         
3075         size = AOP_SIZE(result);
3076         if(size == 1) {
3077                 
3078                 if (AOP_TYPE(right) == AOP_LIT){
3079                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3080                                 aopGet(AOP(right),0,FALSE,FALSE), 
3081                                 aopGet(AOP(left),0,FALSE,FALSE), 
3082                                 aopGet(AOP(result),0,FALSE,FALSE));
3083                         pic14_emitcode("call","genMultLit");
3084                 } else {
3085                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3086                                 aopGet(AOP(right),0,FALSE,FALSE), 
3087                                 aopGet(AOP(left),0,FALSE,FALSE), 
3088                                 aopGet(AOP(result),0,FALSE,FALSE));
3089                         pic14_emitcode("call","genMult8X8_8");
3090                         
3091                 }
3092                 genMult8X8_8 (left, right,result);
3093                 
3094                 
3095                 /* signed or unsigned */
3096                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3097                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3098                 //MOVA(l);       
3099                 //pic14_emitcode("mul","ab");
3100                 /* if result size = 1, mul signed = mul unsigned */
3101                 //aopPut(AOP(result),"a",0);
3102                 
3103         } else {  // (size > 1)
3104                 
3105                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3106                         aopGet(AOP(right),0,FALSE,FALSE), 
3107                         aopGet(AOP(left),0,FALSE,FALSE), 
3108                         aopGet(AOP(result),0,FALSE,FALSE));
3109                 
3110                 if (SPEC_USIGN(opetype)){
3111                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3112                         genUMult8X8_16 (left, right, result, NULL);
3113                         
3114                         if (size > 2) {
3115                                 /* for filling the MSBs */
3116                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3117                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3118                         }
3119                 }
3120                 else{
3121                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3122                         
3123                         pic14_emitcode("mov","a,b");
3124                         
3125                         /* adjust the MSB if left or right neg */
3126                         
3127                         /* if one literal */
3128                         if (AOP_TYPE(right) == AOP_LIT){
3129                                 pic14_emitcode("multiply ","right is a lit");
3130                                 /* AND literal negative */
3131                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3132                                         /* adjust MSB (c==0 after mul) */
3133                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3134                                 }
3135                         }
3136                         else{
3137                                 genSMult8X8_16 (left, right, result, NULL);
3138                         }
3139                         
3140                         if(size > 2){
3141                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3142                                 /* get the sign */
3143                                 pic14_emitcode("rlc","a");
3144                                 pic14_emitcode("subb","a,acc");
3145                         }
3146                 }
3147                 
3148                 size -= 2;   
3149                 offset = 2;
3150                 if (size > 0)
3151                         while (size--)
3152                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3153                         //aopPut(AOP(result),"a",offset++);
3154         }
3155 }
3156
3157 /*-----------------------------------------------------------------*/
3158 /* genMult - generates code for multiplication                     */
3159 /*-----------------------------------------------------------------*/
3160 static void genMult (iCode *ic)
3161 {
3162         operand *left = IC_LEFT(ic);
3163         operand *right = IC_RIGHT(ic);
3164         operand *result= IC_RESULT(ic);   
3165         
3166         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3167         /* assign the amsops */
3168         aopOp (left,ic,FALSE);
3169         aopOp (right,ic,FALSE);
3170         aopOp (result,ic,TRUE);
3171         
3172         DEBUGpic14_AopType(__LINE__,left,right,result);
3173         
3174         /* special cases first */
3175         /* both are bits */
3176         if (AOP_TYPE(left) == AOP_CRY &&
3177                 AOP_TYPE(right)== AOP_CRY) {
3178                 genMultbits(left,right,result);
3179                 goto release ;
3180         }
3181         
3182         /* if both are of size == 1 */
3183         if (AOP_SIZE(left) == 1 &&
3184                 AOP_SIZE(right) == 1 ) {
3185                 genMultOneByte(left,right,result);
3186                 goto release ;
3187         }
3188         
3189         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3190         
3191         /* should have been converted to function call */
3192         //assert(0) ;
3193         
3194 release :
3195         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3196         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3197         freeAsmop(result,NULL,ic,TRUE); 
3198 }
3199
3200 /*-----------------------------------------------------------------*/
3201 /* genDivbits :- division of bits                                  */
3202 /*-----------------------------------------------------------------*/
3203 static void genDivbits (operand *left, 
3204                                                 operand *right, 
3205                                                 operand *result)
3206 {
3207         
3208         char *l;
3209         
3210         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3211         /* the result must be bit */    
3212         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3213         l = aopGet(AOP(left),0,FALSE,FALSE);
3214         
3215         MOVA(l);    
3216         
3217         pic14_emitcode("div","ab");
3218         pic14_emitcode("rrc","a");
3219         aopPut(AOP(result),"c",0);
3220 }
3221
3222 /*-----------------------------------------------------------------*/
3223 /* genDivOneByte : 8 bit division                                  */
3224 /*-----------------------------------------------------------------*/
3225 static void genDivOneByte (operand *left,
3226                                                    operand *right,
3227                                                    operand *result)
3228 {
3229         sym_link *opetype = operandType(result);
3230         char *l ;
3231         symbol *lbl ;
3232         int size,offset;
3233         
3234         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3235         size = AOP_SIZE(result) - 1;
3236         offset = 1;
3237         /* signed or unsigned */
3238         if (SPEC_USIGN(opetype)) {
3239                 /* unsigned is easy */
3240                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3241                 l = aopGet(AOP(left),0,FALSE,FALSE);
3242                 MOVA(l);        
3243                 pic14_emitcode("div","ab");
3244                 aopPut(AOP(result),"a",0);
3245                 while (size--)
3246                         aopPut(AOP(result),zero,offset++);
3247                 return ;
3248         }
3249         
3250         /* signed is a little bit more difficult */
3251         
3252         /* save the signs of the operands */
3253         l = aopGet(AOP(left),0,FALSE,FALSE);    
3254         MOVA(l);    
3255         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3256         pic14_emitcode("push","acc"); /* save it on the stack */
3257         
3258         /* now sign adjust for both left & right */
3259         l =  aopGet(AOP(right),0,FALSE,FALSE);    
3260         MOVA(l);       
3261         lbl = newiTempLabel(NULL);
3262         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3263         pic14_emitcode("cpl","a");   
3264         pic14_emitcode("inc","a");
3265         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3266         pic14_emitcode("mov","b,a");
3267         
3268         /* sign adjust left side */
3269         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3270         MOVA(l);
3271         
3272         lbl = newiTempLabel(NULL);
3273         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3274         pic14_emitcode("cpl","a");
3275         pic14_emitcode("inc","a");
3276         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3277         
3278         /* now the division */
3279         pic14_emitcode("div","ab");
3280         /* we are interested in the lower order
3281         only */
3282         pic14_emitcode("mov","b,a");
3283         lbl = newiTempLabel(NULL);
3284         pic14_emitcode("pop","acc");   
3285         /* if there was an over flow we don't 
3286         adjust the sign of the result */
3287         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3288         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3289         CLRC;
3290         pic14_emitcode("clr","a");
3291         pic14_emitcode("subb","a,b");
3292         pic14_emitcode("mov","b,a");
3293         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3294         
3295         /* now we are done */
3296         aopPut(AOP(result),"b",0);
3297         if(size > 0){
3298                 pic14_emitcode("mov","c,b.7");
3299                 pic14_emitcode("subb","a,acc");   
3300         }
3301         while (size--)
3302                 aopPut(AOP(result),"a",offset++);
3303         
3304 }
3305
3306 /*-----------------------------------------------------------------*/
3307 /* genDiv - generates code for division                            */
3308 /*-----------------------------------------------------------------*/
3309 static void genDiv (iCode *ic)
3310 {
3311         operand *left = IC_LEFT(ic);
3312         operand *right = IC_RIGHT(ic);
3313         operand *result= IC_RESULT(ic);   
3314         
3315         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3316         /* assign the amsops */
3317         aopOp (left,ic,FALSE);
3318         aopOp (right,ic,FALSE);
3319         aopOp (result,ic,TRUE);
3320         
3321         /* special cases first */
3322         /* both are bits */
3323         if (AOP_TYPE(left) == AOP_CRY &&
3324                 AOP_TYPE(right)== AOP_CRY) {
3325                 genDivbits(left,right,result);
3326                 goto release ;
3327         }
3328         
3329         /* if both are of size == 1 */
3330         if (AOP_SIZE(left) == 1 &&
3331                 AOP_SIZE(right) == 1 ) {
3332                 genDivOneByte(left,right,result);
3333                 goto release ;
3334         }
3335         
3336         /* should have been converted to function call */
3337         assert(0);
3338 release :
3339         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3340         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3341         freeAsmop(result,NULL,ic,TRUE); 
3342 }
3343
3344 /*-----------------------------------------------------------------*/
3345 /* genModbits :- modulus of bits                                   */
3346 /*-----------------------------------------------------------------*/
3347 static void genModbits (operand *left, 
3348                                                 operand *right, 
3349                                                 operand *result)
3350 {
3351         
3352         char *l;
3353         
3354         /* the result must be bit */    
3355         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3356         l = aopGet(AOP(left),0,FALSE,FALSE);
3357         
3358         MOVA(l);       
3359         
3360         pic14_emitcode("div","ab");
3361         pic14_emitcode("mov","a,b");
3362         pic14_emitcode("rrc","a");
3363         aopPut(AOP(result),"c",0);
3364 }
3365
3366 /*-----------------------------------------------------------------*/
3367 /* genModOneByte : 8 bit modulus                                   */
3368 /*-----------------------------------------------------------------*/
3369 static void genModOneByte (operand *left,
3370                                                    operand *right,
3371                                                    operand *result)
3372 {
3373         sym_link *opetype = operandType(result);
3374         char *l ;
3375         symbol *lbl ;
3376         
3377         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3378         /* signed or unsigned */
3379         if (SPEC_USIGN(opetype)) {
3380                 /* unsigned is easy */
3381                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3382                 l = aopGet(AOP(left),0,FALSE,FALSE);
3383                 MOVA(l);    
3384                 pic14_emitcode("div","ab");
3385                 aopPut(AOP(result),"b",0);
3386                 return ;
3387         }
3388         
3389         /* signed is a little bit more difficult */
3390         
3391         /* save the signs of the operands */
3392         l = aopGet(AOP(left),0,FALSE,FALSE);    
3393         MOVA(l);
3394         
3395         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3396         pic14_emitcode("push","acc"); /* save it on the stack */
3397         
3398         /* now sign adjust for both left & right */
3399         l =  aopGet(AOP(right),0,FALSE,FALSE);    
3400         MOVA(l);
3401         
3402         lbl = newiTempLabel(NULL);
3403         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3404         pic14_emitcode("cpl","a");   
3405         pic14_emitcode("inc","a");
3406         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3407         pic14_emitcode("mov","b,a"); 
3408         
3409         /* sign adjust left side */
3410         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3411         MOVA(l);
3412         
3413         lbl = newiTempLabel(NULL);
3414         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415         pic14_emitcode("cpl","a");   
3416         pic14_emitcode("inc","a");
3417         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3418         
3419         /* now the multiplication */
3420         pic14_emitcode("div","ab");
3421         /* we are interested in the lower order
3422         only */
3423         lbl = newiTempLabel(NULL);
3424         pic14_emitcode("pop","acc");   
3425         /* if there was an over flow we don't 
3426         adjust the sign of the result */
3427         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3428         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3429         CLRC ;
3430         pic14_emitcode("clr","a");
3431         pic14_emitcode("subb","a,b");
3432         pic14_emitcode("mov","b,a");
3433         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3434         
3435         /* now we are done */
3436         aopPut(AOP(result),"b",0);
3437         
3438 }
3439
3440 /*-----------------------------------------------------------------*/
3441 /* genMod - generates code for division                            */
3442 /*-----------------------------------------------------------------*/
3443 static void genMod (iCode *ic)
3444 {
3445         operand *left = IC_LEFT(ic);
3446         operand *right = IC_RIGHT(ic);
3447         operand *result= IC_RESULT(ic);  
3448         
3449         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3450         /* assign the amsops */
3451         aopOp (left,ic,FALSE);
3452         aopOp (right,ic,FALSE);
3453         aopOp (result,ic,TRUE);
3454         
3455         /* special cases first */
3456         /* both are bits */
3457         if (AOP_TYPE(left) == AOP_CRY &&
3458                 AOP_TYPE(right)== AOP_CRY) {
3459                 genModbits(left,right,result);
3460                 goto release ;
3461         }
3462         
3463         /* if both are of size == 1 */
3464         if (AOP_SIZE(left) == 1 &&
3465                 AOP_SIZE(right) == 1 ) {
3466                 genModOneByte(left,right,result);
3467                 goto release ;
3468         }
3469         
3470         /* should have been converted to function call */
3471         assert(0);
3472         
3473 release :
3474         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3475         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3476         freeAsmop(result,NULL,ic,TRUE); 
3477 }
3478
3479 /*-----------------------------------------------------------------*/
3480 /* genIfxJump :- will create a jump depending on the ifx           */
3481 /*-----------------------------------------------------------------*/
3482 /*
3483 note: May need to add parameter to indicate when a variable is in bit space.
3484 */
3485 static void genIfxJump (iCode *ic, char *jval)
3486 {
3487         
3488         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3489         /* if true label then we jump if condition
3490         supplied is true */
3491         if ( IC_TRUE(ic) ) {
3492                 
3493                 if(strcmp(jval,"a") == 0)
3494                         emitSKPZ;
3495                 else if (strcmp(jval,"c") == 0)
3496                         emitSKPC;
3497                 else {
3498                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);   
3499                         emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3500                 }
3501                 
3502                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3503                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3504                 
3505         }
3506         else {
3507                 /* false label is present */
3508                 if(strcmp(jval,"a") == 0)
3509                         emitSKPNZ;
3510                 else if (strcmp(jval,"c") == 0)
3511                         emitSKPNC;
3512                 else {
3513                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);   
3514                         emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3515                 }
3516                 
3517                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3518                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3519                 
3520         }
3521         
3522         
3523         /* mark the icode as generated */
3524         ic->generated = 1;
3525 }
3526
3527 /*-----------------------------------------------------------------*/
3528 /* genSkip                                                         */
3529 /*-----------------------------------------------------------------*/
3530 static void genSkip(iCode *ifx,int status_bit)
3531 {
3532         if(!ifx)
3533                 return;
3534         
3535         if ( IC_TRUE(ifx) ) {
3536                 switch(status_bit) {
3537                 case 'z':
3538                         emitSKPNZ;
3539                         break;
3540                         
3541                 case 'c':
3542                         emitSKPNC;
3543                         break;
3544                         
3545                 case 'd':
3546                         emitSKPDC;
3547                         break;
3548                         
3549                 }
3550                 
3551                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3552                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3553                 
3554         } else {
3555                 
3556                 switch(status_bit) {
3557                         
3558                 case 'z':
3559                         emitSKPZ;
3560                         break;
3561                         
3562                 case 'c':
3563                         emitSKPC;
3564                         break;
3565                         
3566                 case 'd':
3567                         emitSKPDC;
3568                         break;
3569                 }
3570                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3571                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3572                 
3573         }
3574         
3575 }
3576
3577 /*-----------------------------------------------------------------*/
3578 /* genSkipc                                                        */
3579 /*-----------------------------------------------------------------*/
3580 static void genSkipc(resolvedIfx *rifx)
3581 {
3582         if(!rifx)
3583                 return;
3584         
3585         if(rifx->condition)
3586                 emitSKPC;
3587         else
3588                 emitSKPNC;
3589         
3590         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3591         rifx->generated = 1;
3592 }
3593
3594 /*-----------------------------------------------------------------*/
3595 /* genSkipz2                                                       */
3596 /*-----------------------------------------------------------------*/
3597 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3598 {
3599         if(!rifx)
3600                 return;
3601         
3602         if( (rifx->condition ^ invert_condition) & 1)
3603                 emitSKPZ;
3604         else
3605                 emitSKPNZ;
3606         
3607         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3608         rifx->generated = 1;
3609 }
3610
3611 /*-----------------------------------------------------------------*/
3612 /* genSkipz                                                        */
3613 /*-----------------------------------------------------------------*/
3614 static void genSkipz(iCode *ifx, int condition)
3615 {
3616         if(!ifx)
3617                 return;
3618         
3619         if(condition)
3620                 emitSKPNZ;
3621         else
3622                 emitSKPZ;
3623         
3624         if ( IC_TRUE(ifx) )
3625                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3626         else
3627                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3628         
3629         if ( IC_TRUE(ifx) )
3630                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3631         else
3632                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3633         
3634 }
3635 /*-----------------------------------------------------------------*/
3636 /* genSkipCond                                                     */
3637 /*-----------------------------------------------------------------*/
3638 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3639 {
3640         if(!rifx)
3641                 return;
3642         
3643         if(rifx->condition)
3644                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3645         else
3646                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3647         
3648         
3649         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3650         rifx->generated = 1;
3651 }
3652
3653 #if 0
3654 /*-----------------------------------------------------------------*/
3655 /* genChkZeroes :- greater or less than comparison                 */
3656 /*     For each byte in a literal that is zero, inclusive or the   */
3657 /*     the corresponding byte in the operand with W                */
3658 /*     returns true if any of the bytes are zero                   */
3659 /*-----------------------------------------------------------------*/
3660 static int genChkZeroes(operand *op, int lit,  int size)
3661 {
3662         
3663         int i;
3664         int flag =1;
3665         
3666         while(size--) {
3667                 i = (lit >> (size*8)) & 0xff;
3668                 
3669                 if(i==0) {
3670                         if(flag) 
3671                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3672                         else
3673                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3674                         flag = 0;
3675                 }
3676         }
3677         
3678         return (flag==0);
3679 }
3680 #endif
3681
3682 /*-----------------------------------------------------------------*/
3683 /* genCmp :- greater or less than comparison                       */
3684 /*-----------------------------------------------------------------*/
3685 static void genCmp (operand *left,operand *right,
3686                                         operand *result, iCode *ifx, int sign)
3687 {
3688         int size; //, offset = 0 ;
3689         unsigned long lit = 0L,i = 0;
3690         resolvedIfx rFalseIfx;
3691         //  resolvedIfx rTrueIfx;
3692         symbol *truelbl;
3693         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3694         /*
3695         if(ifx) {
3696         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3697         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3698         }
3699         */
3700         
3701         resolveIfx(&rFalseIfx,ifx);
3702         truelbl  = newiTempLabel(NULL);
3703         size = max(AOP_SIZE(left),AOP_SIZE(right));
3704         
3705         DEBUGpic14_AopType(__LINE__,left,right,result);
3706         
3707 #define _swapp
3708         
3709         /* if literal is on the right then swap with left */
3710         if ((AOP_TYPE(right) == AOP_LIT)) {
3711                 operand *tmp = right ;
3712                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3713                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3714 #ifdef _swapp
3715                 
3716                 lit = (lit - 1) & mask;
3717                 right = left;
3718                 left = tmp;
3719                 rFalseIfx.condition ^= 1;
3720 #endif
3721                 
3722         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3723                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3724         }
3725         
3726         
3727         //if(IC_TRUE(ifx) == NULL)
3728         /* if left & right are bit variables */
3729         if (AOP_TYPE(left) == AOP_CRY &&
3730                 AOP_TYPE(right) == AOP_CRY ) {
3731                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3732                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3733         } else {
3734         /* subtract right from left if at the
3735         end the carry flag is set then we know that
3736                 left is greater than right */
3737                 
3738                 //    {
3739                 
3740                 symbol *lbl  = newiTempLabel(NULL);
3741                 
3742 #ifndef _swapp
3743                 if(AOP_TYPE(right) == AOP_LIT) {
3744                         
3745                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3746                         
3747                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3748                         
3749                         /* special cases */
3750                         
3751                         if(lit == 0) {
3752                                 
3753                                 if(sign != 0) 
3754                                         genSkipCond(&rFalseIfx,left,size-1,7);
3755                                 else 
3756                                         /* no need to compare to 0...*/
3757                                         /* NOTE: this is a de-generate compare that most certainly 
3758                                         *       creates some dead code. */
3759                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3760                                 
3761                                 if(ifx) ifx->generated = 1;
3762                                 return;
3763                                 
3764                         }
3765                         size--;
3766                         
3767                         if(size == 0) {
3768                                 //i = (lit >> (size*8)) & 0xff;
3769                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3770                                 
3771                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3772                                 
3773                                 i = ((0-lit) & 0xff);
3774                                 if(sign) {
3775                                         if( i == 0x81) { 
3776                                         /* lit is 0x7f, all signed chars are less than
3777                                                 * this except for 0x7f itself */
3778                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3779                                                 genSkipz2(&rFalseIfx,0);
3780                                         } else {
3781                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3782                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3783                                                 genSkipc(&rFalseIfx);
3784                                         }
3785                                         
3786                                 } else {
3787                                         if(lit == 1) {
3788                                                 genSkipz2(&rFalseIfx,1);
3789                                         } else {
3790                                                 emitpcode(POC_ADDLW, popGetLit(i));
3791                                                 genSkipc(&rFalseIfx);
3792                                         }
3793                                 }
3794                                 
3795                                 if(ifx) ifx->generated = 1;
3796                                 return;
3797                         }
3798                         
3799                         /* chars are out of the way. now do ints and longs */
3800                         
3801                         
3802                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3803                         
3804                         /* special cases */
3805                         
3806                         if(sign) {
3807                                 
3808                                 if(lit == 0) {
3809                                         genSkipCond(&rFalseIfx,left,size,7);
3810                                         if(ifx) ifx->generated = 1;
3811                                         return;
3812                                 }
3813                                 
3814                                 if(lit <0x100) {
3815                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3816                                         
3817                                         //rFalseIfx.condition ^= 1;
3818                                         //genSkipCond(&rFalseIfx,left,size,7);
3819                                         //rFalseIfx.condition ^= 1;
3820                                         
3821                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3822                                         if(rFalseIfx.condition)
3823                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3824                                         else
3825                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3826                                         
3827                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3828                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3829                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3830                                         
3831                                         while(size > 1)
3832                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3833                                         
3834                                         if(rFalseIfx.condition) {
3835                                                 emitSKPZ;
3836                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3837                                                 
3838                                         } else {
3839                                                 emitSKPNZ;
3840                                         }
3841                                         
3842                                         genSkipc(&rFalseIfx);
3843                                         emitpLabel(truelbl->key);
3844                                         if(ifx) ifx->generated = 1;
3845                                         return;
3846                                         
3847                                 }
3848                                 
3849                                 if(size == 1) {
3850                                         
3851                                         if( (lit & 0xff) == 0) {
3852                                                 /* lower byte is zero */
3853                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3854                                                 i = ((lit >> 8) & 0xff) ^0x80;
3855                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3856                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3857                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3858                                                 genSkipc(&rFalseIfx);
3859                                                 
3860                                                 
3861                                                 if(ifx) ifx->generated = 1;
3862                                                 return;
3863                                                 
3864                                         }
3865                                 } else {
3866                                         /* Special cases for signed longs */
3867                                         if( (lit & 0xffffff) == 0) {
3868                                                 /* lower byte is zero */
3869                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3870                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3871                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3872                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3873                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3874                                                 genSkipc(&rFalseIfx);
3875                                                 
3876                                                 
3877                                                 if(ifx) ifx->generated = 1;
3878                                                 return;
3879                                                 
3880                                         }
3881                                         
3882                                 }
3883                                 
3884                                 
3885                                 if(lit & (0x80 << (size*8))) {
3886                                         /* lit is negative */
3887                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3888                                         
3889                                         //genSkipCond(&rFalseIfx,left,size,7);
3890                                         
3891                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3892                                         
3893                                         if(rFalseIfx.condition)
3894                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3895                                         else
3896                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3897                                         
3898                                         
3899                                 } else {
3900                                         /* lit is positive */
3901                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3902                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3903                                         if(rFalseIfx.condition)
3904                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3905                                         else
3906                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3907                                         
3908                                 }
3909                                 
3910                                 /* There are no more special cases, so perform a general compare */
3911                                 
3912                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3913                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3914                                 
3915                                 while(size--) {
3916                                         
3917                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3918                                         emitSKPNZ;
3919                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3920                                 }
3921                                 //rFalseIfx.condition ^= 1;
3922                                 genSkipc(&rFalseIfx);
3923                                 
3924                                 emitpLabel(truelbl->key);
3925                                 
3926                                 if(ifx) ifx->generated = 1;
3927                                 return;
3928                                 
3929                                 
3930           }
3931           
3932           
3933           /* sign is out of the way. So now do an unsigned compare */
3934           DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3935           
3936           
3937           /* General case - compare to an unsigned literal on the right.*/
3938           
3939           i = (lit >> (size*8)) & 0xff;
3940           emitpcode(POC_MOVLW, popGetLit(i));
3941           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3942           while(size--) {
3943                   i = (lit >> (size*8)) & 0xff;
3944                   
3945                   if(i) {
3946                           emitpcode(POC_MOVLW, popGetLit(i));
3947                           emitSKPNZ;
3948                           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3949                   } else {
3950                   /* this byte of the lit is zero, 
3951                           *if it's not the last then OR in the variable */
3952                           if(size)
3953                                   emitpcode(POC_IORFW, popGet(AOP(left),size));
3954                   }
3955           }
3956           
3957           
3958           emitpLabel(lbl->key);
3959           //if(emitFinalCheck)
3960           genSkipc(&rFalseIfx);
3961           if(sign)
3962                   emitpLabel(truelbl->key);
3963           
3964           if(ifx) ifx->generated = 1;
3965           return;
3966           
3967           
3968         }
3969 #endif  // _swapp
3970         
3971         if(AOP_TYPE(left) == AOP_LIT) {
3972                 //symbol *lbl = newiTempLabel(NULL);
3973                 
3974                 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3975                 
3976                 
3977                 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3978                 
3979                 /* Special cases */
3980                 if((lit == 0) && (sign == 0)){
3981                         
3982                         size--;
3983                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
3984                         while(size) 
3985                                 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3986                         
3987                         genSkipz2(&rFalseIfx,0);
3988                         if(ifx) ifx->generated = 1;
3989                         return;
3990                 }
3991                 
3992                 if(size==1) {
3993                         /* Special cases */
3994                         lit &= 0xff;
3995                         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3996                                 /* degenerate compare can never be true */
3997                                 if(rFalseIfx.condition == 0)
3998                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3999                                 
4000                                 if(ifx) ifx->generated = 1;
4001                                 return;
4002                         }
4003                         
4004                         if(sign) {
4005                                 /* signed comparisons to a literal byte */
4006                                 
4007                                 int lp1 = (lit+1) & 0xff;
4008                                 
4009                                 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4010                                 switch (lp1) {
4011                                 case 0:
4012                                         rFalseIfx.condition ^= 1;
4013                                         genSkipCond(&rFalseIfx,right,0,7);
4014                                         break;
4015                                 case 0x7f:
4016                                         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4017                                         emitpcode(POC_XORLW, popGetLit(0x7f));
4018                                         genSkipz2(&rFalseIfx,1);
4019                                         break;
4020                                 default:
4021                                         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4022                                         emitpcode(POC_ADDLW, popGetLit(0x80));
4023                                         emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4024                                         rFalseIfx.condition ^= 1;
4025                                         genSkipc(&rFalseIfx);
4026                                         break;
4027                                 }
4028                                 if(ifx) ifx->generated = 1;
4029                         } else {
4030                                 /* unsigned comparisons to a literal byte */
4031                                 
4032                                 switch(lit & 0xff ) {
4033                                 case 0:
4034                                         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4035                                         genSkipz2(&rFalseIfx,0);
4036                                         if(ifx) ifx->generated = 1;
4037                                         break;
4038                                 case 0x7f:
4039                                         genSkipCond(&rFalseIfx,right,0,7);
4040                                         if(ifx) ifx->generated = 1;
4041                                         break;
4042                                         
4043                                 default:
4044                                         emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4045                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4046                                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4047                                         rFalseIfx.condition ^= 1;
4048                                         if (AOP_TYPE(result) == AOP_CRY) {
4049                                                 genSkipc(&rFalseIfx);
4050                                                 if(ifx) ifx->generated = 1;
4051                                         } else {
4052                                                 DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4053                                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
4054                                                 emitpcode(POC_RLF, popGet(AOP(result),0));
4055                                                 emitpcode(POC_MOVLW, popGetLit(0x01));
4056                                                 emitpcode(POC_XORWF, popGet(AOP(result),0));
4057                                         }             
4058                                         break;
4059                                 }
4060                         }
4061                         
4062                         //goto check_carry;
4063                         return;
4064                         
4065                 } else {
4066                         
4067                         /* Size is greater than 1 */
4068                         
4069                         if(sign) {
4070                                 int lp1 = lit+1;
4071                                 
4072                                 size--;
4073                                 
4074                                 if(lp1 == 0) {
4075                                         /* this means lit = 0xffffffff, or -1 */
4076                                         
4077                                         
4078                                         DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4079                                         rFalseIfx.condition ^= 1;
4080                                         genSkipCond(&rFalseIfx,right,size,7);
4081                                         if(ifx) ifx->generated = 1;
4082                                         return;
4083                                 }
4084                                 
4085                                 if(lit == 0) {
4086                                         int s = size;
4087                                         
4088                                         if(rFalseIfx.condition) {
4089                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4090                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4091                                         }
4092                                         
4093                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4094                                         while(size--)
4095                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4096                                         
4097                                         
4098                                         emitSKPZ;
4099                                         if(rFalseIfx.condition) {
4100                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4101                                                 emitpLabel(truelbl->key);
4102                                         }else {
4103                                                 rFalseIfx.condition ^= 1;
4104                                                 genSkipCond(&rFalseIfx,right,s,7);
4105                                         }
4106                                         
4107                                         if(ifx) ifx->generated = 1;
4108                                         return;
4109                                 }
4110                                 
4111                                 if((size == 1) &&  (0 == (lp1&0xff))) {
4112                                         /* lower byte of signed word is zero */
4113                                         DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4114                                         i = ((lp1 >> 8) & 0xff) ^0x80;
4115                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4116                                         emitpcode(POC_ADDLW, popGetLit( 0x80));
4117                                         emitpcode(POC_ADDLW, popGetLit(0x100-i));
4118                                         rFalseIfx.condition ^= 1;
4119                                         genSkipc(&rFalseIfx);
4120                                         
4121                                         
4122                                         if(ifx) ifx->generated = 1;
4123                                         return;
4124                                 }
4125                                 
4126                                 if(lit & (0x80 << (size*8))) {
4127                                         /* Lit is less than zero */
4128                                         DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4129                                         //rFalseIfx.condition ^= 1;
4130                                         //genSkipCond(&rFalseIfx,left,size,7);
4131                                         //rFalseIfx.condition ^= 1;
4132                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133                                         //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4134                                         
4135                                         if(rFalseIfx.condition)
4136                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4137                                         else
4138                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4139                                         
4140                                         
4141                                 } else {
4142                                         /* Lit is greater than or equal to zero */
4143                                         DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4144                                         //rFalseIfx.condition ^= 1;
4145                                         //genSkipCond(&rFalseIfx,right,size,7);
4146                                         //rFalseIfx.condition ^= 1;
4147                                         
4148                                         //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4149                                         //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4150                                         
4151                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152                                         if(rFalseIfx.condition)
4153                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4154                                         else
4155                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4156                                         
4157                                 }
4158                                 
4159                                 
4160                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4161                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4162                                 
4163                                 while(size--) {
4164                                         
4165                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4166                                         emitSKPNZ;
4167                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4168                                 }
4169                                 rFalseIfx.condition ^= 1;
4170                                 //rFalseIfx.condition = 1;
4171                                 genSkipc(&rFalseIfx);
4172                                 
4173                                 emitpLabel(truelbl->key);
4174                                 
4175                                 if(ifx) ifx->generated = 1;
4176                                 return;
4177                                 // end of if (sign)
4178         } else {
4179                 
4180                 /* compare word or long to an unsigned literal on the right.*/
4181                 
4182                 
4183                 size--;
4184                 if(lit < 0xff) {
4185                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4186                         switch (lit) {
4187                         case 0:
4188                                 break; /* handled above */
4189                         /*
4190                         case 0xff:
4191                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4192                         while(size--)
4193                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4194                         genSkipz2(&rFalseIfx,0);
4195                         break;
4196                         */
4197                         default:
4198                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4199                                 while(--size)
4200                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4201                                 
4202                                 emitSKPZ;
4203                                 if(rFalseIfx.condition)
4204                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4205                                 else
4206                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4207                                 
4208                                 
4209                                 emitpcode(POC_MOVLW, popGetLit(lit+1));
4210                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4211                                 
4212                                 rFalseIfx.condition ^= 1;
4213                                 genSkipc(&rFalseIfx);
4214                         }
4215                         
4216                         emitpLabel(truelbl->key);
4217                         
4218                         if(ifx) ifx->generated = 1;
4219                         return;
4220                 }
4221                 
4222                 
4223                 lit++;
4224                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4225                 i = (lit >> (size*8)) & 0xff;
4226                 
4227                 emitpcode(POC_MOVLW, popGetLit(i));
4228                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4229                 
4230                 while(size--) {
4231                         i = (lit >> (size*8)) & 0xff;
4232                         
4233                         if(i) {
4234                                 emitpcode(POC_MOVLW, popGetLit(i));
4235                                 emitSKPNZ;
4236                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4237                         } else {
4238                         /* this byte of the lit is zero, 
4239                                 *if it's not the last then OR in the variable */
4240                                 if(size)
4241                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4242                         }
4243                 }
4244                 
4245                 
4246                 emitpLabel(lbl->key);
4247                 
4248                 rFalseIfx.condition ^= 1;
4249                 genSkipc(&rFalseIfx);
4250         }
4251         
4252         if(sign)
4253                 emitpLabel(truelbl->key);
4254         if(ifx) ifx->generated = 1;
4255         return;
4256           }
4257         }
4258         /* Compare two variables */
4259         
4260         DEBUGpic14_emitcode(";sign","%d",sign);
4261         
4262         size--;
4263         if(sign) {
4264                 /* Sigh. thus sucks... */
4265                 if(size) {
4266                         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4267                         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4268                         emitpcode(POC_MOVLW, popGetLit(0x80));
4269                         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4270                         emitpcode(POC_XORFW, popGet(AOP(right),size));
4271                         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4272                 } else {
4273                         /* Signed char comparison */
4274                         /* Special thanks to Nikolai Golovchenko for this snippet */
4275                         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4276                         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4277                         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4278                         emitpcode(POC_XORFW, popGet(AOP(left),0));
4279                         emitpcode(POC_XORFW, popGet(AOP(right),0));
4280                         emitpcode(POC_ADDLW, popGetLit(0x80));
4281                         
4282                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4283                         genSkipc(&rFalseIfx);
4284                         
4285                         if(ifx) ifx->generated = 1;
4286                         return;
4287                 }
4288                 
4289         } else {
4290                 
4291                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4292                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4293         }
4294         
4295         
4296         /* The rest of the bytes of a multi-byte compare */
4297         while (size) {
4298                 
4299                 emitSKPZ;
4300                 emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4301                 size--;
4302                 
4303                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4304                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4305                 
4306                 
4307         }
4308         
4309         emitpLabel(lbl->key);
4310         
4311         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4312         if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4313                 (AOP_TYPE(result) == AOP_REG)) {
4314                 emitpcode(POC_CLRF, popGet(AOP(result),0));
4315                 emitpcode(POC_RLF, popGet(AOP(result),0));
4316         } else {
4317                 genSkipc(&rFalseIfx);
4318         }             
4319         //genSkipc(&rFalseIfx);
4320         if(ifx) ifx->generated = 1;
4321         
4322         return;
4323         
4324   }
4325   
4326   // check_carry:
4327   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4328           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4329           pic14_outBitC(result);
4330   } else {
4331           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4332           /* if the result is used in the next
4333           ifx conditional branch then generate
4334           code a little differently */
4335           if (ifx )
4336                   genIfxJump (ifx,"c");
4337           else
4338                   pic14_outBitC(result);
4339           /* leave the result in acc */
4340   }
4341   
4342 }
4343
4344 /*-----------------------------------------------------------------*/
4345 /* genCmpGt :- greater than comparison                             */
4346 /*-----------------------------------------------------------------*/
4347 static void genCmpGt (iCode *ic, iCode *ifx)
4348 {
4349         operand *left, *right, *result;
4350         sym_link *letype , *retype;
4351         int sign ;
4352         
4353         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4354         left = IC_LEFT(ic);
4355         right= IC_RIGHT(ic);
4356         result = IC_RESULT(ic);
4357         
4358         letype = getSpec(operandType(left));
4359         retype =getSpec(operandType(right));
4360         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4361         /* assign the amsops */
4362         aopOp (left,ic,FALSE);
4363         aopOp (right,ic,FALSE);
4364         aopOp (result,ic,TRUE);
4365         
4366         genCmp(right, left, result, ifx, sign);
4367         
4368         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4369         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4370         freeAsmop(result,NULL,ic,TRUE); 
4371 }
4372
4373 /*-----------------------------------------------------------------*/
4374 /* genCmpLt - less than comparisons                                */
4375 /*-----------------------------------------------------------------*/
4376 static void genCmpLt (iCode *ic, iCode *ifx)
4377 {
4378         operand *left, *right, *result;
4379         sym_link *letype , *retype;
4380         int sign ;
4381         
4382         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4383         left = IC_LEFT(ic);
4384         right= IC_RIGHT(ic);
4385         result = IC_RESULT(ic);
4386         
4387         letype = getSpec(operandType(left));
4388         retype =getSpec(operandType(right));
4389         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4390         
4391         /* assign the amsops */
4392         aopOp (left,ic,FALSE);
4393         aopOp (right,ic,FALSE);
4394         aopOp (result,ic,TRUE);
4395         
4396         genCmp(left, right, result, ifx, sign);
4397         
4398         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4399         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4400         freeAsmop(result,NULL,ic,TRUE); 
4401 }
4402
4403 /*-----------------------------------------------------------------*/
4404 /* genc16bit2lit - compare a 16 bit value to a literal             */
4405 /*-----------------------------------------------------------------*/
4406 static void genc16bit2lit(operand *op, int lit, int offset)
4407 {
4408         int i;
4409         
4410         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4411         if( (lit&0xff) == 0) 
4412                 i=1;
4413         else
4414                 i=0;
4415         
4416         switch( BYTEofLONG(lit,i)) { 
4417         case 0:
4418                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4419                 break;
4420         case 1:
4421                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4422                 break;
4423         case 0xff:
4424                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4425                 break;
4426         default:
4427                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4428                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4429         }
4430         
4431         i ^= 1;
4432         
4433         switch( BYTEofLONG(lit,i)) { 
4434         case 0:
4435                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4436                 break;
4437         case 1:
4438                 emitSKPNZ;
4439                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4440                 break;
4441         case 0xff:
4442                 emitSKPNZ;
4443                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4444                 break;
4445         default:
4446                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4447                 emitSKPNZ;
4448                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4449                 
4450         }
4451         
4452 }
4453
4454 /*-----------------------------------------------------------------*/
4455 /* gencjneshort - compare and jump if not equal                    */
4456 /*-----------------------------------------------------------------*/
4457 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4458 {
4459         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4460         int offset = 0;
4461         int res_offset = 0;  /* the result may be a different size then left or right */
4462         int res_size = AOP_SIZE(result);
4463         resolvedIfx rIfx;
4464         symbol *lbl;
4465         
4466         unsigned long lit = 0L;
4467         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4468         DEBUGpic14_AopType(__LINE__,left,right,result);
4469         if(result)
4470                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4471         resolveIfx(&rIfx,ifx);
4472         lbl =  newiTempLabel(NULL);
4473         
4474         
4475         /* if the left side is a literal or 
4476         if the right is in a pointer register and left 
4477         is not */
4478         if ((AOP_TYPE(left) == AOP_LIT) || 
4479                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4480                 operand *t = right;
4481                 right = left;
4482                 left = t;
4483         }
4484         if(AOP_TYPE(right) == AOP_LIT)
4485                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4486         
4487         /* if the right side is a literal then anything goes */
4488         if (AOP_TYPE(right) == AOP_LIT &&
4489                 AOP_TYPE(left) != AOP_DIR ) {
4490                 switch(size) {
4491                 case 2:
4492                         genc16bit2lit(left, lit, 0);
4493                         emitSKPNZ;
4494                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4495                         break;
4496                 default:
4497                         while (size--) {
4498                                 if(lit & 0xff) {
4499                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4500                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4501                                 } else {
4502                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4503                                 }
4504                                 
4505                                 emitSKPNZ;
4506                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4507                                 offset++;
4508                                 if(res_offset < res_size-1)
4509                                         res_offset++;
4510                                 lit >>= 8;
4511                         }
4512                         break;
4513                 }
4514         }
4515         
4516         /* if the right side is in a register or in direct space or
4517         if the left is a pointer register & right is not */    
4518         else if (AOP_TYPE(right) == AOP_REG ||
4519                 AOP_TYPE(right) == AOP_DIR || 
4520                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4521                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4522                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4523                 int lbl_key = lbl->key;
4524                 
4525                 if(result) {
4526                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4527                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4528                 }else {
4529                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4530                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4531                                 __FUNCTION__,__LINE__);
4532                         return;
4533                 }
4534                 
4535                 /*     switch(size) { */
4536                 /*     case 2: */
4537                 /*       genc16bit2lit(left, lit, 0); */
4538                 /*       emitSKPNZ; */
4539                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4540                 /*       break; */
4541                 /*     default: */
4542                 while (size--) {
4543                         int emit_skip=1;
4544                         if((AOP_TYPE(left) == AOP_DIR) && 
4545                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4546                                 
4547                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4548                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4549                                 
4550                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4551                                 
4552                                 switch (lit & 0xff) {
4553                                 case 0:
4554                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4555                                         break;
4556                                 case 1:
4557                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4558                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4559                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4560                                         emit_skip=0;
4561                                         break;
4562                                 case 0xff:
4563                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4564                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4565                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4566                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4567                                         emit_skip=0;
4568                                         break;
4569                                 default:
4570                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4572                                 }
4573                                 lit >>= 8;
4574                                 
4575                         } else {
4576                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4577                         }
4578                         if(emit_skip) {
4579                                 if(AOP_TYPE(result) == AOP_CRY) {
4580                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4581                                         if(rIfx.condition)
4582                                                 emitSKPNZ;
4583                                         else
4584                                                 emitSKPZ;
4585                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4586                                 } else {
4587                                         /* fix me. probably need to check result size too */
4588                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4589                                         if(rIfx.condition)
4590                                                 emitSKPZ;
4591                                         else
4592                                                 emitSKPNZ;
4593                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4594                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4595                                 }
4596                                 if(ifx)
4597                                         ifx->generated=1;
4598                         }
4599                         emit_skip++;
4600                         offset++;
4601                         if(res_offset < res_size-1)
4602                                 res_offset++;
4603                 }
4604                 /*       break; */
4605                 /*     } */
4606         } else if(AOP_TYPE(right) == AOP_REG &&
4607                 AOP_TYPE(left) != AOP_DIR){
4608                 
4609                 while(size--) {
4610                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4611                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4612                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4613                         if(rIfx.condition)
4614                                 emitSKPNZ;
4615                         else
4616                                 emitSKPZ;
4617                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4618                         offset++;
4619                         if(res_offset < res_size-1)
4620                                 res_offset++;
4621                 }
4622                 
4623         }else{
4624                 /* right is a pointer reg need both a & b */
4625                 while(size--) {
4626                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4627                         if(strcmp(l,"b"))
4628                                 pic14_emitcode("mov","b,%s",l);
4629                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4630                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4631                         offset++;
4632                 }
4633         }
4634         
4635         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636         if(!rIfx.condition)
4637                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4638         
4639         emitpLabel(lbl->key);
4640         
4641         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4642         
4643         if(ifx)
4644                 ifx->generated = 1;
4645 }
4646
4647 #if 0
4648 /*-----------------------------------------------------------------*/
4649 /* gencjne - compare and jump if not equal                         */
4650 /*-----------------------------------------------------------------*/
4651 static void gencjne(operand *left, operand *right, iCode *ifx)
4652 {
4653         symbol *tlbl  = newiTempLabel(NULL);
4654         
4655         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4656         gencjneshort(left, right, lbl);
4657         
4658         pic14_emitcode("mov","a,%s",one);
4659         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4660         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4661         pic14_emitcode("clr","a");
4662         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4663         
4664         emitpLabel(lbl->key);
4665         emitpLabel(tlbl->key);
4666         
4667 }
4668 #endif
4669
4670 /*-----------------------------------------------------------------*/
4671 /* genCmpEq - generates code for equal to                          */
4672 /*-----------------------------------------------------------------*/
4673 static void genCmpEq (iCode *ic, iCode *ifx)
4674 {
4675         operand *left, *right, *result;
4676         unsigned long lit = 0L;
4677         int size,offset=0;
4678         
4679         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4680         
4681         if(ifx)
4682                 DEBUGpic14_emitcode ("; ifx is non-null","");
4683         else
4684                 DEBUGpic14_emitcode ("; ifx is null","");
4685         
4686         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4687         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4688         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4689         
4690         size = max(AOP_SIZE(left),AOP_SIZE(right));
4691         
4692         DEBUGpic14_AopType(__LINE__,left,right,result);
4693         
4694         /* if literal, literal on the right or 
4695         if the right is in a pointer register and left 
4696         is not */
4697         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4698                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4699                 operand *tmp = right ;
4700                 right = left;
4701                 left = tmp;
4702         }
4703         
4704         
4705         if(ifx && !AOP_SIZE(result)){
4706                 symbol *tlbl;
4707                 /* if they are both bit variables */
4708                 if (AOP_TYPE(left) == AOP_CRY &&
4709                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4710                         if(AOP_TYPE(right) == AOP_LIT){
4711                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4712                                 if(lit == 0L){
4713                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4714                                         pic14_emitcode("cpl","c");
4715                                 } else if(lit == 1L) {
4716                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4717                                 } else {
4718                                         pic14_emitcode("clr","c");
4719                                 }
4720                                 /* AOP_TYPE(right) == AOP_CRY */
4721                         } else {
4722                                 symbol *lbl = newiTempLabel(NULL);
4723                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4724                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4725                                 pic14_emitcode("cpl","c");
4726                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4727                         }
4728                         /* if true label then we jump if condition
4729                         supplied is true */
4730                         tlbl = newiTempLabel(NULL);
4731                         if ( IC_TRUE(ifx) ) {
4732                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4733                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4734                         } else {
4735                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4736                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4737                         }
4738                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4739                         
4740                         {
4741                                 /* left and right are both bit variables, result is carry */
4742                                 resolvedIfx rIfx;
4743                                 
4744                                 resolveIfx(&rIfx,ifx);
4745                                 
4746                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4747                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4748                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4749                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4750                                 genSkipz2(&rIfx,0);
4751                         }
4752                 } else {
4753                         
4754                         /* They're not both bit variables. Is the right a literal? */
4755                         if(AOP_TYPE(right) == AOP_LIT) {
4756                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4757                                 
4758                                 switch(size) {
4759                                         
4760                                 case 1:
4761                                         switch(lit & 0xff) {
4762                                         case 1:
4763                                                 if ( IC_TRUE(ifx) ) {
4764                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4765                                                         emitSKPNZ;
4766                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4767                                                 } else {
4768                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4769                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4770                                                 }
4771                                                 break;
4772                                         case 0xff:
4773                                                 if ( IC_TRUE(ifx) ) {
4774                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4775                                                         emitSKPNZ;
4776                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4777                                                 } else {
4778                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4779                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4780                                                 }
4781                                                 break;
4782                                         default:
4783                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4784                                                 if(lit)
4785                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4786                                                 genSkip(ifx,'z');
4787                                         }
4788                                         
4789                                         
4790                                         /* end of size == 1 */
4791                                         break;
4792                                         
4793                                         case 2:
4794                                                 genc16bit2lit(left,lit,offset);
4795                                                 genSkip(ifx,'z');
4796                                                 break;
4797                                                 /* end of size == 2 */
4798                                                 
4799                                         default:
4800                                                 /* size is 4 */
4801                                                 if(lit==0) {
4802                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4803                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4804                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4805                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4806                                                         
4807                                                 } else {
4808                                                         
4809                                                         /* search for patterns that can be optimized */
4810                                                         
4811                                                         genc16bit2lit(left,lit,0);
4812                                                         lit >>= 16;
4813                                                         if(lit) {
4814                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4815                                                                 //genSkip(ifx,'z');
4816                                                                 genc16bit2lit(left,lit,2);
4817                                                         } else {
4818                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4819                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4820                                                                 
4821                                                         }
4822                                                         
4823                                                 }
4824                                                 
4825                                                 genSkip(ifx,'z');
4826                                 }
4827                                 
4828                                 ifx->generated = 1;
4829                                 goto release ;
4830                                 
4831                                 
4832                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4833                                 /* we know the left is not a bit, but that the right is */
4834                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4835                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4836                                         popGet(AOP(right),offset));
4837                                 emitpcode(POC_XORLW,popGetLit(1));
4838                                 
4839                                 /* if the two are equal, then W will be 0 and the Z bit is set
4840                                 * we could test Z now, or go ahead and check the high order bytes if
4841                                 * the variable we're comparing is larger than a byte. */
4842                                 
4843                                 while(--size)
4844                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4845                                 
4846                                 if ( IC_TRUE(ifx) ) {
4847                                         emitSKPNZ;
4848                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4849                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4850                                 } else {
4851                                         emitSKPZ;
4852                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4853                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4854                                 }
4855                                 
4856                         } else {
4857                                 /* They're both variables that are larger than bits */
4858                                 int s = size;
4859                                 
4860                                 tlbl = newiTempLabel(NULL);
4861                                 
4862                                 while(size--) {
4863                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4864                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4865                                         
4866                                         if ( IC_TRUE(ifx) ) {
4867                                                 if(size) {
4868                                                         emitSKPZ;
4869                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4870                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4871                                                 } else {
4872                                                         emitSKPNZ;
4873                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4874                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4875                                                 }
4876                                         } else {
4877                                                 emitSKPZ;
4878                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4879                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4880                                         }
4881                                         offset++;
4882                                 }
4883                                 if(s>1 && IC_TRUE(ifx)) {
4884                                         emitpLabel(tlbl->key);
4885                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4886                                 }
4887                         }
4888                 }
4889                 /* mark the icode as generated */
4890                 ifx->generated = 1;
4891                 goto release ;
4892         }
4893         
4894         /* if they are both bit variables */
4895         if (AOP_TYPE(left) == AOP_CRY &&
4896                 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4897                 if(AOP_TYPE(right) == AOP_LIT){
4898                         unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4899                         if(lit == 0L){
4900                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4901                                 pic14_emitcode("cpl","c");
4902                         } else if(lit == 1L) {
4903                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4904                         } else {
4905                                 pic14_emitcode("clr","c");
4906                         }
4907                         /* AOP_TYPE(right) == AOP_CRY */
4908                 } else {
4909                         symbol *lbl = newiTempLabel(NULL);
4910                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4911                         pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4912                         pic14_emitcode("cpl","c");
4913                         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4914                 }
4915                 /* c = 1 if egal */
4916                 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4917                         pic14_outBitC(result);
4918                         goto release ;
4919                 }
4920                 if (ifx) {
4921                         genIfxJump (ifx,"c");
4922                         goto release ;
4923                 }
4924                 /* if the result is used in an arithmetic operation
4925                 then put the result in place */
4926                 pic14_outBitC(result);
4927         } else {
4928                 
4929                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4930                 gencjne(left,right,result,ifx);
4931                 /*
4932                 if(ifx) 
4933                 gencjne(left,right,newiTempLabel(NULL));
4934                 else {
4935                 if(IC_TRUE(ifx)->key)
4936                 gencjne(left,right,IC_TRUE(ifx)->key);
4937                 else
4938                 gencjne(left,right,IC_FALSE(ifx)->key);
4939                 ifx->generated = 1;
4940                 goto release ;
4941                 }
4942                 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4943                 aopPut(AOP(result),"a",0);
4944                 goto release ;
4945                 }
4946                 
4947                   if (ifx) {
4948                   genIfxJump (ifx,"a");
4949                   goto release ;
4950                   }
4951                 */
4952                 /* if the result is used in an arithmetic operation
4953                 then put the result in place */
4954                 /*
4955                 if (AOP_TYPE(result) != AOP_CRY) 
4956                 pic14_outAcc(result);
4957                 */
4958                 /* leave the result in acc */
4959         }
4960         
4961 release:
4962         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4963         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4964         freeAsmop(result,NULL,ic,TRUE);
4965 }
4966
4967 /*-----------------------------------------------------------------*/
4968 /* ifxForOp - returns the icode containing the ifx for operand     */
4969 /*-----------------------------------------------------------------*/
4970 static iCode *ifxForOp ( operand *op, iCode *ic )
4971 {
4972         /* if true symbol then needs to be assigned */
4973         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4974         if (IS_TRUE_SYMOP(op))
4975                 return NULL ;
4976         
4977                 /* if this has register type condition and
4978                 the next instruction is ifx with the same operand
4979         and live to of the operand is upto the ifx only then */
4980         if (ic->next &&
4981                 ic->next->op == IFX &&
4982                 IC_COND(ic->next)->key == op->key &&
4983                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4984                 return ic->next;
4985         
4986         if (ic->next &&
4987                 ic->next->op == IFX &&
4988                 IC_COND(ic->next)->key == op->key) {
4989                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4990                 return ic->next;
4991         }
4992         
4993         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4994         if (ic->next &&
4995                 ic->next->op == IFX)
4996                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4997         
4998         if (ic->next &&
4999                 ic->next->op == IFX &&
5000                 IC_COND(ic->next)->key == op->key) {
5001                 DEBUGpic14_emitcode ("; "," key is okay");
5002                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5003                         OP_SYMBOL(op)->liveTo,
5004                         ic->next->seq);
5005         }
5006         
5007         
5008         return NULL;
5009 }
5010 /*-----------------------------------------------------------------*/
5011 /* genAndOp - for && operation                                     */
5012 /*-----------------------------------------------------------------*/
5013 static void genAndOp (iCode *ic)
5014 {
5015         operand *left,*right, *result;
5016         /*     symbol *tlbl; */
5017         
5018         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5019         /* note here that && operations that are in an
5020         if statement are taken away by backPatchLabels
5021         only those used in arthmetic operations remain */
5022         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5023         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5024         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5025         
5026         DEBUGpic14_AopType(__LINE__,left,right,result);
5027         
5028         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5029         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5030         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5031         
5032         /* if both are bit variables */
5033         /*     if (AOP_TYPE(left) == AOP_CRY && */
5034         /*         AOP_TYPE(right) == AOP_CRY ) { */
5035         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5036         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5037         /*         pic14_outBitC(result); */
5038         /*     } else { */
5039         /*         tlbl = newiTempLabel(NULL); */
5040         /*         pic14_toBoolean(left);     */
5041         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5042         /*         pic14_toBoolean(right); */
5043         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5044         /*         pic14_outBitAcc(result); */
5045         /*     } */
5046         
5047         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5048         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5049         freeAsmop(result,NULL,ic,TRUE);
5050 }
5051
5052
5053 /*-----------------------------------------------------------------*/
5054 /* genOrOp - for || operation                                      */
5055 /*-----------------------------------------------------------------*/
5056 /*
5057 tsd pic port -
5058 modified this code, but it doesn't appear to ever get called
5059 */
5060
5061 static void genOrOp (iCode *ic)
5062 {
5063         operand *left,*right, *result;
5064         symbol *tlbl;
5065         
5066         /* note here that || operations that are in an
5067         if statement are taken away by backPatchLabels
5068         only those used in arthmetic operations remain */
5069         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5070         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5071         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5072         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5073         
5074         DEBUGpic14_AopType(__LINE__,left,right,result);
5075         
5076         /* if both are bit variables */
5077         if (AOP_TYPE(left) == AOP_CRY &&
5078                 AOP_TYPE(right) == AOP_CRY ) {
5079                 pic14_emitcode("clrc","");
5080                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5081                         AOP(left)->aopu.aop_dir,
5082                         AOP(left)->aopu.aop_dir);
5083                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5084                         AOP(right)->aopu.aop_dir,
5085                         AOP(right)->aopu.aop_dir);
5086                 pic14_emitcode("setc","");
5087                 
5088         } else {
5089                 tlbl = newiTempLabel(NULL);
5090                 pic14_toBoolean(left);
5091                 emitSKPZ;
5092                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5093                 pic14_toBoolean(right);
5094                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5095                 
5096                 pic14_outBitAcc(result);
5097         }
5098         
5099         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5100         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5101         freeAsmop(result,NULL,ic,TRUE);            
5102 }
5103
5104 /*-----------------------------------------------------------------*/
5105 /* isLiteralBit - test if lit == 2^n                               */
5106 /*-----------------------------------------------------------------*/
5107 static int isLiteralBit(unsigned long lit)
5108 {
5109         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5110                 0x100L,0x200L,0x400L,0x800L,
5111                 0x1000L,0x2000L,0x4000L,0x8000L,
5112                 0x10000L,0x20000L,0x40000L,0x80000L,
5113                 0x100000L,0x200000L,0x400000L,0x800000L,
5114                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5115                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5116         int idx;
5117         
5118         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5119         for(idx = 0; idx < 32; idx++)
5120                 if(lit == pw[idx])
5121                         return idx+1;
5122                 return 0;
5123 }
5124
5125 /*-----------------------------------------------------------------*/
5126 /* continueIfTrue -                                                */
5127 /*-----------------------------------------------------------------*/
5128 static void continueIfTrue (iCode *ic)
5129 {
5130         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5131         if(IC_TRUE(ic))
5132                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5133         ic->generated = 1;
5134 }
5135
5136 /*-----------------------------------------------------------------*/
5137 /* jmpIfTrue -                                                     */
5138 /*-----------------------------------------------------------------*/
5139 static void jumpIfTrue (iCode *ic)
5140 {
5141         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5142         if(!IC_TRUE(ic))
5143                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5144         ic->generated = 1;
5145 }
5146
5147 /*-----------------------------------------------------------------*/
5148 /* jmpTrueOrFalse -                                                */
5149 /*-----------------------------------------------------------------*/
5150 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5151 {
5152         // ugly but optimized by peephole
5153         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5154         if(IC_TRUE(ic)){
5155                 symbol *nlbl = newiTempLabel(NULL);
5156                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5157                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5158                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5159                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5160         }
5161         else{
5162                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5163                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5164         }
5165         ic->generated = 1;
5166 }
5167
5168 /*-----------------------------------------------------------------*/
5169 /* genAnd  - code for and                                          */
5170 /*-----------------------------------------------------------------*/
5171 static void genAnd (iCode *ic, iCode *ifx)
5172 {
5173         operand *left, *right, *result;
5174         int size, offset=0;  
5175         unsigned long lit = 0L;
5176         int bytelit = 0;
5177         resolvedIfx rIfx;
5178         
5179         
5180         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5181         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5182         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5183         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5184         
5185         resolveIfx(&rIfx,ifx);
5186         
5187         /* if left is a literal & right is not then exchange them */
5188         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5189                 AOP_NEEDSACC(left)) {
5190                 operand *tmp = right ;
5191                 right = left;
5192                 left = tmp;
5193         }
5194         
5195         /* if result = right then exchange them */
5196         if(pic14_sameRegs(AOP(result),AOP(right))){
5197                 operand *tmp = right ;
5198                 right = left;
5199                 left = tmp;
5200         }
5201         
5202         /* if right is bit then exchange them */
5203         if (AOP_TYPE(right) == AOP_CRY &&
5204                 AOP_TYPE(left) != AOP_CRY){
5205                 operand *tmp = right ;
5206                 right = left;
5207                 left = tmp;
5208         }
5209         if(AOP_TYPE(right) == AOP_LIT)
5210                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5211         
5212         size = AOP_SIZE(result);
5213         
5214         DEBUGpic14_AopType(__LINE__,left,right,result);
5215         
5216         // if(bit & yy)
5217         // result = bit & yy;
5218         if (AOP_TYPE(left) == AOP_CRY){
5219                 // c = bit & literal;
5220                 if(AOP_TYPE(right) == AOP_LIT){
5221                         if(lit & 1) {
5222                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5223                                         // no change
5224                                         goto release;
5225                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5226                         } else {
5227                                 // bit(result) = 0;
5228                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5229                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5230                                         goto release;
5231                                 }
5232                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5233                                         jumpIfTrue(ifx);
5234                                         goto release;
5235                                 }
5236                                 pic14_emitcode("clr","c");
5237                         }
5238                 } else {
5239                         if (AOP_TYPE(right) == AOP_CRY){
5240                                 // c = bit & bit;
5241                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5242                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5243                         } else {
5244                                 // c = bit & val;
5245                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5246                                 // c = lsb
5247                                 pic14_emitcode("rrc","a");
5248                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5249                         }
5250                 }
5251                 // bit = c
5252                 // val = c
5253                 if(size)
5254                         pic14_outBitC(result);
5255                 // if(bit & ...)
5256                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5257                         genIfxJump(ifx, "c");           
5258                 goto release ;
5259         }
5260         
5261         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5262         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5263         if((AOP_TYPE(right) == AOP_LIT) &&
5264                 (AOP_TYPE(result) == AOP_CRY) &&
5265                 (AOP_TYPE(left) != AOP_CRY)){
5266                 int posbit = isLiteralBit(lit);
5267                 /* left &  2^n */
5268                 if(posbit){
5269                         posbit--;
5270                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5271                         // bit = left & 2^n
5272                         if(size)
5273                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5274                         // if(left &  2^n)
5275                         else{
5276                                 if(ifx){
5277                                         int offset = 0;
5278                                         while (posbit > 7) {
5279                                                 posbit -= 8;
5280                                                 offset++;
5281                                         }
5282                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5283                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5284                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5285                                         
5286                                         ifx->generated = 1;
5287                                 }
5288                                 goto release;
5289                         }
5290                 } else {
5291                         symbol *tlbl = newiTempLabel(NULL);
5292                         int sizel = AOP_SIZE(left);
5293                         if(size)
5294                                 pic14_emitcode("setb","c");
5295                         while(sizel--){
5296                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5297                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5298                                         // byte ==  2^n ?
5299                                         if((posbit = isLiteralBit(bytelit)) != 0)
5300                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5301                                         else{
5302                                                 if(bytelit != 0x0FFL)
5303                                                         pic14_emitcode("anl","a,%s",
5304                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5305                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5306                                         }
5307                                 }
5308                                 offset++;
5309                         }
5310                         // bit = left & literal
5311                         if(size){
5312                                 pic14_emitcode("clr","c");
5313                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5314                         }
5315                         // if(left & literal)
5316                         else{
5317                                 if(ifx)
5318                                         jmpTrueOrFalse(ifx, tlbl);
5319                                 goto release ;
5320                         }
5321                 }
5322                 pic14_outBitC(result);
5323                 goto release ;
5324         }
5325         
5326         /* if left is same as result */
5327         if(pic14_sameRegs(AOP(result),AOP(left))){
5328                 int know_W = -1;
5329                 for(;size--; offset++,lit>>=8) {
5330                         if(AOP_TYPE(right) == AOP_LIT){
5331                                 switch(lit & 0xff) {
5332                                 case 0x00:
5333                                         /*  and'ing with 0 has clears the result */
5334                                         pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5335                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5336                                         break;
5337                                 case 0xff:
5338                                         /* and'ing with 0xff is a nop when the result and left are the same */
5339                                         break;
5340                                         
5341                                 default:
5342                                         {
5343                                                 int p = my_powof2( (~lit) & 0xff );
5344                                                 if(p>=0) {
5345                                                         /* only one bit is set in the literal, so use a bcf instruction */
5346                                                         pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5347                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5348                                                         
5349                                                 } else {
5350                                                         pic14_emitcode("movlw","0x%x", (lit & 0xff));
5351                                                         pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5352                                                         if(know_W != (int)(lit&0xff))
5353                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5354                                                         know_W = lit &0xff;
5355                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5356                                                 }
5357                                         }    
5358                                 }
5359                         } else {
5360                                 if (AOP_TYPE(left) == AOP_ACC) {
5361                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5362                                 } else {                    
5363                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5364                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5365                                         
5366                                 }
5367                         }
5368                 }
5369                 
5370         } else {
5371                 // left & result in different registers
5372                 if(AOP_TYPE(result) == AOP_CRY){
5373                         // result = bit
5374                         // if(size), result in bit
5375                         // if(!size && ifx), conditional oper: if(left & right)
5376                         symbol *tlbl = newiTempLabel(NULL);
5377                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5378                         if(size)
5379                                 pic14_emitcode("setb","c");
5380                         while(sizer--){
5381                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5382                                 pic14_emitcode("anl","a,%s",
5383                                         aopGet(AOP(left),offset,FALSE,FALSE));
5384                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5385                                 offset++;
5386                         }
5387                         if(size){
5388                                 CLRC;
5389                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5390                                 pic14_outBitC(result);
5391                         } else if(ifx)
5392                                 jmpTrueOrFalse(ifx, tlbl);
5393                 } else {
5394                         for(;(size--);offset++) {
5395                                 // normal case
5396                                 // result = left & right
5397                                 if(AOP_TYPE(right) == AOP_LIT){
5398                                         int t = (lit >> (offset*8)) & 0x0FFL;
5399                                         switch(t) { 
5400                                         case 0x00:
5401                                                 pic14_emitcode("clrf","%s",
5402                                                         aopGet(AOP(result),offset,FALSE,FALSE));
5403                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5404                                                 break;
5405                                         case 0xff:
5406                                                 if(AOP_TYPE(left) != AOP_ACC) {
5407                                                         pic14_emitcode("movf","%s,w",
5408                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5409                                                         pic14_emitcode("movwf","%s",
5410                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5411                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5412                                                 }
5413                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5414                                                 break;
5415                                         default:
5416                                                 if(AOP_TYPE(left) == AOP_ACC) {
5417                                                         emitpcode(POC_ANDLW, popGetLit(t));
5418                                                 } else {
5419                                                         pic14_emitcode("movlw","0x%x",t);
5420                                                         pic14_emitcode("andwf","%s,w",
5421                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5422                                                         pic14_emitcode("movwf","%s",
5423                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5424                                                         
5425                                                         emitpcode(POC_MOVLW, popGetLit(t));
5426                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5427                                                 }
5428                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5429                                         }
5430                                         continue;
5431                                 }
5432                                 
5433                                 if (AOP_TYPE(left) == AOP_ACC) {
5434                                         pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5435                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5436                                 } else {
5437                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5438                                         pic14_emitcode("andwf","%s,w",
5439                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5440                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5441                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5442                                 }
5443                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5444                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5445                         }
5446                 }
5447         }
5448         
5449 release :
5450         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5451         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5452         freeAsmop(result,NULL,ic,TRUE);     
5453 }
5454
5455 /*-----------------------------------------------------------------*/
5456 /* genOr  - code for or                                            */
5457 /*-----------------------------------------------------------------*/
5458 static void genOr (iCode *ic, iCode *ifx)
5459 {
5460         operand *left, *right, *result;
5461         int size, offset=0;
5462         unsigned long lit = 0L;
5463         
5464         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5465         
5466         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5467         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5468         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5469         
5470         DEBUGpic14_AopType(__LINE__,left,right,result);
5471         
5472         /* if left is a literal & right is not then exchange them */
5473         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5474                 AOP_NEEDSACC(left)) {
5475                 operand *tmp = right ;
5476                 right = left;
5477                 left = tmp;
5478         }
5479         
5480         /* if result = right then exchange them */
5481         if(pic14_sameRegs(AOP(result),AOP(right))){
5482                 operand *tmp = right ;
5483                 right = left;
5484                 left = tmp;
5485         }
5486         
5487         /* if right is bit then exchange them */
5488         if (AOP_TYPE(right) == AOP_CRY &&
5489                 AOP_TYPE(left) != AOP_CRY){
5490                 operand *tmp = right ;
5491                 right = left;
5492                 left = tmp;
5493         }
5494         
5495         DEBUGpic14_AopType(__LINE__,left,right,result);
5496         
5497         if(AOP_TYPE(right) == AOP_LIT)
5498                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5499         
5500         size = AOP_SIZE(result);
5501         
5502         // if(bit | yy)
5503         // xx = bit | yy;
5504         if (AOP_TYPE(left) == AOP_CRY){
5505                 if(AOP_TYPE(right) == AOP_LIT){
5506                         // c = bit & literal;
5507                         if(lit){
5508                                 // lit != 0 => result = 1
5509                                 if(AOP_TYPE(result) == AOP_CRY){
5510                                         if(size)
5511                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5512                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5513                                         //       AOP(result)->aopu.aop_dir,
5514                                         //       AOP(result)->aopu.aop_dir);
5515                                         else if(ifx)
5516                                                 continueIfTrue(ifx);
5517                                         goto release;
5518                                 }
5519                         } else {
5520                                 // lit == 0 => result = left
5521                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5522                                         goto release;
5523                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5524                         }
5525                 } else {
5526                         if (AOP_TYPE(right) == AOP_CRY){
5527                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5528                                         // c = bit | bit;
5529                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5530                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5531                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5532                                         
5533                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5534                                                 AOP(result)->aopu.aop_dir,
5535                                                 AOP(result)->aopu.aop_dir);
5536                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5537                                                 AOP(right)->aopu.aop_dir,
5538                                                 AOP(right)->aopu.aop_dir);
5539                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5540                                                 AOP(result)->aopu.aop_dir,
5541                                                 AOP(result)->aopu.aop_dir);
5542                                 } else {
5543                                         if( AOP_TYPE(result) == AOP_ACC) {
5544                                                 emitpcode(POC_MOVLW, popGetLit(0));
5545                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5546                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5547                                                 emitpcode(POC_MOVLW, popGetLit(1));
5548                                                 
5549                                         } else {
5550                                                 
5551                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5552                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5553                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5554                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5555                                                 
5556                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5557                                                         AOP(result)->aopu.aop_dir,
5558                                                         AOP(result)->aopu.aop_dir);
5559                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5560                                                         AOP(right)->aopu.aop_dir,
5561                                                         AOP(right)->aopu.aop_dir);
5562                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5563                                                         AOP(left)->aopu.aop_dir,
5564                                                         AOP(left)->aopu.aop_dir);
5565                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5566                                                         AOP(result)->aopu.aop_dir,
5567                                                         AOP(result)->aopu.aop_dir);
5568                                         }
5569                                 }
5570                         } else {
5571                                 // c = bit | val;
5572                                 symbol *tlbl = newiTempLabel(NULL);
5573                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5574                                 
5575                                 
5576                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5577                                 if( AOP_TYPE(right) == AOP_ACC) {
5578                                         emitpcode(POC_IORLW, popGetLit(0));
5579                                         emitSKPNZ;
5580                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5581                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5582                                 }
5583                                 
5584                                 
5585                                 
5586                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5587                                         pic14_emitcode(";XXX setb","c");
5588                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5589                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5590                                 pic14_toBoolean(right);
5591                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5592                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5593                                         jmpTrueOrFalse(ifx, tlbl);
5594                                         goto release;
5595                                 } else {
5596                                         CLRC;
5597                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5598                                 }
5599                         }
5600                 }
5601                 // bit = c
5602                 // val = c
5603                 if(size)
5604                         pic14_outBitC(result);
5605                 // if(bit | ...)
5606                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5607                         genIfxJump(ifx, "c");           
5608                 goto release ;
5609         }
5610         
5611         // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5612         // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5613         if((AOP_TYPE(right) == AOP_LIT) &&
5614                 (AOP_TYPE(result) == AOP_CRY) &&
5615                 (AOP_TYPE(left) != AOP_CRY)){
5616                 if(lit){
5617                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5618                         // result = 1
5619                         if(size)
5620                                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5621                         else 
5622                                 continueIfTrue(ifx);
5623                         goto release;
5624                 } else {
5625                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5626                         // lit = 0, result = boolean(left)
5627                         if(size)
5628                                 pic14_emitcode(";XXX setb","c");
5629                         pic14_toBoolean(right);
5630                         if(size){
5631                                 symbol *tlbl = newiTempLabel(NULL);
5632                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5633                                 CLRC;
5634                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5635                         } else {
5636                                 genIfxJump (ifx,"a");
5637                                 goto release;
5638                         }
5639                 }
5640                 pic14_outBitC(result);
5641                 goto release ;
5642         }
5643         
5644         /* if left is same as result */
5645         if(pic14_sameRegs(AOP(result),AOP(left))){
5646                 int know_W = -1;
5647                 for(;size--; offset++,lit>>=8) {
5648                         if(AOP_TYPE(right) == AOP_LIT){
5649                                 if((lit & 0xff) == 0)
5650                                         /*  or'ing with 0 has no effect */
5651                                         continue;
5652                                 else {
5653                                         int p = my_powof2(lit & 0xff);
5654                                         if(p>=0) {
5655                                                 /* only one bit is set in the literal, so use a bsf instruction */
5656                                                 emitpcode(POC_BSF,
5657                                                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5658                                         } else {
5659                                                 if(know_W != (int)(lit & 0xff))
5660                                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5661                                                 know_W = lit & 0xff;
5662                                                 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5663                                         }
5664                                         
5665                                 }
5666                         } else {
5667                                 if (AOP_TYPE(left) == AOP_ACC) {
5668                                         emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5669                                         pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5670                                 } else {                    
5671                                         emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5672                                         emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5673                                         
5674                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5675                                         pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5676                                         
5677                                 }
5678                         }
5679                 }
5680         } else {
5681                 // left & result in different registers
5682                 if(AOP_TYPE(result) == AOP_CRY){
5683                         // result = bit
5684                         // if(size), result in bit
5685                         // if(!size && ifx), conditional oper: if(left | right)
5686                         symbol *tlbl = newiTempLabel(NULL);
5687                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5688                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689                         
5690                         
5691                         if(size)
5692                                 pic14_emitcode(";XXX setb","c");
5693                         while(sizer--){
5694                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5695                                 pic14_emitcode(";XXX orl","a,%s",
5696                                         aopGet(AOP(left),offset,FALSE,FALSE));
5697                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5698                                 offset++;
5699                         }
5700                         if(size){
5701                                 CLRC;
5702                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5703                                 pic14_outBitC(result);
5704                         } else if(ifx)
5705                                 jmpTrueOrFalse(ifx, tlbl);
5706                 } else for(;(size--);offset++){
5707                         // normal case
5708                         // result = left & right
5709                         if(AOP_TYPE(right) == AOP_LIT){
5710                                 int t = (lit >> (offset*8)) & 0x0FFL;
5711                                 switch(t) { 
5712                                 case 0x00:
5713                                         if (AOP_TYPE(left) != AOP_ACC) {
5714                                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5715                                         }
5716                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5717                                         
5718                                         break;
5719                                 default:
5720                                         if (AOP_TYPE(left) == AOP_ACC) {
5721                                                 emitpcode(POC_IORLW,  popGetLit(t));
5722                                         } else {
5723                                                 emitpcode(POC_MOVLW,  popGetLit(t));
5724                                                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5725                                         }
5726                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));            
5727                                 }
5728                                 continue;
5729                         }
5730                         
5731                         // faster than result <- left, anl result,right
5732                         // and better if result is SFR
5733                         if (AOP_TYPE(left) == AOP_ACC) {
5734                                 emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5735                                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5736                         } else {
5737                                 emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5738                                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5739                                 
5740                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5741                                 pic14_emitcode("iorwf","%s,w",
5742                                         aopGet(AOP(left),offset,FALSE,FALSE));
5743                         }
5744                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5745                         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5746                 }
5747         }
5748         
5749 release :
5750         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5751         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5752         freeAsmop(result,NULL,ic,TRUE);     
5753 }
5754
5755 /*-----------------------------------------------------------------*/
5756 /* genXor - code for xclusive or                                   */
5757 /*-----------------------------------------------------------------*/
5758 static void genXor (iCode *ic, iCode *ifx)
5759 {
5760         operand *left, *right, *result;
5761         int size, offset=0;
5762         unsigned long lit = 0L;
5763         
5764         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5765         
5766         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5767         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5768         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5769         
5770         /* if left is a literal & right is not ||
5771         if left needs acc & right does not */
5772         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5773                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5774                 operand *tmp = right ;
5775                 right = left;
5776                 left = tmp;
5777         }
5778         
5779         /* if result = right then exchange them */
5780         if(pic14_sameRegs(AOP(result),AOP(right))){
5781                 operand *tmp = right ;
5782                 right = left;
5783                 left = tmp;
5784         }
5785         
5786         /* if right is bit then exchange them */
5787         if (AOP_TYPE(right) == AOP_CRY &&
5788                 AOP_TYPE(left) != AOP_CRY){
5789                 operand *tmp = right ;
5790                 right = left;
5791                 left = tmp;
5792         }
5793         if(AOP_TYPE(right) == AOP_LIT)
5794                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5795         
5796         size = AOP_SIZE(result);
5797         
5798         // if(bit ^ yy)
5799         // xx = bit ^ yy;
5800         if (AOP_TYPE(left) == AOP_CRY){
5801                 if(AOP_TYPE(right) == AOP_LIT){
5802                         // c = bit & literal;
5803                         if(lit>>1){
5804                                 // lit>>1  != 0 => result = 1
5805                                 if(AOP_TYPE(result) == AOP_CRY){
5806                                         if(size)
5807                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5808                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5809                                         else if(ifx)
5810                                                 continueIfTrue(ifx);
5811                                         goto release;
5812                                 }
5813                                 pic14_emitcode("setb","c");
5814                         } else{
5815                                 // lit == (0 or 1)
5816                                 if(lit == 0){
5817                                         // lit == 0, result = left
5818                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5819                                                 goto release;
5820                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5821                                 } else{
5822                                         // lit == 1, result = not(left)
5823                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5824                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5825                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5826                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5827                                                 goto release;
5828                                         } else {
5829                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5830                                                 pic14_emitcode("cpl","c");
5831                                         }
5832                                 }
5833                         }
5834                         
5835                 } else {
5836                         // right != literal
5837                         symbol *tlbl = newiTempLabel(NULL);
5838                         if (AOP_TYPE(right) == AOP_CRY){
5839                                 // c = bit ^ bit;
5840                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5841                         }
5842                         else{
5843                                 int sizer = AOP_SIZE(right);
5844                                 // c = bit ^ val
5845                                 // if val>>1 != 0, result = 1
5846                                 pic14_emitcode("setb","c");
5847                                 while(sizer){
5848                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5849                                         if(sizer == 1)
5850                                                 // test the msb of the lsb
5851                                                 pic14_emitcode("anl","a,#0xfe");
5852                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5853                                         sizer--;
5854                                 }
5855                                 // val = (0,1)
5856                                 pic14_emitcode("rrc","a");
5857                         }
5858                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5859                         pic14_emitcode("cpl","c");
5860                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5861                 }
5862                 // bit = c
5863                 // val = c
5864                 if(size)
5865                         pic14_outBitC(result);
5866                 // if(bit | ...)
5867                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5868                         genIfxJump(ifx, "c");           
5869                 goto release ;
5870         }
5871         
5872         if(pic14_sameRegs(AOP(result),AOP(left))){
5873                 /* if left is same as result */
5874                 for(;size--; offset++) {
5875                         if(AOP_TYPE(right) == AOP_LIT){
5876                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5877                                 if(t == 0x00L)
5878                                         continue;
5879                                 else
5880                                         if (IS_AOP_PREG(left)) {
5881                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5882                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5883                                                 aopPut(AOP(result),"a",offset);
5884                                         } else {
5885                                                 emitpcode(POC_MOVLW, popGetLit(t));
5886                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5887                                                 pic14_emitcode("xrl","%s,%s",
5888                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5889                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5890                                         }
5891                         } else {
5892                                 if (AOP_TYPE(left) == AOP_ACC)
5893                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5894                                 else {
5895                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5896                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5897                                         /*
5898                                         if (IS_AOP_PREG(left)) {
5899                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5900                                         aopPut(AOP(result),"a",offset);
5901                                         } else
5902                                         pic14_emitcode("xrl","%s,a",
5903                                         aopGet(AOP(left),offset,FALSE,TRUE));
5904                                         */
5905                                 }
5906                         }
5907                 }
5908         } else {
5909                 // left & result in different registers
5910                 if(AOP_TYPE(result) == AOP_CRY){
5911                         // result = bit
5912                         // if(size), result in bit
5913                         // if(!size && ifx), conditional oper: if(left ^ right)
5914                         symbol *tlbl = newiTempLabel(NULL);
5915                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5916                         if(size)
5917                                 pic14_emitcode("setb","c");
5918                         while(sizer--){
5919                                 if((AOP_TYPE(right) == AOP_LIT) &&
5920                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5921                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5922                                 } else {
5923                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5924                                         pic14_emitcode("xrl","a,%s",
5925                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5926                                 }
5927                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5928                                 offset++;
5929                         }
5930                         if(size){
5931                                 CLRC;
5932                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5933                                 pic14_outBitC(result);
5934                         } else if(ifx)
5935                                 jmpTrueOrFalse(ifx, tlbl);
5936                 } else for(;(size--);offset++){
5937                         // normal case
5938                         // result = left & right
5939                         if(AOP_TYPE(right) == AOP_LIT){
5940                                 int t = (lit >> (offset*8)) & 0x0FFL;
5941                                 switch(t) { 
5942                                 case 0x00:
5943                                         if (AOP_TYPE(left) != AOP_ACC) {
5944                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5945                                         }
5946                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5947                                         pic14_emitcode("movf","%s,w",
5948                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5949                                         pic14_emitcode("movwf","%s",
5950                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5951                                         break;
5952                                 case 0xff:
5953                                         if (AOP_TYPE(left) == AOP_ACC) {
5954                                                 emitpcode(POC_XORLW, popGetLit(t));
5955                                         } else {
5956                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5957                                         }
5958                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5959                                         break;
5960                                 default:
5961                                         if (AOP_TYPE(left) == AOP_ACC) {
5962                                                 emitpcode(POC_XORLW, popGetLit(t));
5963                                         } else {
5964                                                 emitpcode(POC_MOVLW, popGetLit(t));
5965                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5966                                         }
5967                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5968                                         pic14_emitcode("movlw","0x%x",t);
5969                                         pic14_emitcode("xorwf","%s,w",
5970                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5971                                         pic14_emitcode("movwf","%s",
5972                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5973                                         
5974                                 }
5975                                 continue;
5976                         }
5977                         
5978                         // faster than result <- left, anl result,right
5979                         // and better if result is SFR
5980                         if (AOP_TYPE(left) == AOP_ACC) {
5981                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5982                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5983                         } else {
5984                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5985                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5986                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5987                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5988                         }
5989                         if ( AOP_TYPE(result) != AOP_ACC){
5990                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5991                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5992                         }
5993                 }
5994         }
5995         
5996 release :
5997         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5998         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5999         freeAsmop(result,NULL,ic,TRUE);     
6000 }
6001
6002 /*-----------------------------------------------------------------*/
6003 /* genInline - write the inline code out                           */
6004 /*-----------------------------------------------------------------*/
6005 static void genInline (iCode *ic)
6006 {
6007         char *buffer, *bp, *bp1;
6008         
6009         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6010         
6011         _G.inLine += (!options.asmpeep);
6012         
6013         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6014         strcpy(buffer,IC_INLINE(ic));
6015         
6016         /* emit each line as a code */
6017         while (*bp) {
6018                 if (*bp == '\n') {
6019                         *bp++ = '\0';
6020                         
6021                         if(*bp1)
6022                                 addpCode2pBlock(pb,AssembleLine(bp1));
6023                         bp1 = bp;
6024                 } else {
6025                         if (*bp == ':') {
6026                                 bp++;
6027                                 *bp = '\0';
6028                                 bp++;
6029                                 pic14_emitcode(bp1,"");
6030                                 bp1 = bp;
6031                         } else
6032                                 bp++;
6033                 }
6034         }
6035         if ((bp1 != bp) && *bp1)
6036                 addpCode2pBlock(pb,AssembleLine(bp1));
6037         
6038         Safe_free(buffer);
6039         
6040         _G.inLine -= (!options.asmpeep);
6041 }
6042
6043 /*-----------------------------------------------------------------*/
6044 /* genRRC - rotate right with carry                                */
6045 /*-----------------------------------------------------------------*/
6046 static void genRRC (iCode *ic)
6047 {
6048         operand *left , *result ;
6049         int size, offset = 0, same;
6050         
6051         /* rotate right with carry */
6052         left = IC_LEFT(ic);
6053         result=IC_RESULT(ic);
6054         aopOp (left,ic,FALSE);
6055         aopOp (result,ic,FALSE);
6056         
6057         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6058         
6059         same = pic14_sameRegs(AOP(result),AOP(left));
6060         
6061         size = AOP_SIZE(result);    
6062         
6063         /* get the lsb and put it into the carry */
6064         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6065         
6066         offset = 0 ;
6067         
6068         while(size--) {
6069                 
6070                 if(same) {
6071                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6072                 } else {
6073                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6074                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6075                 }
6076                 
6077                 offset++;
6078         }
6079         
6080         freeAsmop(left,NULL,ic,TRUE);
6081         freeAsmop(result,NULL,ic,TRUE);
6082 }
6083
6084 /*-----------------------------------------------------------------*/
6085 /* genRLC - generate code for rotate left with carry               */
6086 /*-----------------------------------------------------------------*/
6087 static void genRLC (iCode *ic)
6088 {    
6089         operand *left , *result ;
6090         int size, offset = 0;
6091         int same;
6092         
6093         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6094         /* rotate right with carry */
6095         left = IC_LEFT(ic);
6096         result=IC_RESULT(ic);
6097         aopOp (left,ic,FALSE);
6098         aopOp (result,ic,FALSE);
6099         
6100         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6101         
6102         same = pic14_sameRegs(AOP(result),AOP(left));
6103         
6104         /* move it to the result */
6105         size = AOP_SIZE(result);    
6106         
6107         /* get the msb and put it into the carry */
6108         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6109         
6110         offset = 0 ;
6111         
6112         while(size--) {
6113                 
6114                 if(same) {
6115                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6116                 } else {
6117                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6118                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6119                 }
6120                 
6121                 offset++;
6122         }
6123         
6124         
6125         freeAsmop(left,NULL,ic,TRUE);
6126         freeAsmop(result,NULL,ic,TRUE);
6127 }
6128
6129 /*-----------------------------------------------------------------*/
6130 /* genGetHbit - generates code get highest order bit               */
6131 /*-----------------------------------------------------------------*/
6132 static void genGetHbit (iCode *ic)
6133 {
6134         operand *left, *result;
6135         left = IC_LEFT(ic);
6136         result=IC_RESULT(ic);
6137         aopOp (left,ic,FALSE);
6138         aopOp (result,ic,FALSE);
6139         
6140         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6141         /* get the highest order byte into a */
6142         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6143         if(AOP_TYPE(result) == AOP_CRY){
6144                 pic14_emitcode("rlc","a");
6145                 pic14_outBitC(result);
6146         }
6147         else{
6148                 pic14_emitcode("rl","a");
6149                 pic14_emitcode("anl","a,#0x01");
6150                 pic14_outAcc(result);
6151         }
6152         
6153         
6154         freeAsmop(left,NULL,ic,TRUE);
6155         freeAsmop(result,NULL,ic,TRUE);
6156 }
6157
6158 /*-----------------------------------------------------------------*/
6159 /* AccRol - rotate left accumulator by known count                 */
6160 /*-----------------------------------------------------------------*/
6161 static void AccRol (int shCount)
6162 {
6163         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6164         shCount &= 0x0007;              // shCount : 0..7
6165         switch(shCount){
6166         case 0 :
6167                 break;
6168         case 1 :
6169                 pic14_emitcode("rl","a");
6170                 break;
6171         case 2 :
6172                 pic14_emitcode("rl","a");
6173                 pic14_emitcode("rl","a");
6174                 break;
6175         case 3 :
6176                 pic14_emitcode("swap","a");
6177                 pic14_emitcode("rr","a");
6178                 break;
6179         case 4 :
6180                 pic14_emitcode("swap","a");
6181                 break;
6182         case 5 :
6183                 pic14_emitcode("swap","a");
6184                 pic14_emitcode("rl","a");
6185                 break;
6186         case 6 :
6187                 pic14_emitcode("rr","a");
6188                 pic14_emitcode("rr","a");
6189                 break;
6190         case 7 :
6191                 pic14_emitcode("rr","a");
6192                 break;
6193         }
6194 }
6195
6196 /*-----------------------------------------------------------------*/
6197 /* AccLsh - left shift accumulator by known count                  */
6198 /*-----------------------------------------------------------------*/
6199 static void AccLsh (int shCount)
6200 {
6201         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6202         if(shCount != 0){
6203                 if(shCount == 1)
6204                         pic14_emitcode("add","a,acc");
6205                 else 
6206                         if(shCount == 2) {
6207                                 pic14_emitcode("add","a,acc");
6208                                 pic14_emitcode("add","a,acc");
6209                         } else {
6210                                 /* rotate left accumulator */
6211                                 AccRol(shCount);
6212                                 /* and kill the lower order bits */
6213                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6214                         }
6215         }
6216 }
6217
6218 /*-----------------------------------------------------------------*/
6219 /* AccRsh - right shift accumulator by known count                 */
6220 /*-----------------------------------------------------------------*/
6221 static void AccRsh (int shCount)
6222 {
6223         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6224         if(shCount != 0){
6225                 if(shCount == 1){
6226                         CLRC;
6227                         pic14_emitcode("rrc","a");
6228                 } else {
6229                         /* rotate right accumulator */
6230                         AccRol(8 - shCount);
6231                         /* and kill the higher order bits */
6232                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6233                 }
6234         }
6235 }
6236
6237 #if 0
6238 /*-----------------------------------------------------------------*/
6239 /* AccSRsh - signed right shift accumulator by known count                 */
6240 /*-----------------------------------------------------------------*/
6241 static void AccSRsh (int shCount)
6242 {
6243         symbol *tlbl ;
6244         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6245         if(shCount != 0){
6246                 if(shCount == 1){
6247                         pic14_emitcode("mov","c,acc.7");
6248                         pic14_emitcode("rrc","a");
6249                 } else if(shCount == 2){
6250                         pic14_emitcode("mov","c,acc.7");
6251                         pic14_emitcode("rrc","a");
6252                         pic14_emitcode("mov","c,acc.7");
6253                         pic14_emitcode("rrc","a");
6254                 } else {
6255                         tlbl = newiTempLabel(NULL);
6256                         /* rotate right accumulator */
6257                         AccRol(8 - shCount);
6258                         /* and kill the higher order bits */
6259                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6260                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6261                         pic14_emitcode("orl","a,#0x%02x",
6262                                 (unsigned char)~SRMask[shCount]);
6263                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6264                 }
6265         }
6266 }
6267 #endif
6268 /*-----------------------------------------------------------------*/
6269 /* shiftR1Left2Result - shift right one byte from left to result   */
6270 /*-----------------------------------------------------------------*/
6271 static void shiftR1Left2ResultSigned (operand *left, int offl,
6272                                                                           operand *result, int offr,
6273                                                                           int shCount)
6274 {
6275         int same;
6276         
6277         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6278         
6279         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6280         
6281         switch(shCount) {
6282         case 1:
6283                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6284                 if(same) 
6285                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6286                 else {
6287                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6288                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6289                 }
6290                 
6291                 break;
6292         case 2:
6293                 
6294                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6295                 if(same) 
6296                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6297                 else {
6298                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6299                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6300                 }
6301                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6302                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6303                 
6304                 break;
6305                 
6306         case 3:
6307                 if(same)
6308                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6309                 else {
6310                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6311                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6312                 }
6313                 
6314                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6315                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6316                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6317                 
6318                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6319                 emitpcode(POC_IORLW, popGetLit(0xe0));
6320                 
6321                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6322                 break;
6323                 
6324         case 4:
6325                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6326                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6327                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6328                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6329                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6330                 break;
6331         case 5:
6332                 if(same) {
6333                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6334                 } else {
6335                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6336                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6337                 }
6338                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6339                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6340                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6341                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6342                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6343                 break;
6344                 
6345         case 6:
6346                 if(same) {
6347                         emitpcode(POC_MOVLW, popGetLit(0x00));
6348                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6349                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6350                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6351                         emitpcode(POC_IORLW, popGetLit(0x01));
6352                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6353                 } else {
6354                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6355                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6356                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6357                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6358                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6359                 }
6360                 break;
6361                 
6362         case 7:
6363                 if(same) {
6364                         emitpcode(POC_MOVLW, popGetLit(0x00));
6365                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6366                         emitpcode(POC_MOVLW, popGetLit(0xff));
6367                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368                 } else {
6369                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6370                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6371                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6372                 }
6373                 
6374         default:
6375                 break;
6376         }
6377 }
6378
6379 /*-----------------------------------------------------------------*/
6380 /* shiftR1Left2Result - shift right one byte from left to result   */
6381 /*-----------------------------------------------------------------*/
6382 static void shiftR1Left2Result (operand *left, int offl,
6383                                                                 operand *result, int offr,
6384                                                                 int shCount, int sign)
6385 {
6386         int same;
6387         
6388         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6389         
6390         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6391         
6392         /* Copy the msb into the carry if signed. */
6393         if(sign) {
6394                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6395                 return;
6396         }
6397         
6398         
6399         
6400         switch(shCount) {
6401         case 1:
6402                 emitCLRC;
6403                 if(same) 
6404                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6405                 else {
6406                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6407                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6408                 }
6409                 break;
6410         case 2:
6411                 emitCLRC;
6412                 if(same) {
6413                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6414                 } else {
6415                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6416                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6417                 }
6418                 emitCLRC;
6419                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6420                 
6421                 break;
6422         case 3:
6423                 if(same)
6424                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6425                 else {
6426                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6427                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6428                 }
6429                 
6430                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6431                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6432                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6433                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6434                 break;
6435                 
6436         case 4:
6437                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6438                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6439                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6440                 break;
6441                 
6442         case 5:
6443                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6444                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6445                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6446                 emitCLRC;
6447                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6448                 
6449                 break;
6450         case 6:
6451                 
6452                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6453                 emitpcode(POC_ANDLW, popGetLit(0x80));
6454                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6455                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6456                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6457                 break;
6458                 
6459         case 7:
6460                 
6461                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6462                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6463                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6464                 
6465                 break;
6466                 
6467         default:
6468                 break;
6469         }
6470 }
6471
6472 /*-----------------------------------------------------------------*/
6473 /* shiftL1Left2Result - shift left one byte from left to result    */
6474 /*-----------------------------------------------------------------*/
6475 static void shiftL1Left2Result (operand *left, int offl,
6476                                                                 operand *result, int offr, int shCount)
6477 {
6478         int same;
6479         
6480         //    char *l;
6481         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6482         
6483         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6484         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6485         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6486         //    MOVA(l);
6487         /* shift left accumulator */
6488         //AccLsh(shCount); // don't comment out just yet...
6489         //    aopPut(AOP(result),"a",offr);
6490         
6491         switch(shCount) {
6492         case 1:
6493                 /* Shift left 1 bit position */
6494                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6495                 if(same) {
6496                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6497                 } else {
6498                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6499                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6500                 }
6501                 break;
6502         case 2:
6503                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6504                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6505                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6506                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6507                 break;
6508         case 3:
6509                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6510                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6511                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6512                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6513                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6514                 break;
6515         case 4:
6516                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6517                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6518                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6519                 break;
6520         case 5:
6521                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6522                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6523                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6524                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6525                 break;
6526         case 6:
6527                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6528                 emitpcode(POC_ANDLW, popGetLit(0x30));
6529                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6530                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6531                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6532                 break;
6533         case 7:
6534                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6535                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6536                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6537                 break;
6538                 
6539         default:
6540                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6541         }
6542         
6543 }
6544
6545 /*-----------------------------------------------------------------*/
6546 /* movLeft2Result - move byte from left to result                  */
6547 /*-----------------------------------------------------------------*/
6548 static void movLeft2Result (operand *left, int offl,
6549                                                         operand *result, int offr)
6550 {
6551         char *l;
6552         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6553         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6554                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6555                 
6556                 if (*l == '@' && (IS_AOP_PREG(result))) {
6557                         pic14_emitcode("mov","a,%s",l);
6558                         aopPut(AOP(result),"a",offr);
6559                 } else {
6560                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6561                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6562                 }
6563         }
6564 }
6565
6566 /*-----------------------------------------------------------------*/
6567 /* shiftL2Left2Result - shift left two bytes from left to result   */
6568 /*-----------------------------------------------------------------*/
6569 static void shiftL2Left2Result (operand *left, int offl,
6570                                                                 operand *result, int offr, int shCount)
6571 {
6572         
6573         
6574         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6575         
6576         if(pic14_sameRegs(AOP(result), AOP(left))) {
6577                 switch(shCount) {
6578                 case 0:
6579                         break;
6580                 case 1:
6581                 case 2:
6582                 case 3:
6583                         
6584                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6585                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6586                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6587                         
6588                         while(--shCount) {
6589                                 emitCLRC;
6590                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6591                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6592                         }
6593                         
6594                         break;
6595                 case 4:
6596                 case 5:
6597                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6598                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6599                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6600                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6601                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6602                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6603                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6604                         if(shCount >=5) {
6605                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6606                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6607                         }
6608                         break;
6609                 case 6:
6610                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6611                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6612                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6613                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6614                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6615                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6616                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6617                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6618                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6619                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6620                         break;
6621                 case 7:
6622                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6623                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6624                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6625                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6626                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6627                 }
6628                 
6629         } else {
6630                 switch(shCount) {
6631                 case 0:
6632                         break;
6633                 case 1:
6634                 case 2:
6635                 case 3:
6636                 /* note, use a mov/add for the shift since the mov has a
6637                         chance of getting optimized out */
6638                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6639                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6640                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6641                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6642                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6643                         
6644                         while(--shCount) {
6645                                 emitCLRC;
6646                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6647                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6648                         }
6649                         break;
6650                         
6651                 case 4:
6652                 case 5:
6653                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6654                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6655                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6656                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6657                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6658                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6659                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6660                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6661                         
6662                         
6663                         if(shCount == 5) {
6664                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6665                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6666                         }
6667                         break;
6668                 case 6:
6669                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6670                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6671                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6672                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6673                         
6674                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6675                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6676                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6677                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6678                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6679                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6680                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6681                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6682                         break;
6683                 case 7:
6684                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6685                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6686                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6687                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6688                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6689                 }
6690         }
6691         
6692 }
6693 /*-----------------------------------------------------------------*/
6694 /* shiftR2Left2Result - shift right two bytes from left to result  */
6695 /*-----------------------------------------------------------------*/
6696 static void shiftR2Left2Result (operand *left, int offl,
6697                                                                 operand *result, int offr,
6698                                                                 int shCount, int sign)
6699 {
6700         int same=0;
6701         
6702         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6703         same = pic14_sameRegs(AOP(result), AOP(left));
6704         
6705         if(same && ((offl + MSB16) == offr)){
6706                 same=1;
6707                 /* don't crash result[offr] */
6708                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6709                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6710         }
6711         /* else {
6712         movLeft2Result(left,offl, result, offr);
6713         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6714         }
6715         */
6716         /* a:x >> shCount (x = lsb(result))*/
6717         /*
6718         if(sign)
6719         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6720         else {
6721         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6722         */
6723         switch(shCount) {
6724         case 0:
6725                 break;
6726         case 1:
6727         case 2:
6728         case 3:
6729                 if(sign)
6730                         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6731                 else
6732                         emitCLRC;
6733                 
6734                 if(same) {
6735                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6736                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6737                 } else {
6738                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6739                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6741                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6742                 }
6743                 
6744                 while(--shCount) {
6745                         if(sign)
6746                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6747                         else
6748                                 emitCLRC;
6749                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6750                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6751                 }
6752                 break;
6753         case 4:
6754         case 5:
6755                 if(same) {
6756                         
6757                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6758                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6759                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6760                         
6761                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6762                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6763                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6764                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6765                 } else {
6766                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6767                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6768                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6769                         
6770                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6771                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6772                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6773                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6774                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6775                 }
6776                 
6777                 if(shCount >=5) {
6778                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6779                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6780                 }
6781                 
6782                 if(sign) {
6783                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6784                         emitpcode(POC_BTFSC, 
6785                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6786                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6787                 }
6788                 
6789                 break;
6790                 
6791         case 6:
6792                 if(same) {
6793                         
6794                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6795                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6796                         
6797                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6798                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6799                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6800                         emitpcode(POC_ANDLW,popGetLit(0x03));
6801                         if(sign) {
6802                                 emitpcode(POC_BTFSC, 
6803                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6804                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6805                         }
6806                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6807                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6808                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6809                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6810                 } else {
6811                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6812                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6813                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6814                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6816                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6817                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6818                         emitpcode(POC_ANDLW,popGetLit(0x03));
6819                         if(sign) {
6820                                 emitpcode(POC_BTFSC, 
6821                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6822                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6823                         }
6824                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6825                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6826                         
6827                         
6828                 }
6829                 
6830                 break;
6831         case 7:
6832                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6833                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6834                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6835                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6836                 if(sign) {
6837                         emitSKPNC;
6838                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6839                 } else 
6840                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6841   }
6842 }
6843
6844
6845 /*-----------------------------------------------------------------*/
6846 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6847 /*-----------------------------------------------------------------*/
6848 static void shiftLLeftOrResult (operand *left, int offl,
6849                                                                 operand *result, int offr, int shCount)
6850 {
6851         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6852         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6853         /* shift left accumulator */
6854         AccLsh(shCount);
6855         /* or with result */
6856         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6857         /* back to result */
6858         aopPut(AOP(result),"a",offr);
6859 }
6860
6861 /*-----------------------------------------------------------------*/
6862 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6863 /*-----------------------------------------------------------------*/
6864 static void shiftRLeftOrResult (operand *left, int offl,
6865                                                                 operand *result, int offr, int shCount)
6866 {
6867         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6868         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6869         /* shift right accumulator */
6870         AccRsh(shCount);
6871         /* or with result */
6872         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6873         /* back to result */
6874         aopPut(AOP(result),"a",offr);
6875 }
6876
6877 /*-----------------------------------------------------------------*/
6878 /* genlshOne - left shift a one byte quantity by known count       */
6879 /*-----------------------------------------------------------------*/
6880 static void genlshOne (operand *result, operand *left, int shCount)
6881 {       
6882         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6883         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6884 }
6885
6886 /*-----------------------------------------------------------------*/
6887 /* genlshTwo - left shift two bytes by known amount != 0           */
6888 /*-----------------------------------------------------------------*/
6889 static void genlshTwo (operand *result,operand *left, int shCount)
6890 {
6891         int size;
6892         
6893         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6894         size = pic14_getDataSize(result);
6895         
6896         /* if shCount >= 8 */
6897         if (shCount >= 8) {
6898                 shCount -= 8 ;
6899                 
6900                 if (size > 1){
6901                         if (shCount)
6902                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6903                         else 
6904                                 movLeft2Result(left, LSB, result, MSB16);
6905                 }
6906                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6907         }
6908         
6909         /*  1 <= shCount <= 7 */
6910         else {  
6911                 if(size == 1)
6912                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6913                 else 
6914                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6915         }
6916 }
6917
6918 /*-----------------------------------------------------------------*/
6919 /* shiftLLong - shift left one long from left to result            */
6920 /* offl = LSB or MSB16                                             */
6921 /*-----------------------------------------------------------------*/
6922 static void shiftLLong (operand *left, operand *result, int offr )
6923 {
6924         char *l;
6925         int size = AOP_SIZE(result);
6926         
6927         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6928         if(size >= LSB+offr){
6929                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6930                 MOVA(l);
6931                 pic14_emitcode("add","a,acc");
6932                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6933                         size >= MSB16+offr && offr != LSB )
6934                         pic14_emitcode("xch","a,%s",
6935                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6936                 else        
6937                         aopPut(AOP(result),"a",LSB+offr);
6938         }
6939         
6940         if(size >= MSB16+offr){
6941                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6942                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6943                         MOVA(l);
6944                 }
6945                 pic14_emitcode("rlc","a");
6946                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6947                         size >= MSB24+offr && offr != LSB)
6948                         pic14_emitcode("xch","a,%s",
6949                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6950                 else        
6951                         aopPut(AOP(result),"a",MSB16+offr);
6952         }
6953         
6954         if(size >= MSB24+offr){
6955                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6956                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6957                         MOVA(l);
6958                 }
6959                 pic14_emitcode("rlc","a");
6960                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6961                         size >= MSB32+offr && offr != LSB )
6962                         pic14_emitcode("xch","a,%s",
6963                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6964                 else        
6965                         aopPut(AOP(result),"a",MSB24+offr);
6966         }
6967         
6968         if(size > MSB32+offr){
6969                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6970                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6971                         MOVA(l);        
6972                 }
6973                 pic14_emitcode("rlc","a");
6974                 aopPut(AOP(result),"a",MSB32+offr);
6975         }
6976         if(offr != LSB)
6977                 aopPut(AOP(result),zero,LSB);       
6978 }
6979
6980 /*-----------------------------------------------------------------*/
6981 /* genlshFour - shift four byte by a known amount != 0             */
6982 /*-----------------------------------------------------------------*/
6983 static void genlshFour (operand *result, operand *left, int shCount)
6984 {
6985         int size;
6986         
6987         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6988         size = AOP_SIZE(result);
6989         
6990         /* if shifting more that 3 bytes */
6991         if (shCount >= 24 ) {
6992                 shCount -= 24;
6993                 if (shCount)
6994                 /* lowest order of left goes to the highest
6995                 order of the destination */
6996                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6997                 else
6998                         movLeft2Result(left, LSB, result, MSB32);
6999                 aopPut(AOP(result),zero,LSB);
7000                 aopPut(AOP(result),zero,MSB16);
7001                 aopPut(AOP(result),zero,MSB32);
7002                 return;
7003         }
7004         
7005         /* more than two bytes */
7006         else if ( shCount >= 16 ) {
7007                 /* lower order two bytes goes to higher order two bytes */
7008                 shCount -= 16;
7009                 /* if some more remaining */
7010                 if (shCount)
7011                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7012                 else {
7013                         movLeft2Result(left, MSB16, result, MSB32);
7014                         movLeft2Result(left, LSB, result, MSB24);
7015                 }
7016                 aopPut(AOP(result),zero,MSB16);
7017                 aopPut(AOP(result),zero,LSB);
7018                 return;
7019         }    
7020         
7021         /* if more than 1 byte */
7022         else if ( shCount >= 8 ) {
7023                 /* lower order three bytes goes to higher order  three bytes */
7024                 shCount -= 8;
7025                 if(size == 2){
7026                         if(shCount)
7027                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7028                         else
7029                                 movLeft2Result(left, LSB, result, MSB16);
7030                 }
7031                 else{   /* size = 4 */
7032                         if(shCount == 0){
7033                                 movLeft2Result(left, MSB24, result, MSB32);
7034                                 movLeft2Result(left, MSB16, result, MSB24);
7035                                 movLeft2Result(left, LSB, result, MSB16);
7036                                 aopPut(AOP(result),zero,LSB);
7037                         }
7038                         else if(shCount == 1)
7039                                 shiftLLong(left, result, MSB16);
7040                         else{
7041                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7042                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7043                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7044                                 aopPut(AOP(result),zero,LSB);
7045                         }
7046                 }
7047         }
7048         
7049         /* 1 <= shCount <= 7 */
7050         else if(shCount <= 2){
7051                 shiftLLong(left, result, LSB);
7052                 if(shCount == 2)
7053                         shiftLLong(result, result, LSB);
7054         }
7055         /* 3 <= shCount <= 7, optimize */
7056         else{
7057                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7058                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7059                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7060         }
7061 }
7062
7063 /*-----------------------------------------------------------------*/
7064 /* genLeftShiftLiteral - left shifting by known count              */
7065 /*-----------------------------------------------------------------*/
7066 static void genLeftShiftLiteral (operand *left,
7067                                                                  operand *right,
7068                                                                  operand *result,
7069                                                                  iCode *ic)
7070 {    
7071         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7072         int size;
7073         
7074         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7075         freeAsmop(right,NULL,ic,TRUE);
7076         
7077         aopOp(left,ic,FALSE);
7078         aopOp(result,ic,FALSE);
7079         
7080         size = getSize(operandType(result));
7081         
7082 #if VIEW_SIZE
7083         pic14_emitcode("; shift left ","result %d, left %d",size,
7084                 AOP_SIZE(left));
7085 #endif
7086         
7087         /* I suppose that the left size >= result size */
7088         if(shCount == 0){
7089                 while(size--){
7090                         movLeft2Result(left, size, result, size);
7091                 }
7092         }
7093         
7094         else if(shCount >= (size * 8))
7095                 while(size--)
7096                         aopPut(AOP(result),zero,size);
7097                 else{
7098                         switch (size) {
7099                         case 1:
7100                                 genlshOne (result,left,shCount);
7101                                 break;
7102                                 
7103                         case 2:
7104                         case 3:
7105                                 genlshTwo (result,left,shCount);
7106                                 break;
7107                                 
7108                         case 4:
7109                                 genlshFour (result,left,shCount);
7110                                 break;
7111                         }
7112                 }
7113                 freeAsmop(left,NULL,ic,TRUE);
7114                 freeAsmop(result,NULL,ic,TRUE);
7115 }
7116
7117 /*-----------------------------------------------------------------*
7118 * genMultiAsm - repeat assembly instruction for size of register.
7119 * if endian == 1, then the high byte (i.e base address + size of 
7120 * register) is used first else the low byte is used first;
7121 *-----------------------------------------------------------------*/
7122 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7123 {
7124         
7125         int offset = 0;
7126         
7127         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7128         
7129         if(!reg)
7130                 return;
7131         
7132         if(!endian) {
7133                 endian = 1;
7134         } else {
7135                 endian = -1;
7136                 offset = size-1;
7137         }
7138         
7139         while(size--) {
7140                 emitpcode(poc,    popGet(AOP(reg),offset));
7141                 offset += endian;
7142         }
7143         
7144 }
7145 /*-----------------------------------------------------------------*/
7146 /* genLeftShift - generates code for left shifting                 */
7147 /*-----------------------------------------------------------------*/
7148 static void genLeftShift (iCode *ic)
7149 {
7150         operand *left,*right, *result;
7151         int size, offset;
7152         char *l;
7153         symbol *tlbl , *tlbl1;
7154         pCodeOp *pctemp;
7155         
7156         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7157         
7158         right = IC_RIGHT(ic);
7159         left  = IC_LEFT(ic);
7160         result = IC_RESULT(ic);
7161         
7162         aopOp(right,ic,FALSE);
7163         
7164         /* if the shift count is known then do it 
7165         as efficiently as possible */
7166         if (AOP_TYPE(right) == AOP_LIT) {
7167                 genLeftShiftLiteral (left,right,result,ic);
7168                 return ;
7169         }
7170         
7171         /* shift count is unknown then we have to form 
7172         a loop get the loop count in B : Note: we take
7173         only the lower order byte since shifting
7174         more that 32 bits make no sense anyway, ( the
7175         largest size of an object can be only 32 bits ) */  
7176         
7177         
7178         aopOp(left,ic,FALSE);
7179         aopOp(result,ic,FALSE);
7180         
7181         /* now move the left to the result if they are not the
7182         same */
7183         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7184                 AOP_SIZE(result) > 1) {
7185                 
7186                 size = AOP_SIZE(result);
7187                 offset=0;
7188                 while (size--) {
7189                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7190                         if (*l == '@' && (IS_AOP_PREG(result))) {
7191                                 
7192                                 pic14_emitcode("mov","a,%s",l);
7193                                 aopPut(AOP(result),"a",offset);
7194                         } else {
7195                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7196                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7197                                 //aopPut(AOP(result),l,offset);
7198                         }
7199                         offset++;
7200                 }
7201         }
7202         
7203         size = AOP_SIZE(result);
7204         
7205         /* if it is only one byte then */
7206         if (size == 1) {
7207                 if(optimized_for_speed) {
7208                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7209                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7210                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7211                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7212                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7213                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7214                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7215                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7216                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7217                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7218                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7219                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7220                 } else {
7221                         
7222                         tlbl = newiTempLabel(NULL);
7223                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7224                                 emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7225                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7226                         }
7227                         
7228                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7229                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7230                         emitpLabel(tlbl->key);
7231                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7232                         emitpcode(POC_ADDLW,  popGetLit(1));
7233                         emitSKPC;
7234                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7235                 }
7236                 goto release ;
7237         }
7238         
7239         if (pic14_sameRegs(AOP(left),AOP(result))) {
7240                 
7241                 tlbl = newiTempLabel(NULL);
7242                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7243                 genMultiAsm(POC_RRF, result, size,1);
7244                 emitpLabel(tlbl->key);
7245                 genMultiAsm(POC_RLF, result, size,0);
7246                 emitpcode(POC_ADDLW,  popGetLit(1));
7247                 emitSKPC;
7248                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7249                 goto release;
7250         }
7251         
7252         //tlbl = newiTempLabel(NULL);
7253         //offset = 0 ;   
7254         //tlbl1 = newiTempLabel(NULL);
7255         
7256         //reAdjustPreg(AOP(result));    
7257         
7258         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7259         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7260         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7261         //MOVA(l);
7262         //pic14_emitcode("add","a,acc");         
7263         //aopPut(AOP(result),"a",offset++);
7264         //while (--size) {
7265         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7266         //  MOVA(l);
7267         //  pic14_emitcode("rlc","a");         
7268         //  aopPut(AOP(result),"a",offset++);
7269         //}
7270         //reAdjustPreg(AOP(result));
7271         
7272         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7273         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7274         
7275         
7276         tlbl = newiTempLabel(NULL);
7277         tlbl1= newiTempLabel(NULL);
7278         
7279         size = AOP_SIZE(result);
7280         offset = 1;
7281         
7282         pctemp = popGetTempReg();  /* grab a temporary working register. */
7283         
7284         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7285         
7286         /* offset should be 0, 1 or 3 */
7287         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7288         emitSKPNZ;
7289         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7290         
7291         emitpcode(POC_MOVWF, pctemp);
7292         
7293         
7294         emitpLabel(tlbl->key);
7295         
7296         emitCLRC;
7297         emitpcode(POC_RLF,  popGet(AOP(result),0));
7298         while(--size)
7299                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7300         
7301         emitpcode(POC_DECFSZ,  pctemp);
7302         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7303         emitpLabel(tlbl1->key);
7304         
7305         popReleaseTempReg(pctemp);
7306         
7307         
7308 release:
7309         freeAsmop (right,NULL,ic,TRUE);
7310         freeAsmop(left,NULL,ic,TRUE);
7311         freeAsmop(result,NULL,ic,TRUE);
7312 }
7313
7314 /*-----------------------------------------------------------------*/
7315 /* genrshOne - right shift a one byte quantity by known count      */
7316 /*-----------------------------------------------------------------*/
7317 static void genrshOne (operand *result, operand *left,
7318                                            int shCount, int sign)
7319 {
7320         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7321         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7322 }
7323
7324 /*-----------------------------------------------------------------*/
7325 /* genrshTwo - right shift two bytes by known amount != 0          */
7326 /*-----------------------------------------------------------------*/
7327 static void genrshTwo (operand *result,operand *left,
7328                                            int shCount, int sign)
7329 {
7330         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7331         /* if shCount >= 8 */
7332         if (shCount >= 8) {
7333                 shCount -= 8 ;
7334                 if (shCount)
7335                         shiftR1Left2Result(left, MSB16, result, LSB,
7336                         shCount, sign);
7337                 else
7338                         movLeft2Result(left, MSB16, result, LSB);
7339                 
7340                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7341                 
7342                 if(sign) {
7343                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7344                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7345                 }
7346         }
7347         
7348         /*  1 <= shCount <= 7 */
7349         else
7350                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7351 }
7352
7353 /*-----------------------------------------------------------------*/
7354 /* shiftRLong - shift right one long from left to result           */
7355 /* offl = LSB or MSB16                                             */
7356 /*-----------------------------------------------------------------*/
7357 static void shiftRLong (operand *left, int offl,
7358                                                 operand *result, int sign)
7359 {
7360         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7361         if(!sign)
7362                 pic14_emitcode("clr","c");
7363         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7364         if(sign)
7365                 pic14_emitcode("mov","c,acc.7");
7366         pic14_emitcode("rrc","a");
7367         aopPut(AOP(result),"a",MSB32-offl);
7368         if(offl == MSB16)
7369                 /* add sign of "a" */
7370                 addSign(result, MSB32, sign);
7371         
7372         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7373         pic14_emitcode("rrc","a");
7374         aopPut(AOP(result),"a",MSB24-offl);
7375         
7376         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7377         pic14_emitcode("rrc","a");
7378         aopPut(AOP(result),"a",MSB16-offl);
7379         
7380         if(offl == LSB){
7381                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7382                 pic14_emitcode("rrc","a");
7383                 aopPut(AOP(result),"a",LSB);
7384         }
7385 }
7386
7387 /*-----------------------------------------------------------------*/
7388 /* genrshFour - shift four byte by a known amount != 0             */
7389 /*-----------------------------------------------------------------*/
7390 static void genrshFour (operand *result, operand *left,
7391                                                 int shCount, int sign)
7392 {
7393         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7394         /* if shifting more that 3 bytes */
7395         if(shCount >= 24 ) {
7396                 shCount -= 24;
7397                 if(shCount)
7398                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7399                 else
7400                         movLeft2Result(left, MSB32, result, LSB);
7401                 
7402                 addSign(result, MSB16, sign);
7403         }
7404         else if(shCount >= 16){
7405                 shCount -= 16;
7406                 if(shCount)
7407                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7408                 else{
7409                         movLeft2Result(left, MSB24, result, LSB);
7410                         movLeft2Result(left, MSB32, result, MSB16);
7411                 }
7412                 addSign(result, MSB24, sign);
7413         }
7414         else if(shCount >= 8){
7415                 shCount -= 8;
7416                 if(shCount == 1)
7417                         shiftRLong(left, MSB16, result, sign);
7418                 else if(shCount == 0){
7419                         movLeft2Result(left, MSB16, result, LSB);
7420                         movLeft2Result(left, MSB24, result, MSB16);
7421                         movLeft2Result(left, MSB32, result, MSB24);
7422                         addSign(result, MSB32, sign);
7423                 }
7424                 else{
7425                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7426                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7427                         /* the last shift is signed */
7428                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7429                         addSign(result, MSB32, sign);
7430                 }
7431         }
7432         else{   /* 1 <= shCount <= 7 */
7433                 if(shCount <= 2){
7434                         shiftRLong(left, LSB, result, sign);
7435                         if(shCount == 2)
7436                                 shiftRLong(result, LSB, result, sign);
7437                 }
7438                 else{
7439                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7440                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7441                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7442                 }
7443         }
7444 }
7445
7446 /*-----------------------------------------------------------------*/
7447 /* genRightShiftLiteral - right shifting by known count            */
7448 /*-----------------------------------------------------------------*/
7449 static void genRightShiftLiteral (operand *left,
7450                                                                   operand *right,
7451                                                                   operand *result,
7452                                                                   iCode *ic,
7453                                                                   int sign)
7454 {    
7455         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7456         int lsize,res_size;
7457         
7458         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7459         freeAsmop(right,NULL,ic,TRUE);
7460         
7461         aopOp(left,ic,FALSE);
7462         aopOp(result,ic,FALSE);
7463         
7464 #if VIEW_SIZE
7465         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7466                 AOP_SIZE(left));
7467 #endif
7468         
7469         lsize = pic14_getDataSize(left);
7470         res_size = pic14_getDataSize(result);
7471         /* test the LEFT size !!! */
7472         
7473         /* I suppose that the left size >= result size */
7474         if(shCount == 0){
7475                 while(res_size--)
7476                         movLeft2Result(left, lsize, result, res_size);
7477         }
7478         
7479         else if(shCount >= (lsize * 8)){
7480                 
7481                 if(res_size == 1) {
7482                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7483                         if(sign) {
7484                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7485                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7486                         }
7487                 } else {
7488                         
7489                         if(sign) {
7490                                 emitpcode(POC_MOVLW, popGetLit(0));
7491                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7492                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7493                                 while(res_size--)
7494                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7495                                 
7496                         } else {
7497                                 
7498                                 while(res_size--)
7499                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7500                         }
7501                 }
7502         } else {
7503                 
7504                 switch (res_size) {
7505                 case 1:
7506                         genrshOne (result,left,shCount,sign);
7507                         break;
7508                         
7509                 case 2:
7510                         genrshTwo (result,left,shCount,sign);
7511                         break;
7512                         
7513                 case 4:
7514                         genrshFour (result,left,shCount,sign);
7515                         break;
7516                 default :
7517                         break;
7518                 }
7519                 
7520         }
7521         
7522         freeAsmop(left,NULL,ic,TRUE);
7523         freeAsmop(result,NULL,ic,TRUE);
7524 }
7525
7526 /*-----------------------------------------------------------------*/
7527 /* genSignedRightShift - right shift of signed number              */
7528 /*-----------------------------------------------------------------*/
7529 static void genSignedRightShift (iCode *ic)
7530 {
7531         operand *right, *left, *result;
7532         int size, offset;
7533         //  char *l;
7534         symbol *tlbl, *tlbl1 ;
7535         pCodeOp *pctemp;
7536         
7537         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7538         
7539         /* we do it the hard way put the shift count in b
7540         and loop thru preserving the sign */
7541         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7542         
7543         right = IC_RIGHT(ic);
7544         left  = IC_LEFT(ic);
7545         result = IC_RESULT(ic);
7546         
7547         aopOp(right,ic,FALSE);  
7548         aopOp(left,ic,FALSE);
7549         aopOp(result,ic,FALSE);
7550         
7551         
7552         if ( AOP_TYPE(right) == AOP_LIT) {
7553                 genRightShiftLiteral (left,right,result,ic,1);
7554                 return ;
7555         }
7556         /* shift count is unknown then we have to form 
7557         a loop get the loop count in B : Note: we take
7558         only the lower order byte since shifting
7559         more that 32 bits make no sense anyway, ( the
7560         largest size of an object can be only 32 bits ) */  
7561         
7562         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7563         //pic14_emitcode("inc","b");
7564         //freeAsmop (right,NULL,ic,TRUE);
7565         //aopOp(left,ic,FALSE);
7566         //aopOp(result,ic,FALSE);
7567         
7568         /* now move the left to the result if they are not the
7569         same */
7570         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7571                 AOP_SIZE(result) > 1) {
7572                 
7573                 size = AOP_SIZE(result);
7574                 offset=0;
7575                 while (size--) { 
7576                 /*
7577                 l = aopGet(AOP(left),offset,FALSE,TRUE);
7578                 if (*l == '@' && IS_AOP_PREG(result)) {
7579                 
7580                   pic14_emitcode("mov","a,%s",l);
7581                   aopPut(AOP(result),"a",offset);
7582                   } else
7583                   aopPut(AOP(result),l,offset);
7584                         */
7585                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7586                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7587                         
7588                         offset++;
7589                 }
7590         }
7591         
7592         /* mov the highest order bit to OVR */    
7593         tlbl = newiTempLabel(NULL);
7594         tlbl1= newiTempLabel(NULL);
7595         
7596         size = AOP_SIZE(result);
7597         offset = size - 1;
7598         
7599         pctemp = popGetTempReg();  /* grab a temporary working register. */
7600         
7601         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7602         
7603         /* offset should be 0, 1 or 3 */
7604         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7605         emitSKPNZ;
7606         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7607         
7608         emitpcode(POC_MOVWF, pctemp);
7609         
7610         
7611         emitpLabel(tlbl->key);
7612         
7613         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7614         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7615         
7616         while(--size) {
7617                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7618         }
7619         
7620         emitpcode(POC_DECFSZ,  pctemp);
7621         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7622         emitpLabel(tlbl1->key);
7623         
7624         popReleaseTempReg(pctemp);
7625 #if 0
7626         size = AOP_SIZE(result);
7627         offset = size - 1;
7628         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7629         pic14_emitcode("rlc","a");
7630         pic14_emitcode("mov","ov,c");
7631         /* if it is only one byte then */
7632         if (size == 1) {
7633                 l = aopGet(AOP(left),0,FALSE,FALSE);
7634                 MOVA(l);
7635                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7636                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7637                 pic14_emitcode("mov","c,ov");
7638                 pic14_emitcode("rrc","a");
7639                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7640                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7641                 aopPut(AOP(result),"a",0);
7642                 goto release ;
7643         }
7644         
7645         reAdjustPreg(AOP(result));
7646         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7647         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7648         pic14_emitcode("mov","c,ov");
7649         while (size--) {
7650                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7651                 MOVA(l);
7652                 pic14_emitcode("rrc","a");         
7653                 aopPut(AOP(result),"a",offset--);
7654         }
7655         reAdjustPreg(AOP(result));
7656         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7657         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7658         
7659 release:
7660 #endif
7661         
7662         freeAsmop(left,NULL,ic,TRUE);
7663         freeAsmop(result,NULL,ic,TRUE);
7664         freeAsmop(right,NULL,ic,TRUE);
7665 }
7666
7667 /*-----------------------------------------------------------------*/
7668 /* genRightShift - generate code for right shifting                */
7669 /*-----------------------------------------------------------------*/
7670 static void genRightShift (iCode *ic)
7671 {
7672         operand *right, *left, *result;
7673         sym_link *retype ;
7674         int size, offset;
7675         char *l;
7676         symbol *tlbl, *tlbl1 ;
7677         
7678         /* if signed then we do it the hard way preserve the
7679         sign bit moving it inwards */
7680         retype = getSpec(operandType(IC_RESULT(ic)));
7681         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7682         
7683         if (!SPEC_USIGN(retype)) {
7684                 genSignedRightShift (ic);
7685                 return ;
7686         }
7687         
7688         /* signed & unsigned types are treated the same : i.e. the
7689         signed is NOT propagated inwards : quoting from the
7690         ANSI - standard : "for E1 >> E2, is equivalent to division
7691         by 2**E2 if unsigned or if it has a non-negative value,
7692         otherwise the result is implementation defined ", MY definition
7693         is that the sign does not get propagated */
7694         
7695         right = IC_RIGHT(ic);
7696         left  = IC_LEFT(ic);
7697         result = IC_RESULT(ic);
7698         
7699         aopOp(right,ic,FALSE);
7700         
7701         /* if the shift count is known then do it 
7702         as efficiently as possible */
7703         if (AOP_TYPE(right) == AOP_LIT) {
7704                 genRightShiftLiteral (left,right,result,ic, 0);
7705                 return ;
7706         }
7707         
7708         /* shift count is unknown then we have to form 
7709         a loop get the loop count in B : Note: we take
7710         only the lower order byte since shifting
7711         more that 32 bits make no sense anyway, ( the
7712         largest size of an object can be only 32 bits ) */  
7713         
7714         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7715         pic14_emitcode("inc","b");
7716         aopOp(left,ic,FALSE);
7717         aopOp(result,ic,FALSE);
7718         
7719         /* now move the left to the result if they are not the
7720         same */
7721         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7722                 AOP_SIZE(result) > 1) {
7723                 
7724                 size = AOP_SIZE(result);
7725                 offset=0;
7726                 while (size--) {
7727                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7728                         if (*l == '@' && IS_AOP_PREG(result)) {
7729                                 
7730                                 pic14_emitcode("mov","a,%s",l);
7731                                 aopPut(AOP(result),"a",offset);
7732                         } else
7733                                 aopPut(AOP(result),l,offset);
7734                         offset++;
7735                 }
7736         }
7737         
7738         tlbl = newiTempLabel(NULL);
7739         tlbl1= newiTempLabel(NULL);
7740         size = AOP_SIZE(result);
7741         offset = size - 1;
7742         
7743         /* if it is only one byte then */
7744         if (size == 1) {
7745                 
7746                 tlbl = newiTempLabel(NULL);
7747                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7748                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7749                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7750                 }
7751                 
7752                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7753                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7754                 emitpLabel(tlbl->key);
7755                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7756                 emitpcode(POC_ADDLW,  popGetLit(1));
7757                 emitSKPC;
7758                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7759                 
7760                 goto release ;
7761         }
7762         
7763         reAdjustPreg(AOP(result));
7764         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7765         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7766         CLRC;
7767         while (size--) {
7768                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7769                 MOVA(l);
7770                 pic14_emitcode("rrc","a");         
7771                 aopPut(AOP(result),"a",offset--);
7772         }
7773         reAdjustPreg(AOP(result));
7774         
7775         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7776         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7777         
7778 release:
7779         freeAsmop(left,NULL,ic,TRUE);
7780         freeAsmop (right,NULL,ic,TRUE);
7781         freeAsmop(result,NULL,ic,TRUE);
7782 }
7783
7784 /*-----------------------------------------------------------------*/
7785 /* genUnpackBits - generates code for unpacking bits               */
7786 /*-----------------------------------------------------------------*/
7787 static void genUnpackBits (operand *result, char *rname, int ptype)
7788 {    
7789         int shCnt ;
7790         int rlen = 0 ;
7791         sym_link *etype;
7792         int offset = 0 ;
7793         
7794         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7795         etype = getSpec(operandType(result));
7796         
7797         /* read the first byte  */
7798         switch (ptype) {
7799                 
7800         case POINTER:
7801         case IPOINTER:
7802                 pic14_emitcode("mov","a,@%s",rname);
7803                 break;
7804                 
7805         case PPOINTER:
7806                 pic14_emitcode("movx","a,@%s",rname);
7807                 break;
7808                 
7809         case FPOINTER:
7810                 pic14_emitcode("movx","a,@dptr");
7811                 break;
7812                 
7813         case CPOINTER:
7814                 pic14_emitcode("clr","a");
7815                 pic14_emitcode("movc","a","@a+dptr");
7816                 break;
7817                 
7818         case GPOINTER:
7819                 pic14_emitcode("lcall","__gptrget");
7820                 break;
7821         }
7822         
7823         /* if we have bitdisplacement then it fits   */
7824         /* into this byte completely or if length is */
7825         /* less than a byte                          */
7826         if ((shCnt = SPEC_BSTR(etype)) || 
7827                 (SPEC_BLEN(etype) <= 8))  {
7828                 
7829                 /* shift right acc */
7830                 AccRsh(shCnt);
7831                 
7832                 pic14_emitcode("anl","a,#0x%02x",
7833                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7834                 aopPut(AOP(result),"a",offset);
7835                 return ;
7836         }
7837         
7838         /* bit field did not fit in a byte  */
7839         rlen = SPEC_BLEN(etype) - 8;
7840         aopPut(AOP(result),"a",offset++);
7841         
7842         while (1)  {
7843                 
7844                 switch (ptype) {
7845                 case POINTER:
7846                 case IPOINTER:
7847                         pic14_emitcode("inc","%s",rname);
7848                         pic14_emitcode("mov","a,@%s",rname);
7849                         break;
7850                         
7851                 case PPOINTER:
7852                         pic14_emitcode("inc","%s",rname);
7853                         pic14_emitcode("movx","a,@%s",rname);
7854                         break;
7855                         
7856                 case FPOINTER:
7857                         pic14_emitcode("inc","dptr");
7858                         pic14_emitcode("movx","a,@dptr");
7859                         break;
7860                         
7861                 case CPOINTER:
7862                         pic14_emitcode("clr","a");
7863                         pic14_emitcode("inc","dptr");
7864                         pic14_emitcode("movc","a","@a+dptr");
7865                         break;
7866                         
7867                 case GPOINTER:
7868                         pic14_emitcode("inc","dptr");
7869                         pic14_emitcode("lcall","__gptrget");
7870                         break;
7871                 }
7872                 
7873                 rlen -= 8;            
7874                 /* if we are done */
7875                 if ( rlen <= 0 )
7876                         break ;
7877                 
7878                 aopPut(AOP(result),"a",offset++);
7879                 
7880         }
7881         
7882         if (rlen) {
7883                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7884                 aopPut(AOP(result),"a",offset);        
7885         }
7886         
7887         return ;
7888 }
7889
7890 #if 0
7891 /*-----------------------------------------------------------------*/
7892 /* genDataPointerGet - generates code when ptr offset is known     */
7893 /*-----------------------------------------------------------------*/
7894 static void genDataPointerGet (operand *left, 
7895                                                            operand *result, 
7896                                                            iCode *ic)
7897 {
7898         int size , offset = 0;
7899         
7900         
7901         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7902         
7903         
7904         /* optimization - most of the time, left and result are the same
7905         * address, but different types. for the pic code, we could omit
7906         * the following
7907         */
7908         
7909         aopOp(result,ic,TRUE);
7910         
7911         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7912         
7913         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7914         
7915         size = AOP_SIZE(result);
7916         
7917         while (size--) {
7918                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7919                 offset++;
7920         }
7921         
7922         freeAsmop(left,NULL,ic,TRUE);
7923         freeAsmop(result,NULL,ic,TRUE);
7924 }
7925 #endif
7926 /*-----------------------------------------------------------------*/
7927 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7928 /*-----------------------------------------------------------------*/
7929 static void genNearPointerGet (operand *left, 
7930                                                            operand *result, 
7931                                                            iCode *ic)
7932 {
7933         asmop *aop = NULL;
7934         //regs *preg = NULL ;
7935         char *rname ;
7936         sym_link *rtype, *retype;
7937         sym_link *ltype = operandType(left);    
7938         //char buffer[80];
7939         
7940         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7941         
7942         rtype = operandType(result);
7943         retype= getSpec(rtype);
7944         
7945         aopOp(left,ic,FALSE);
7946         
7947         /* if left is rematerialisable and
7948         result is not bit variable type and
7949         the left is pointer to data space i.e
7950         lower 128 bytes of space */
7951         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7952                 !IS_BITVAR(retype)         &&
7953                 DCL_TYPE(ltype) == POINTER) {
7954                 //genDataPointerGet (left,result,ic);
7955                 return ;
7956         }
7957         
7958         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7959         
7960         /* if the value is already in a pointer register
7961         then don't need anything more */
7962         if (!AOP_INPREG(AOP(left))) {
7963                 /* otherwise get a free pointer register */
7964                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7965                 /*
7966                 aop = newAsmop(0);
7967                 preg = getFreePtr(ic,&aop,FALSE);
7968                 pic14_emitcode("mov","%s,%s",
7969                 preg->name,
7970                 aopGet(AOP(left),0,FALSE,TRUE));
7971                 rname = preg->name ;
7972                 */
7973                 rname ="BAD";
7974         } else
7975                 rname = aopGet(AOP(left),0,FALSE,FALSE);
7976         
7977         aopOp (result,ic,FALSE);
7978         
7979         /* if bitfield then unpack the bits */
7980         if (IS_BITVAR(retype)) 
7981                 genUnpackBits (result,rname,POINTER);
7982         else {
7983                 /* we have can just get the values */
7984                 int size = AOP_SIZE(result);
7985                 int offset = 0 ;        
7986                 
7987                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7988                 
7989                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7990                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7991                 while(size--) {
7992                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7993                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7994                         if(size)
7995                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7996                 }
7997                 /*
7998                 while (size--) {
7999                 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8000
8001                         pic14_emitcode("mov","a,@%s",rname);
8002                         aopPut(AOP(result),"a",offset);
8003                         } else {
8004                         sprintf(buffer,"@%s",rname);
8005                         aopPut(AOP(result),buffer,offset);
8006                         }
8007                         offset++ ;
8008                         if (size)
8009                         pic14_emitcode("inc","%s",rname);
8010                 }
8011                 */
8012         }
8013         
8014         /* now some housekeeping stuff */
8015         if (aop) {
8016                 /* we had to allocate for this iCode */
8017                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8018                 freeAsmop(NULL,aop,ic,TRUE);
8019         } else { 
8020         /* we did not allocate which means left
8021            already in a pointer register, then
8022            if size > 0 && this could be used again
8023            we have to point it back to where it 
8024                 belongs */
8025                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8026                 if (AOP_SIZE(result) > 1 &&
8027                         !OP_SYMBOL(left)->remat &&
8028                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8029                         ic->depth )) {
8030                         int size = AOP_SIZE(result) - 1;
8031                         while (size--)
8032                                 pic14_emitcode("dec","%s",rname);
8033                 }
8034         }
8035         
8036         /* done */
8037         freeAsmop(left,NULL,ic,TRUE);
8038         freeAsmop(result,NULL,ic,TRUE);
8039         
8040 }
8041
8042 /*-----------------------------------------------------------------*/
8043 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8044 /*-----------------------------------------------------------------*/
8045 static void genPagedPointerGet (operand *left, 
8046                                                                 operand *result, 
8047                                                                 iCode *ic)
8048 {
8049         asmop *aop = NULL;
8050         regs *preg = NULL ;
8051         char *rname ;
8052         sym_link *rtype, *retype;    
8053         
8054         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8055         
8056         rtype = operandType(result);
8057         retype= getSpec(rtype);
8058         
8059         aopOp(left,ic,FALSE);
8060         
8061         /* if the value is already in a pointer register
8062         then don't need anything more */
8063         if (!AOP_INPREG(AOP(left))) {
8064                 /* otherwise get a free pointer register */
8065                 aop = newAsmop(0);
8066                 preg = getFreePtr(ic,&aop,FALSE);
8067                 pic14_emitcode("mov","%s,%s",
8068                         preg->name,
8069                         aopGet(AOP(left),0,FALSE,TRUE));
8070                 rname = preg->name ;
8071         } else
8072                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8073         
8074         freeAsmop(left,NULL,ic,TRUE);
8075         aopOp (result,ic,FALSE);
8076         
8077         /* if bitfield then unpack the bits */
8078         if (IS_BITVAR(retype)) 
8079                 genUnpackBits (result,rname,PPOINTER);
8080         else {
8081                 /* we have can just get the values */
8082                 int size = AOP_SIZE(result);
8083                 int offset = 0 ;        
8084                 
8085                 while (size--) {
8086                         
8087                         pic14_emitcode("movx","a,@%s",rname);
8088                         aopPut(AOP(result),"a",offset);
8089                         
8090                         offset++ ;
8091                         
8092                         if (size)
8093                                 pic14_emitcode("inc","%s",rname);
8094                 }
8095         }
8096         
8097         /* now some housekeeping stuff */
8098         if (aop) {
8099                 /* we had to allocate for this iCode */
8100                 freeAsmop(NULL,aop,ic,TRUE);
8101         } else { 
8102         /* we did not allocate which means left
8103            already in a pointer register, then
8104            if size > 0 && this could be used again
8105            we have to point it back to where it 
8106                 belongs */
8107                 if (AOP_SIZE(result) > 1 &&
8108                         !OP_SYMBOL(left)->remat &&
8109                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8110                         ic->depth )) {
8111                         int size = AOP_SIZE(result) - 1;
8112                         while (size--)
8113                                 pic14_emitcode("dec","%s",rname);
8114                 }
8115         }
8116         
8117         /* done */
8118         freeAsmop(result,NULL,ic,TRUE);
8119         
8120         
8121 }
8122
8123 /*-----------------------------------------------------------------*/
8124 /* genFarPointerGet - gget value from far space                    */
8125 /*-----------------------------------------------------------------*/
8126 static void genFarPointerGet (operand *left,
8127                                                           operand *result, iCode *ic)
8128 {
8129         int size, offset ;
8130         sym_link *retype = getSpec(operandType(result));
8131         
8132         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8133         
8134         aopOp(left,ic,FALSE);
8135         
8136         /* if the operand is already in dptr 
8137         then we do nothing else we move the value to dptr */
8138         if (AOP_TYPE(left) != AOP_STR) {
8139                 /* if this is remateriazable */
8140                 if (AOP_TYPE(left) == AOP_IMMD)
8141                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8142                 else { /* we need to get it byte by byte */
8143                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8144                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8145                         if (options.model == MODEL_FLAT24)
8146                         {
8147                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8148                         }
8149                 }
8150         }
8151         /* so dptr know contains the address */
8152         freeAsmop(left,NULL,ic,TRUE);
8153         aopOp(result,ic,FALSE);
8154         
8155         /* if bit then unpack */
8156         if (IS_BITVAR(retype)) 
8157                 genUnpackBits(result,"dptr",FPOINTER);
8158         else {
8159                 size = AOP_SIZE(result);
8160                 offset = 0 ;
8161                 
8162                 while (size--) {
8163                         pic14_emitcode("movx","a,@dptr");
8164                         aopPut(AOP(result),"a",offset++);
8165                         if (size)
8166                                 pic14_emitcode("inc","dptr");
8167                 }
8168         }
8169         
8170         freeAsmop(result,NULL,ic,TRUE);
8171 }
8172 #if 0
8173 /*-----------------------------------------------------------------*/
8174 /* genCodePointerGet - get value from code space                  */
8175 /*-----------------------------------------------------------------*/
8176 static void genCodePointerGet (operand *left,
8177                                                            operand *result, iCode *ic)
8178 {
8179         int size, offset ;
8180         sym_link *retype = getSpec(operandType(result));
8181         
8182         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8183         
8184         aopOp(left,ic,FALSE);
8185         
8186         /* if the operand is already in dptr 
8187         then we do nothing else we move the value to dptr */
8188         if (AOP_TYPE(left) != AOP_STR) {
8189                 /* if this is remateriazable */
8190                 if (AOP_TYPE(left) == AOP_IMMD)
8191                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8192                 else { /* we need to get it byte by byte */
8193                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8194                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8195                         if (options.model == MODEL_FLAT24)
8196                         {
8197                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8198                         }
8199                 }
8200         }
8201         /* so dptr know contains the address */
8202         freeAsmop(left,NULL,ic,TRUE);
8203         aopOp(result,ic,FALSE);
8204         
8205         /* if bit then unpack */
8206         if (IS_BITVAR(retype)) 
8207                 genUnpackBits(result,"dptr",CPOINTER);
8208         else {
8209                 size = AOP_SIZE(result);
8210                 offset = 0 ;
8211                 
8212                 while (size--) {
8213                         pic14_emitcode("clr","a");
8214                         pic14_emitcode("movc","a,@a+dptr");
8215                         aopPut(AOP(result),"a",offset++);
8216                         if (size)
8217                                 pic14_emitcode("inc","dptr");
8218                 }
8219         }
8220         
8221         freeAsmop(result,NULL,ic,TRUE);
8222 }
8223 #endif
8224 /*-----------------------------------------------------------------*/
8225 /* genGenPointerGet - gget value from generic pointer space        */
8226 /*-----------------------------------------------------------------*/
8227 static void genGenPointerGet (operand *left,
8228                                                           operand *result, iCode *ic)
8229 {
8230         int size, offset ;
8231         sym_link *retype = getSpec(operandType(result));
8232         
8233         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8234         aopOp(left,ic,FALSE);
8235         aopOp(result,ic,FALSE);
8236         
8237         
8238         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8239         
8240         /* if the operand is already in dptr 
8241         then we do nothing else we move the value to dptr */
8242         //  if (AOP_TYPE(left) != AOP_STR) {
8243         /* if this is remateriazable */
8244         if (AOP_TYPE(left) == AOP_IMMD) {
8245                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8246                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8247         }
8248         else { /* we need to get it byte by byte */
8249                 
8250                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8251                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8252                 
8253                 size = AOP_SIZE(result);
8254                 offset = 0 ;
8255                 
8256                 while(size--) {
8257                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8258                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8259                         if(size)
8260                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8261                 }
8262                 goto release;
8263         }
8264         //}
8265         /* so dptr know contains the address */
8266         
8267         /* if bit then unpack */
8268         //if (IS_BITVAR(retype)) 
8269         //  genUnpackBits(result,"dptr",GPOINTER);
8270         
8271 release:
8272         freeAsmop(left,NULL,ic,TRUE);
8273         freeAsmop(result,NULL,ic,TRUE);
8274         
8275 }
8276
8277 /*-----------------------------------------------------------------*/
8278 /* genConstPointerGet - get value from const generic pointer space */
8279 /*-----------------------------------------------------------------*/
8280 static void genConstPointerGet (operand *left,
8281                                                                 operand *result, iCode *ic)
8282 {
8283         //sym_link *retype = getSpec(operandType(result));
8284         symbol *albl = newiTempLabel(NULL);
8285         symbol *blbl = newiTempLabel(NULL);
8286         PIC_OPCODE poc;
8287         pCodeOp *pcop;
8288         
8289         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8290         aopOp(left,ic,FALSE);
8291         aopOp(result,ic,FALSE);
8292         
8293         
8294         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8295         
8296         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8297         
8298         emitpcode(POC_CALL,popGetLabel(albl->key));
8299         pcop = popGetLabel(blbl->key);
8300         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8301         emitpcode(POC_GOTO,pcop);
8302         emitpLabel(albl->key);
8303         
8304         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8305         
8306         emitpcode(poc,popGet(AOP(left),1));
8307         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8308         emitpcode(poc,popGet(AOP(left),0));
8309         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8310         
8311         emitpLabel(blbl->key);
8312         
8313         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8314         
8315         
8316         freeAsmop(left,NULL,ic,TRUE);
8317         freeAsmop(result,NULL,ic,TRUE);
8318         
8319 }
8320 /*-----------------------------------------------------------------*/
8321 /* genPointerGet - generate code for pointer get                   */
8322 /*-----------------------------------------------------------------*/
8323 static void genPointerGet (iCode *ic)
8324 {
8325         operand *left, *result ;
8326         sym_link *type, *etype;
8327         int p_type;
8328         
8329         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8330         
8331         left = IC_LEFT(ic);
8332         result = IC_RESULT(ic) ;
8333         
8334         /* depending on the type of pointer we need to
8335         move it to the correct pointer register */
8336         type = operandType(left);
8337         etype = getSpec(type);
8338         
8339         if (IS_PTR_CONST(type))
8340                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8341         
8342         /* if left is of type of pointer then it is simple */
8343         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8344                 p_type = DCL_TYPE(type);
8345         else {
8346                 /* we have to go by the storage class */
8347                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8348                 
8349                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8350                 
8351                 if (SPEC_OCLS(etype)->codesp ) {
8352                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8353                         //p_type = CPOINTER ;   
8354                 }
8355                 else
8356                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8357                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8358                         /*p_type = FPOINTER ;*/ 
8359                         else
8360                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8361                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8362                                 /*                  p_type = PPOINTER; */
8363                                 else
8364                                         if (SPEC_OCLS(etype) == idata )
8365                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8366                                         /*                      p_type = IPOINTER; */
8367                                         else
8368                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8369                                         /*                      p_type = POINTER ; */
8370         }
8371         
8372         /* now that we have the pointer type we assign
8373         the pointer values */
8374         switch (p_type) {
8375                 
8376         case POINTER:   
8377         case IPOINTER:
8378                 genNearPointerGet (left,result,ic);
8379                 break;
8380                 
8381         case PPOINTER:
8382                 genPagedPointerGet(left,result,ic);
8383                 break;
8384                 
8385         case FPOINTER:
8386                 genFarPointerGet (left,result,ic);
8387                 break;
8388                 
8389         case CPOINTER:
8390                 genConstPointerGet (left,result,ic);
8391                 //pic14_emitcodePointerGet (left,result,ic);
8392                 break;
8393                 
8394         case GPOINTER:
8395                 if (IS_PTR_CONST(type))
8396                         genConstPointerGet (left,result,ic);
8397                 else
8398                         genGenPointerGet (left,result,ic);
8399                 break;
8400         }
8401         
8402 }
8403
8404 /*-----------------------------------------------------------------*/
8405 /* genPackBits - generates code for packed bit storage             */
8406 /*-----------------------------------------------------------------*/
8407 static void genPackBits (sym_link    *etype ,
8408                                                  operand *right ,
8409                                                  char *rname, int p_type)
8410 {
8411         int shCount = 0 ;
8412         int offset = 0  ;
8413         int rLen = 0 ;
8414         int blen, bstr ;   
8415         char *l ;
8416         
8417         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8418         blen = SPEC_BLEN(etype);
8419         bstr = SPEC_BSTR(etype);
8420         
8421         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8422         MOVA(l);   
8423         
8424         /* if the bit lenth is less than or    */
8425         /* it exactly fits a byte then         */
8426         if (SPEC_BLEN(etype) <= 8 )  {
8427                 shCount = SPEC_BSTR(etype) ;
8428                 
8429                 /* shift left acc */
8430                 AccLsh(shCount);
8431                 
8432                 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8433                         
8434                         
8435                         switch (p_type) {
8436                         case POINTER:
8437                                 pic14_emitcode ("mov","b,a");
8438                                 pic14_emitcode("mov","a,@%s",rname);
8439                                 break;
8440                                 
8441                         case FPOINTER:
8442                                 pic14_emitcode ("mov","b,a");
8443                                 pic14_emitcode("movx","a,@dptr");
8444                                 break;
8445                                 
8446                         case GPOINTER:
8447                                 pic14_emitcode ("push","b");
8448                                 pic14_emitcode ("push","acc");
8449                                 pic14_emitcode ("lcall","__gptrget");
8450                                 pic14_emitcode ("pop","b");
8451                                 break;
8452                         }
8453                         
8454                         pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8455                                 ((unsigned char)(0xFF << (blen+bstr)) | 
8456                                 (unsigned char)(0xFF >> (8-bstr)) ) );
8457                         pic14_emitcode ("orl","a,b");
8458                         if (p_type == GPOINTER)
8459                                 pic14_emitcode("pop","b");
8460                 }
8461         }
8462         
8463         switch (p_type) {
8464         case POINTER:
8465                 pic14_emitcode("mov","@%s,a",rname);
8466                 break;
8467                 
8468         case FPOINTER:
8469                 pic14_emitcode("movx","@dptr,a");
8470                 break;
8471                 
8472         case GPOINTER:
8473                 DEBUGpic14_emitcode(";lcall","__gptrput");
8474                 break;
8475         }
8476         
8477         /* if we r done */
8478         if ( SPEC_BLEN(etype) <= 8 )
8479                 return ;
8480         
8481         pic14_emitcode("inc","%s",rname);
8482         rLen = SPEC_BLEN(etype) ;     
8483         
8484         /* now generate for lengths greater than one byte */
8485         while (1) {
8486                 
8487                 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8488                 
8489                 rLen -= 8 ;
8490                 if (rLen <= 0 )
8491                         break ;
8492                 
8493                 switch (p_type) {
8494                 case POINTER:
8495                         if (*l == '@') {
8496                                 MOVA(l);
8497                                 pic14_emitcode("mov","@%s,a",rname);
8498                         } else
8499                                 pic14_emitcode("mov","@%s,%s",rname,l);
8500                         break;
8501                         
8502                 case FPOINTER:
8503                         MOVA(l);
8504                         pic14_emitcode("movx","@dptr,a");
8505                         break;
8506                         
8507                 case GPOINTER:
8508                         MOVA(l);
8509                         DEBUGpic14_emitcode(";lcall","__gptrput");
8510                         break;  
8511                 }   
8512                 pic14_emitcode ("inc","%s",rname);
8513         }
8514         
8515         MOVA(l);
8516         
8517         /* last last was not complete */
8518         if (rLen)   {
8519                 /* save the byte & read byte */
8520                 switch (p_type) {
8521                 case POINTER:
8522                         pic14_emitcode ("mov","b,a");
8523                         pic14_emitcode("mov","a,@%s",rname);
8524                         break;
8525                         
8526                 case FPOINTER:
8527                         pic14_emitcode ("mov","b,a");
8528                         pic14_emitcode("movx","a,@dptr");
8529                         break;
8530                         
8531                 case GPOINTER:
8532                         pic14_emitcode ("push","b");
8533                         pic14_emitcode ("push","acc");
8534                         pic14_emitcode ("lcall","__gptrget");
8535                         pic14_emitcode ("pop","b");
8536                         break;
8537                 }
8538                 
8539                 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8540                 pic14_emitcode ("orl","a,b");
8541         }
8542         
8543         if (p_type == GPOINTER)
8544                 pic14_emitcode("pop","b");
8545         
8546         switch (p_type) {
8547                 
8548         case POINTER:
8549                 pic14_emitcode("mov","@%s,a",rname);
8550                 break;
8551                 
8552         case FPOINTER:
8553                 pic14_emitcode("movx","@dptr,a");
8554                 break;
8555                 
8556         case GPOINTER:
8557                 DEBUGpic14_emitcode(";lcall","__gptrput");
8558                 break;                  
8559         }
8560 }
8561 /*-----------------------------------------------------------------*/
8562 /* genDataPointerSet - remat pointer to data space                 */
8563 /*-----------------------------------------------------------------*/
8564 static void genDataPointerSet(operand *right,
8565                                                           operand *result,
8566                                                           iCode *ic)
8567 {
8568         int size, offset = 0 ;
8569         char *l, buffer[256];
8570         
8571         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8572         aopOp(right,ic,FALSE);
8573         
8574         l = aopGet(AOP(result),0,FALSE,TRUE);
8575         size = AOP_SIZE(right);
8576         /*
8577         if ( AOP_TYPE(result) == AOP_PCODE) {
8578         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8579         AOP(result)->aopu.pcop->name,
8580         PCOI(AOP(result)->aopu.pcop)->offset);
8581         }
8582         */
8583         
8584         // tsd, was l+1 - the underline `_' prefix was being stripped
8585         while (size--) {
8586                 if (offset) {
8587                         sprintf(buffer,"(%s + %d)",l,offset);
8588                         fprintf(stderr,"oops  %s\n",buffer);
8589                 } else
8590                         sprintf(buffer,"%s",l);
8591                 
8592                 if (AOP_TYPE(right) == AOP_LIT) {
8593                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8594                         lit = lit >> (8*offset);
8595                         if(lit&0xff) {
8596                                 pic14_emitcode("movlw","%d",lit);
8597                                 pic14_emitcode("movwf","%s",buffer);
8598                                 
8599                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8600                                 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8601                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8602                                 
8603                         } else {
8604                                 pic14_emitcode("clrf","%s",buffer);
8605                                 //emitpcode(POC_CLRF, popRegFromString(buffer));
8606                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8607                         }
8608                 }else {
8609                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8610                         pic14_emitcode("movwf","%s",buffer);
8611                         
8612                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8613                         //emitpcode(POC_MOVWF, popRegFromString(buffer));
8614                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8615                         
8616                 }
8617                 
8618                 offset++;
8619         }
8620         
8621         freeAsmop(right,NULL,ic,TRUE);
8622         freeAsmop(result,NULL,ic,TRUE);
8623 }
8624
8625 /*-----------------------------------------------------------------*/
8626 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8627 /*-----------------------------------------------------------------*/
8628 static void genNearPointerSet (operand *right,
8629                                                            operand *result, 
8630                                                            iCode *ic)
8631 {
8632         asmop *aop = NULL;
8633         char *l;
8634         sym_link *retype;
8635         sym_link *ptype = operandType(result);
8636         
8637         
8638         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8639         retype= getSpec(operandType(right));
8640         
8641         aopOp(result,ic,FALSE);
8642         
8643         
8644         /* if the result is rematerializable &
8645         in data space & not a bit variable */
8646         //if (AOP_TYPE(result) == AOP_IMMD &&
8647         if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8648                 DCL_TYPE(ptype) == POINTER   &&
8649                 !IS_BITVAR(retype)) {
8650                 genDataPointerSet (right,result,ic);
8651                 freeAsmop(result,NULL,ic,TRUE);
8652                 return;
8653         }
8654         
8655         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8656         aopOp(right,ic,FALSE);
8657         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8658         
8659         /* if the value is already in a pointer register
8660         then don't need anything more */
8661         if (!AOP_INPREG(AOP(result))) {
8662                 /* otherwise get a free pointer register */
8663                 //aop = newAsmop(0);
8664                 //preg = getFreePtr(ic,&aop,FALSE);
8665                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8666                 //pic14_emitcode("mov","%s,%s",
8667                 //         preg->name,
8668                 //         aopGet(AOP(result),0,FALSE,TRUE));
8669                 //rname = preg->name ;
8670                 //pic14_emitcode("movwf","fsr");
8671                 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8672                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8673                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8674                 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8675                 goto release;
8676                 
8677         }// else
8678         //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8679         
8680         
8681         /* if bitfield then unpack the bits */
8682         if (IS_BITVAR(retype)) {
8683                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8684                         "The programmer is obviously confused");
8685                 //genPackBits (retype,right,rname,POINTER);
8686                 exit(1);
8687         }
8688         else {
8689                 /* we have can just get the values */
8690                 int size = AOP_SIZE(right);
8691                 int offset = 0 ;    
8692                 
8693                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8694                 while (size--) {
8695                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8696                         if (*l == '@' ) {
8697                                 //MOVA(l);
8698                                 //pic14_emitcode("mov","@%s,a",rname);
8699                                 pic14_emitcode("movf","indf,w ;1");
8700                         } else {
8701                                 
8702                                 if (AOP_TYPE(right) == AOP_LIT) {
8703                                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8704                                         if(lit) {
8705                                                 pic14_emitcode("movlw","%s",l);
8706                                                 pic14_emitcode("movwf","indf ;2");
8707                                         } else 
8708                                                 pic14_emitcode("clrf","indf");
8709                                 }else {
8710                                         pic14_emitcode("movf","%s,w",l);
8711                                         pic14_emitcode("movwf","indf ;2");
8712                                 }
8713                                 //pic14_emitcode("mov","@%s,%s",rname,l);
8714                         }
8715                         if (size)
8716                                 pic14_emitcode("incf","fsr,f ;3");
8717                         //pic14_emitcode("inc","%s",rname);
8718                         offset++;
8719                 }
8720         }
8721         
8722         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8723         /* now some housekeeping stuff */
8724         if (aop) {
8725                 /* we had to allocate for this iCode */
8726                 freeAsmop(NULL,aop,ic,TRUE);
8727         } else { 
8728         /* we did not allocate which means left
8729         already in a pointer register, then
8730         if size > 0 && this could be used again
8731         we have to point it back to where it 
8732                 belongs */
8733                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8734                 if (AOP_SIZE(right) > 1 &&
8735                         !OP_SYMBOL(result)->remat &&
8736                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8737                         ic->depth )) {
8738                         int size = AOP_SIZE(right) - 1;
8739                         while (size--)
8740                                 pic14_emitcode("decf","fsr,f");
8741                         //pic14_emitcode("dec","%s",rname);
8742                 }
8743         }
8744         
8745         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8746         /* done */
8747 release:
8748         freeAsmop(right,NULL,ic,TRUE);
8749         freeAsmop(result,NULL,ic,TRUE);
8750 }
8751
8752 /*-----------------------------------------------------------------*/
8753 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8754 /*-----------------------------------------------------------------*/
8755 static void genPagedPointerSet (operand *right,
8756                                                                 operand *result, 
8757                                                                 iCode *ic)
8758 {
8759         asmop *aop = NULL;
8760         regs *preg = NULL ;
8761         char *rname , *l;
8762         sym_link *retype;
8763         
8764         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8765         
8766         retype= getSpec(operandType(right));
8767         
8768         aopOp(result,ic,FALSE);
8769         
8770         /* if the value is already in a pointer register
8771         then don't need anything more */
8772         if (!AOP_INPREG(AOP(result))) {
8773                 /* otherwise get a free pointer register */
8774                 aop = newAsmop(0);
8775                 preg = getFreePtr(ic,&aop,FALSE);
8776                 pic14_emitcode("mov","%s,%s",
8777                         preg->name,
8778                         aopGet(AOP(result),0,FALSE,TRUE));
8779                 rname = preg->name ;
8780         } else
8781                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8782         
8783         freeAsmop(result,NULL,ic,TRUE);
8784         aopOp (right,ic,FALSE);
8785         
8786         /* if bitfield then unpack the bits */
8787         if (IS_BITVAR(retype)) 
8788                 genPackBits (retype,right,rname,PPOINTER);
8789         else {
8790                 /* we have can just get the values */
8791                 int size = AOP_SIZE(right);
8792                 int offset = 0 ;        
8793                 
8794                 while (size--) {
8795                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8796                         
8797                         MOVA(l);
8798                         pic14_emitcode("movx","@%s,a",rname);
8799                         
8800                         if (size)
8801                                 pic14_emitcode("inc","%s",rname);
8802                         
8803                         offset++;
8804                 }
8805         }
8806         
8807         /* now some housekeeping stuff */
8808         if (aop) {
8809                 /* we had to allocate for this iCode */
8810                 freeAsmop(NULL,aop,ic,TRUE);
8811         } else { 
8812         /* we did not allocate which means left
8813            already in a pointer register, then
8814            if size > 0 && this could be used again
8815            we have to point it back to where it 
8816                 belongs */
8817                 if (AOP_SIZE(right) > 1 &&
8818                         !OP_SYMBOL(result)->remat &&
8819                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8820                         ic->depth )) {
8821                         int size = AOP_SIZE(right) - 1;
8822                         while (size--)
8823                                 pic14_emitcode("dec","%s",rname);
8824                 }
8825         }
8826         
8827         /* done */
8828         freeAsmop(right,NULL,ic,TRUE);
8829         
8830         
8831 }
8832
8833 /*-----------------------------------------------------------------*/
8834 /* genFarPointerSet - set value from far space                     */
8835 /*-----------------------------------------------------------------*/
8836 static void genFarPointerSet (operand *right,
8837                                                           operand *result, iCode *ic)
8838 {
8839         int size, offset ;
8840         sym_link *retype = getSpec(operandType(right));
8841         
8842         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8843         aopOp(result,ic,FALSE);
8844         
8845         /* if the operand is already in dptr 
8846         then we do nothing else we move the value to dptr */
8847         if (AOP_TYPE(result) != AOP_STR) {
8848                 /* if this is remateriazable */
8849                 if (AOP_TYPE(result) == AOP_IMMD)
8850                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8851                 else { /* we need to get it byte by byte */
8852                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8853                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8854                         if (options.model == MODEL_FLAT24)
8855                         {
8856                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8857                         }
8858                 }
8859         }
8860         /* so dptr know contains the address */
8861         freeAsmop(result,NULL,ic,TRUE);
8862         aopOp(right,ic,FALSE);
8863         
8864         /* if bit then unpack */
8865         if (IS_BITVAR(retype)) 
8866                 genPackBits(retype,right,"dptr",FPOINTER);
8867         else {
8868                 size = AOP_SIZE(right);
8869                 offset = 0 ;
8870                 
8871                 while (size--) {
8872                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8873                         MOVA(l);
8874                         pic14_emitcode("movx","@dptr,a");
8875                         if (size)
8876                                 pic14_emitcode("inc","dptr");
8877                 }
8878         }
8879         
8880         freeAsmop(right,NULL,ic,TRUE);
8881 }
8882
8883 /*-----------------------------------------------------------------*/
8884 /* genGenPointerSet - set value from generic pointer space         */
8885 /*-----------------------------------------------------------------*/
8886 static void genGenPointerSet (operand *right,
8887                                                           operand *result, iCode *ic)
8888 {
8889         int size, offset ;
8890         sym_link *retype = getSpec(operandType(right));
8891         
8892         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8893         
8894         aopOp(result,ic,FALSE);
8895         aopOp(right,ic,FALSE);
8896         size = AOP_SIZE(right);
8897         
8898         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8899         
8900         /* if the operand is already in dptr 
8901         then we do nothing else we move the value to dptr */
8902         if (AOP_TYPE(result) != AOP_STR) {
8903                 /* if this is remateriazable */
8904                 if (AOP_TYPE(result) == AOP_IMMD) {
8905                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8906                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8907                 }
8908                 else { /* we need to get it byte by byte */
8909                         //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8910                         size = AOP_SIZE(right);
8911                         offset = 0 ;
8912                         
8913                         /* hack hack! see if this the FSR. If so don't load W */
8914                         if(AOP_TYPE(right) != AOP_ACC) {
8915                                 
8916                                 
8917                                 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8918                                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8919                                 
8920                                 if(AOP_SIZE(result) > 1) {
8921                                         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8922                                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8923                                         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8924                                         
8925                                 }
8926                                 
8927                                 //if(size==2)
8928                                 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8929                                 //if(size==4) {
8930                                 //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8931                                 //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8932                                 //}
8933                                 
8934                                 while(size--) {
8935                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8936                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8937                                         
8938                                         if(size)
8939                                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8940                                 }
8941                                 
8942                                 
8943                                 goto release;
8944                         } 
8945                         
8946                         if(aopIdx(AOP(result),0) != 4) {
8947                                 
8948                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8949                                 goto release;
8950                         }
8951                         
8952                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8953                         goto release;
8954                         
8955                 }
8956         }
8957         /* so dptr know contains the address */
8958         
8959         
8960         /* if bit then unpack */
8961         if (IS_BITVAR(retype)) 
8962                 genPackBits(retype,right,"dptr",GPOINTER);
8963         else {
8964                 size = AOP_SIZE(right);
8965                 offset = 0 ;
8966                 
8967                 DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8968                 
8969                 while (size--) {
8970                         
8971                         emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8972                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8973                         
8974                         if (AOP_TYPE(right) == AOP_LIT) 
8975                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8976                         else
8977                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8978                         
8979                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8980                         
8981                         offset++;
8982                 }
8983         }
8984         
8985 release:
8986         freeAsmop(right,NULL,ic,TRUE);
8987         freeAsmop(result,NULL,ic,TRUE);
8988 }
8989
8990 /*-----------------------------------------------------------------*/
8991 /* genPointerSet - stores the value into a pointer location        */
8992 /*-----------------------------------------------------------------*/
8993 static void genPointerSet (iCode *ic)
8994 {    
8995         operand *right, *result ;
8996         sym_link *type, *etype;
8997         int p_type;
8998         
8999         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9000         
9001         right = IC_RIGHT(ic);
9002         result = IC_RESULT(ic) ;
9003         
9004         /* depending on the type of pointer we need to
9005         move it to the correct pointer register */
9006         type = operandType(result);
9007         etype = getSpec(type);
9008         /* if left is of type of pointer then it is simple */
9009         if (IS_PTR(type) && !IS_FUNC(type->next)) {
9010                 p_type = DCL_TYPE(type);
9011         }
9012         else {
9013                 /* we have to go by the storage class */
9014                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9015                 
9016                 /*      if (SPEC_OCLS(etype)->codesp ) { */
9017                 /*          p_type = CPOINTER ;  */
9018                 /*      } */
9019                 /*      else */
9020                 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9021                 /*              p_type = FPOINTER ; */
9022                 /*          else */
9023                 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9024                 /*                  p_type = PPOINTER ; */
9025                 /*              else */
9026                 /*                  if (SPEC_OCLS(etype) == idata ) */
9027                 /*                      p_type = IPOINTER ; */
9028                 /*                  else */
9029                 /*                      p_type = POINTER ; */
9030         }
9031         
9032         /* now that we have the pointer type we assign
9033         the pointer values */
9034         switch (p_type) {
9035                 
9036         case POINTER:
9037         case IPOINTER:
9038                 genNearPointerSet (right,result,ic);
9039                 break;
9040                 
9041         case PPOINTER:
9042                 genPagedPointerSet (right,result,ic);
9043                 break;
9044                 
9045         case FPOINTER:
9046                 genFarPointerSet (right,result,ic);
9047                 break;
9048                 
9049         case GPOINTER:
9050                 genGenPointerSet (right,result,ic);
9051                 break;
9052                 
9053         default:
9054                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9055                         "genPointerSet: illegal pointer type");
9056         }
9057 }
9058
9059 /*-----------------------------------------------------------------*/
9060 /* genIfx - generate code for Ifx statement                        */
9061 /*-----------------------------------------------------------------*/
9062 static void genIfx (iCode *ic, iCode *popIc)
9063 {
9064         operand *cond = IC_COND(ic);
9065         int isbit =0;
9066         
9067         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9068         
9069         aopOp(cond,ic,FALSE);
9070         
9071         /* get the value into acc */
9072         if (AOP_TYPE(cond) != AOP_CRY)
9073                 pic14_toBoolean(cond);
9074         else
9075                 isbit = 1;
9076         /* the result is now in the accumulator */
9077         freeAsmop(cond,NULL,ic,TRUE);
9078         
9079         /* if there was something to be popped then do it */
9080         if (popIc)
9081                 genIpop(popIc);
9082         
9083         /* if the condition is  a bit variable */
9084         if (isbit && IS_ITEMP(cond) && 
9085                 SPIL_LOC(cond)) {
9086                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9087                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9088         }
9089         else {
9090                 if (isbit && !IS_ITEMP(cond))
9091                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9092                 else
9093                         genIfxJump(ic,"a");
9094         }
9095         ic->generated = 1;
9096         
9097 }
9098
9099 /*-----------------------------------------------------------------*/
9100 /* genAddrOf - generates code for address of                       */
9101 /*-----------------------------------------------------------------*/
9102 static void genAddrOf (iCode *ic)
9103 {
9104         operand *right, *result, *left;
9105         int size, offset ;
9106         
9107         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9108         
9109         
9110         //aopOp(IC_RESULT(ic),ic,FALSE);
9111         
9112         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9113         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9114         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9115         
9116         DEBUGpic14_AopType(__LINE__,left,right,result);
9117         
9118         size = AOP_SIZE(IC_RESULT(ic));
9119         offset = 0;
9120         
9121         while (size--) {
9122                 /* fixing bug #863624, reported from (errolv) */
9123                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9124                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9125                 
9126 #if 0
9127                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9128                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9129 #endif
9130                 offset++;
9131         }
9132         
9133         freeAsmop(left,NULL,ic,FALSE);
9134         freeAsmop(result,NULL,ic,TRUE);
9135         
9136 }
9137
9138 #if 0
9139 /*-----------------------------------------------------------------*/
9140 /* genFarFarAssign - assignment when both are in far space         */
9141 /*-----------------------------------------------------------------*/
9142 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9143 {
9144         int size = AOP_SIZE(right);
9145         int offset = 0;
9146         char *l ;
9147         /* first push the right side on to the stack */
9148         while (size--) {
9149                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9150                 MOVA(l);
9151                 pic14_emitcode ("push","acc");
9152         }
9153         
9154         freeAsmop(right,NULL,ic,FALSE);
9155         /* now assign DPTR to result */
9156         aopOp(result,ic,FALSE);
9157         size = AOP_SIZE(result);
9158         while (size--) {
9159                 pic14_emitcode ("pop","acc");
9160                 aopPut(AOP(result),"a",--offset);
9161         }
9162         freeAsmop(result,NULL,ic,FALSE);
9163         
9164 }
9165 #endif
9166
9167 /*-----------------------------------------------------------------*/
9168 /* genAssign - generate code for assignment                        */
9169 /*-----------------------------------------------------------------*/
9170 static void genAssign (iCode *ic)
9171 {
9172         operand *result, *right;
9173         int size, offset,know_W;
9174         unsigned long lit = 0L;
9175         
9176         result = IC_RESULT(ic);
9177         right  = IC_RIGHT(ic) ;
9178         
9179         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9180         
9181         /* if they are the same */
9182         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9183                 return ;
9184         
9185         aopOp(right,ic,FALSE);
9186         aopOp(result,ic,TRUE);
9187         
9188         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9189         
9190         /* if they are the same registers */
9191         if (pic14_sameRegs(AOP(right),AOP(result)))
9192                 goto release;
9193         
9194         /* if the result is a bit */
9195         if (AOP_TYPE(result) == AOP_CRY) {
9196                 
9197         /* if the right size is a literal then
9198                 we know what the value is */
9199                 if (AOP_TYPE(right) == AOP_LIT) {
9200                         
9201                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9202                                 popGet(AOP(result),0));
9203                         
9204                         if (((int) operandLitValue(right))) 
9205                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9206                                 AOP(result)->aopu.aop_dir,
9207                                 AOP(result)->aopu.aop_dir);
9208                         else
9209                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9210                                 AOP(result)->aopu.aop_dir,
9211                                 AOP(result)->aopu.aop_dir);
9212                         goto release;
9213                 }
9214                 
9215                 /* the right is also a bit variable */
9216                 if (AOP_TYPE(right) == AOP_CRY) {
9217                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9218                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9219                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9220                         
9221                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9222                                 AOP(result)->aopu.aop_dir,
9223                                 AOP(result)->aopu.aop_dir);
9224                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9225                                 AOP(right)->aopu.aop_dir,
9226                                 AOP(right)->aopu.aop_dir);
9227                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9228                                 AOP(result)->aopu.aop_dir,
9229                                 AOP(result)->aopu.aop_dir);
9230                         goto release ;
9231                 }
9232                 
9233                 /* we need to or */
9234                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9235                 pic14_toBoolean(right);
9236                 emitSKPZ;
9237                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9238                 //aopPut(AOP(result),"a",0);
9239                 goto release ;
9240         }
9241         
9242         /* bit variables done */
9243         /* general case */
9244         size = AOP_SIZE(result);
9245         offset = 0 ;
9246         if(AOP_TYPE(right) == AOP_LIT)
9247                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9248         
9249         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9250                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9251                 if(aopIdx(AOP(result),0) == 4) {
9252                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9253                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9254                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9255                         goto release;
9256                 } else
9257                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9258         }
9259         
9260         know_W=-1;
9261         while (size--) {
9262                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9263                 if(AOP_TYPE(right) == AOP_LIT) {
9264                         if(lit&0xff) {
9265                                 if(know_W != (int)(lit&0xff))
9266                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9267                                 know_W = lit&0xff;
9268                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9269                         } else
9270                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9271                         
9272                         lit >>= 8;
9273                         
9274                 } else if (AOP_TYPE(right) == AOP_CRY) {
9275                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9276                         if(offset == 0) {
9277                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9278                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9279                         }
9280                 } else {
9281                         mov2w (AOP(right), offset);
9282                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9283                 }
9284                 
9285                 offset++;
9286         }
9287         
9288         
9289 release:
9290         freeAsmop (right,NULL,ic,FALSE);
9291         freeAsmop (result,NULL,ic,TRUE);
9292 }   
9293
9294 /*-----------------------------------------------------------------*/
9295 /* genJumpTab - genrates code for jump table                       */
9296 /*-----------------------------------------------------------------*/
9297 static void genJumpTab (iCode *ic)
9298 {
9299         symbol *jtab;
9300         char *l;
9301         
9302         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9303         
9304         aopOp(IC_JTCOND(ic),ic,FALSE);
9305         /* get the condition into accumulator */
9306         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9307         MOVA(l);
9308         /* multiply by three */
9309         pic14_emitcode("add","a,acc");
9310         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9311         
9312         jtab = newiTempLabel(NULL);
9313         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9314         pic14_emitcode("jmp","@a+dptr");
9315         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9316         
9317         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9318         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9319         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9320         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9321         emitSKPNC;
9322         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9323         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9324         emitpLabel(jtab->key);
9325         
9326         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9327         
9328         /* now generate the jump labels */
9329         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9330         jtab = setNextItem(IC_JTLABELS(ic))) {
9331                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9332                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9333                 
9334         }
9335         
9336 }
9337
9338 /*-----------------------------------------------------------------*/
9339 /* genMixedOperation - gen code for operators between mixed types  */
9340 /*-----------------------------------------------------------------*/
9341 /*
9342 TSD - Written for the PIC port - but this unfortunately is buggy.
9343 This routine is good in that it is able to efficiently promote 
9344 types to different (larger) sizes. Unfortunately, the temporary
9345 variables that are optimized out by this routine are sometimes
9346 used in other places. So until I know how to really parse the 
9347 iCode tree, I'm going to not be using this routine :(.
9348 */
9349 static int genMixedOperation (iCode *ic)
9350 {
9351 #if 0
9352         operand *result = IC_RESULT(ic);
9353         sym_link *ctype = operandType(IC_LEFT(ic));
9354         operand *right = IC_RIGHT(ic);
9355         int ret = 0;
9356         int big,small;
9357         int offset;
9358         
9359         iCode *nextic;
9360         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9361         
9362         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9363         
9364         nextic = ic->next;
9365         if(!nextic)
9366                 return 0;
9367         
9368         nextright = IC_RIGHT(nextic);
9369         nextleft  = IC_LEFT(nextic);
9370         nextresult = IC_RESULT(nextic);
9371         
9372         aopOp(right,ic,FALSE);
9373         aopOp(result,ic,FALSE);
9374         aopOp(nextright,  nextic, FALSE);
9375         aopOp(nextleft,   nextic, FALSE);
9376         aopOp(nextresult, nextic, FALSE);
9377         
9378         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9379                 
9380                 operand *t = right;
9381                 right = nextright;
9382                 nextright = t; 
9383                 
9384                 pic14_emitcode(";remove right +","");
9385                 
9386         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9387         /*
9388         operand *t = right;
9389         right = nextleft;
9390         nextleft = t; 
9391                 */
9392                 pic14_emitcode(";remove left +","");
9393         } else
9394                 return 0;
9395         
9396         big = AOP_SIZE(nextleft);
9397         small = AOP_SIZE(nextright);
9398         
9399         switch(nextic->op) {
9400                 
9401         case '+':
9402                 pic14_emitcode(";optimize a +","");
9403                 /* if unsigned or not an integral type */
9404                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9405                         pic14_emitcode(";add a bit to something","");
9406                 } else {
9407                         
9408                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9409                         
9410                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9411                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9412                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9413                         } else
9414                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9415                         
9416                         offset = 0;
9417                         while(--big) {
9418                                 
9419                                 offset++;
9420                                 
9421                                 if(--small) {
9422                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9423                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9424                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9425                                         }
9426                                         
9427                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428                                         emitSKPNC;
9429                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9430                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9431                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9432                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9433                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9434                                         
9435                                 } else {
9436                                         pic14_emitcode("rlf","known_zero,w");
9437                                         
9438                                         /*
9439                                         if right is signed
9440                                         btfsc  right,7
9441                                         addlw ff
9442                                         */
9443                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9444                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9445                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9446                                         } else {
9447                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9448                                         }
9449                                 }
9450                         }
9451                         ret = 1;
9452                 }
9453         }
9454         ret = 1;
9455         
9456 release:
9457         freeAsmop(right,NULL,ic,TRUE);
9458         freeAsmop(result,NULL,ic,TRUE);
9459         freeAsmop(nextright,NULL,ic,TRUE);
9460         freeAsmop(nextleft,NULL,ic,TRUE);
9461         if(ret)
9462                 nextic->generated = 1;
9463         
9464         return ret;
9465 #else
9466         return 0;
9467 #endif
9468 }
9469 /*-----------------------------------------------------------------*/
9470 /* genCast - gen code for casting                                  */
9471 /*-----------------------------------------------------------------*/
9472 static void genCast (iCode *ic)
9473 {
9474         operand *result = IC_RESULT(ic);
9475         sym_link *ctype = operandType(IC_LEFT(ic));
9476         sym_link *rtype = operandType(IC_RIGHT(ic));
9477         operand *right = IC_RIGHT(ic);
9478         int size, offset ;
9479         
9480         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9481         /* if they are equivalent then do nothing */
9482         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9483                 return ;
9484         
9485         aopOp(right,ic,FALSE) ;
9486         aopOp(result,ic,FALSE);
9487         
9488         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9489         
9490         /* if the result is a bit */
9491         if (AOP_TYPE(result) == AOP_CRY) {
9492         /* if the right size is a literal then
9493                 we know what the value is */
9494                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9495                 if (AOP_TYPE(right) == AOP_LIT) {
9496                         
9497                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9498                                 popGet(AOP(result),0));
9499                         
9500                         if (((int) operandLitValue(right))) 
9501                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9502                                 AOP(result)->aopu.aop_dir,
9503                                 AOP(result)->aopu.aop_dir);
9504                         else
9505                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9506                                 AOP(result)->aopu.aop_dir,
9507                                 AOP(result)->aopu.aop_dir);
9508                         
9509                         goto release;
9510                 }
9511                 
9512                 /* the right is also a bit variable */
9513                 if (AOP_TYPE(right) == AOP_CRY) {
9514                         
9515                         emitCLRC;
9516                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9517                         
9518                         pic14_emitcode("clrc","");
9519                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9520                                 AOP(right)->aopu.aop_dir,
9521                                 AOP(right)->aopu.aop_dir);
9522                         aopPut(AOP(result),"c",0);
9523                         goto release ;
9524                 }
9525                 
9526                 /* we need to or */
9527                 if (AOP_TYPE(right) == AOP_REG) {
9528                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9529                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9530                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9531                 }
9532                 pic14_toBoolean(right);
9533                 aopPut(AOP(result),"a",0);
9534                 goto release ;
9535         }
9536         
9537         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9538                 int offset = 1;
9539                 size = AOP_SIZE(result);
9540                 
9541                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9542                 
9543                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9544                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9545                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9546                 
9547                 while (size--)
9548                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9549                 
9550                 goto release;
9551         }
9552         
9553         /* if they are the same size : or less */
9554         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9555                 
9556                 /* if they are in the same place */
9557                 if (pic14_sameRegs(AOP(right),AOP(result)))
9558                         goto release;
9559                 
9560                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9561                 if (IS_PTR_CONST(rtype))
9562                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9563                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9564                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9565                 
9566                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9567                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9568                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9569                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9570                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9571                         if(AOP_SIZE(result) <2)
9572                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9573                         
9574                 } else {
9575                         
9576                         /* if they in different places then copy */
9577                         size = AOP_SIZE(result);
9578                         offset = 0 ;
9579                         while (size--) {
9580                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9581                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9582                                 
9583                                 //aopPut(AOP(result),
9584                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9585                                 // offset);
9586                                 
9587                                 offset++;
9588                         }
9589                 }
9590                 goto release;
9591         }
9592         
9593         
9594         /* if the result is of type pointer */
9595         if (IS_PTR(ctype)) {
9596                 
9597                 int p_type;
9598                 sym_link *type = operandType(right);
9599                 sym_link *etype = getSpec(type);
9600                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9601                 
9602                 /* pointer to generic pointer */
9603                 if (IS_GENPTR(ctype)) {
9604                         char *l = zero;
9605                         
9606                         if (IS_PTR(type)) 
9607                                 p_type = DCL_TYPE(type);
9608                         else {
9609                                 /* we have to go by the storage class */
9610                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9611                                 
9612                                 /*              if (SPEC_OCLS(etype)->codesp )  */
9613                                 /*                  p_type = CPOINTER ;  */
9614                                 /*              else */
9615                                 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9616                                 /*                      p_type = FPOINTER ; */
9617                                 /*                  else */
9618                                 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9619                                 /*                          p_type = PPOINTER; */
9620                                 /*                      else */
9621                                 /*                          if (SPEC_OCLS(etype) == idata ) */
9622                                 /*                              p_type = IPOINTER ; */
9623                                 /*                          else */
9624                                 /*                              p_type = POINTER ; */
9625                         }
9626                         
9627                         /* the first two bytes are known */
9628                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9629                         size = GPTRSIZE - 1; 
9630                         offset = 0 ;
9631                         while (size--) {
9632                                 if(offset < AOP_SIZE(right)) {
9633                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9634                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9635                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9636                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9637                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9638                                         } else { 
9639                                                 aopPut(AOP(result),
9640                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9641                                                         offset);
9642                                         }
9643                                 } else 
9644                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9645                                 offset++;
9646                         }
9647                         /* the last byte depending on type */
9648                         switch (p_type) {
9649                         case IPOINTER:
9650                         case POINTER:
9651                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9652                                 break;
9653                         case FPOINTER:
9654                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9655                                 l = one;
9656                                 break;
9657                         case CPOINTER:
9658                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9659                                 l = "#0x02";
9660                                 break;                          
9661                         case PPOINTER:
9662                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9663                                 l = "#0x03";
9664                                 break;
9665                                 
9666                         default:
9667                                 /* this should never happen */
9668                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9669                                         "got unknown pointer type");
9670                                 exit(1);
9671                         }
9672                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9673                         goto release ;
9674                 }
9675                 
9676                 /* just copy the pointers */
9677                 size = AOP_SIZE(result);
9678                 offset = 0 ;
9679                 while (size--) {
9680                         aopPut(AOP(result),
9681                                 aopGet(AOP(right),offset,FALSE,FALSE),
9682                                 offset);
9683                         offset++;
9684                 }
9685                 goto release ;
9686         }
9687         
9688         
9689         
9690         /* so we now know that the size of destination is greater
9691         than the size of the source.
9692         Now, if the next iCode is an operator then we might be
9693         able to optimize the operation without performing a cast.
9694         */
9695         if(genMixedOperation(ic))
9696                 goto release;
9697         
9698         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9699         
9700         /* we move to result for the size of source */
9701         size = AOP_SIZE(right);
9702         offset = 0 ;
9703         while (size--) {
9704                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9705                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9706                 offset++;
9707         }
9708         
9709         /* now depending on the sign of the destination */
9710         size = AOP_SIZE(result) - AOP_SIZE(right);
9711         /* if unsigned or not an integral type */
9712         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9713                 while (size--)
9714                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9715         } else {
9716                 /* we need to extend the sign :{ */
9717                 
9718                 if(size == 1) {
9719                         /* Save one instruction of casting char to int */
9720                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9721                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9722                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9723                 } else {
9724                         emitpcodeNULLop(POC_CLRW);
9725                         
9726                         if(offset)
9727                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9728                         else
9729                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9730                         
9731                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9732                         
9733                         while (size--)
9734                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9735                 }
9736         }
9737         
9738 release:
9739         freeAsmop(right,NULL,ic,TRUE);
9740         freeAsmop(result,NULL,ic,TRUE);
9741         
9742 }
9743
9744 /*-----------------------------------------------------------------*/
9745 /* genDjnz - generate decrement & jump if not zero instrucion      */
9746 /*-----------------------------------------------------------------*/
9747 static int genDjnz (iCode *ic, iCode *ifx)
9748 {
9749         symbol *lbl, *lbl1;
9750         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9751         
9752         if (!ifx)
9753                 return 0;
9754         
9755                 /* if the if condition has a false label
9756         then we cannot save */
9757         if (IC_FALSE(ifx))
9758                 return 0;
9759         
9760                 /* if the minus is not of the form 
9761         a = a - 1 */
9762         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9763                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9764                 return 0;
9765         
9766         if (operandLitValue(IC_RIGHT(ic)) != 1)
9767                 return 0;
9768         
9769                 /* if the size of this greater than one then no
9770         saving */
9771         if (getSize(operandType(IC_RESULT(ic))) > 1)
9772                 return 0;
9773         
9774         /* otherwise we can save BIG */
9775         lbl = newiTempLabel(NULL);
9776         lbl1= newiTempLabel(NULL);
9777         
9778         aopOp(IC_RESULT(ic),ic,FALSE);
9779         
9780         if (IS_AOP_PREG(IC_RESULT(ic))) {
9781                 pic14_emitcode("dec","%s",
9782                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9783                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9784                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9785         } else {        
9786                 
9787                 
9788                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9789                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9790                 
9791                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9792                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9793                 
9794         }
9795         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9796         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9797         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9798         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9799         
9800         
9801         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9802         ifx->generated = 1;
9803         return 1;
9804 }
9805
9806 /*-----------------------------------------------------------------*/
9807 /* genReceive - generate code for a receive iCode                  */
9808 /*-----------------------------------------------------------------*/
9809 static void genReceive (iCode *ic)
9810 {
9811         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9812         
9813         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9814                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9815                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9816                 
9817                 int size = getSize(operandType(IC_RESULT(ic)));
9818                 int offset =  fReturnSizePic - size;
9819                 while (size--) {
9820                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9821                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9822                         offset++;
9823                 }
9824                 aopOp(IC_RESULT(ic),ic,FALSE);
9825                 size = AOP_SIZE(IC_RESULT(ic));
9826                 offset = 0;
9827                 while (size--) {
9828                         pic14_emitcode ("pop","acc");
9829                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9830                 }
9831                 
9832         } else {
9833                 _G.accInUse++;
9834                 aopOp(IC_RESULT(ic),ic,FALSE);
9835                 _G.accInUse--;
9836                 assignResultValue(IC_RESULT(ic));
9837         }
9838         
9839         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9840 }
9841
9842 /*-----------------------------------------------------------------*/
9843 /* genDummyRead - generate code for dummy read of volatiles        */
9844 /*-----------------------------------------------------------------*/
9845 static void
9846 genDummyRead (iCode * ic)
9847 {
9848         pic14_emitcode ("; genDummyRead","");
9849         pic14_emitcode ("; not implemented","");
9850         
9851         ic = ic;
9852 }
9853
9854 /*-----------------------------------------------------------------*/
9855 /* genpic14Code - generate code for pic14 based controllers        */
9856 /*-----------------------------------------------------------------*/
9857 /*
9858 * At this point, ralloc.c has gone through the iCode and attempted
9859 * to optimize in a way suitable for a PIC. Now we've got to generate
9860 * PIC instructions that correspond to the iCode.
9861 *
9862 * Once the instructions are generated, we'll pass through both the
9863 * peep hole optimizer and the pCode optimizer.
9864 *-----------------------------------------------------------------*/
9865
9866 void genpic14Code (iCode *lic)
9867 {
9868         iCode *ic;
9869         int cln = 0;
9870         
9871         lineHead = lineCurr = NULL;
9872         
9873         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9874         addpBlock(pb);
9875         
9876         /* if debug information required */
9877         if (options.debug && currFunc) { 
9878                 if (currFunc) {
9879                         debugFile->writeFunction(currFunc);
9880                         _G.debugLine = 1;
9881                         if (IS_STATIC(currFunc->etype)) {
9882                                 pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9883                                 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9884                         } else {
9885                                 pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9886                                 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9887                         }
9888                         _G.debugLine = 0;
9889                 }
9890         }
9891         
9892         
9893         for (ic = lic ; ic ; ic = ic->next ) {
9894                 
9895                 DEBUGpic14_emitcode(";ic","");
9896                 if ( cln != ic->lineno ) {
9897                         if ( options.debug ) {
9898                                 _G.debugLine = 1;
9899                                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9900                                         FileBaseName(ic->filename),ic->lineno,
9901                                         ic->level,ic->block);
9902                                 _G.debugLine = 0;
9903                         }
9904                         /*
9905                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9906                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9907                         printCLine(ic->filename, ic->lineno));
9908                         */
9909                         if (!options.noCcodeInAsm) {
9910                                 addpCode2pBlock(pb,
9911                                         newpCodeCSource(ic->lineno, 
9912                                         ic->filename, 
9913                                         printCLine(ic->filename, ic->lineno)));
9914                         }
9915                         
9916                         cln = ic->lineno ;
9917                 }
9918                 
9919                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9920                 
9921                 /* if the result is marked as
9922                 spilt and rematerializable or code for
9923                 this has already been generated then
9924                 do nothing */
9925                 if (resultRemat(ic) || ic->generated ) 
9926                         continue ;
9927                 
9928                 /* depending on the operation */
9929                 switch (ic->op) {
9930                 case '!' :
9931                         genNot(ic);
9932                         break;
9933                         
9934                 case '~' :
9935                         genCpl(ic);
9936                         break;
9937                         
9938                 case UNARYMINUS:
9939                         genUminus (ic);
9940                         break;
9941                         
9942                 case IPUSH:
9943                         genIpush (ic);
9944                         break;
9945                         
9946                 case IPOP:
9947                 /* IPOP happens only when trying to restore a 
9948                 spilt live range, if there is an ifx statement
9949                 following this pop then the if statement might
9950                 be using some of the registers being popped which
9951                 would destory the contents of the register so
9952                         we need to check for this condition and handle it */
9953                         if (ic->next            && 
9954                                 ic->next->op == IFX &&
9955                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9956                                 genIfx (ic->next,ic);
9957                         else
9958                                 genIpop (ic);
9959                         break; 
9960                         
9961                 case CALL:
9962                         genCall (ic);
9963                         break;
9964                         
9965                 case PCALL:
9966                         genPcall (ic);
9967                         break;
9968                         
9969                 case FUNCTION:
9970                         genFunction (ic);
9971                         break;
9972                         
9973                 case ENDFUNCTION:
9974                         genEndFunction (ic);
9975                         break;
9976                         
9977                 case RETURN:
9978                         genRet (ic);
9979                         break;
9980                         
9981                 case LABEL:
9982                         genLabel (ic);
9983                         break;
9984                         
9985                 case GOTO:
9986                         genGoto (ic);
9987                         break;
9988                         
9989                 case '+' :
9990                         genPlus (ic) ;
9991                         break;
9992                         
9993                 case '-' :
9994                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9995                                 genMinus (ic);
9996                         break;
9997                         
9998                 case '*' :
9999                         genMult (ic);
10000                         break;
10001                         
10002                 case '/' :
10003                         genDiv (ic) ;
10004                         break;
10005                         
10006                 case '%' :
10007                         genMod (ic);
10008                         break;
10009                         
10010                 case '>' :
10011                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                     
10012                         break;
10013                         
10014                 case '<' :
10015                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10016                         break;
10017                         
10018                 case LE_OP:
10019                 case GE_OP:
10020                 case NE_OP:
10021                         
10022                 /* note these two are xlated by algebraic equivalence
10023                         during parsing SDCC.y */
10024                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10025                                 "got '>=' or '<=' shouldn't have come here");
10026                         break;  
10027                         
10028                 case EQ_OP:
10029                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10030                         break;      
10031                         
10032                 case AND_OP:
10033                         genAndOp (ic);
10034                         break;
10035                         
10036                 case OR_OP:
10037                         genOrOp (ic);
10038                         break;
10039                         
10040                 case '^' :
10041                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10042                         break;
10043                         
10044                 case '|' :
10045                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10046                         break;
10047                         
10048                 case BITWISEAND:
10049                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10050                         break;
10051                         
10052                 case INLINEASM:
10053                         genInline (ic);
10054                         break;
10055                         
10056                 case RRC:
10057                         genRRC (ic);
10058                         break;
10059                         
10060                 case RLC:
10061                         genRLC (ic);
10062                         break;
10063                         
10064                 case GETHBIT:
10065                         genGetHbit (ic);
10066                         break;
10067                         
10068                 case LEFT_OP:
10069                         genLeftShift (ic);
10070                         break;
10071                         
10072                 case RIGHT_OP:
10073                         genRightShift (ic);
10074                         break;
10075                         
10076                 case GET_VALUE_AT_ADDRESS:
10077                         genPointerGet(ic);
10078                         break;
10079                         
10080                 case '=' :
10081                         if (POINTER_SET(ic))
10082                                 genPointerSet(ic);
10083                         else
10084                                 genAssign(ic);
10085                         break;
10086                         
10087                 case IFX:
10088                         genIfx (ic,NULL);
10089                         break;
10090                         
10091                 case ADDRESS_OF:
10092                         genAddrOf (ic);
10093                         break;
10094                         
10095                 case JUMPTABLE:
10096                         genJumpTab (ic);
10097                         break;
10098                         
10099                 case CAST:
10100                         genCast (ic);
10101                         break;
10102                         
10103                 case RECEIVE:
10104                         genReceive(ic);
10105                         break;
10106                         
10107                 case SEND:
10108                         addSet(&_G.sendSet,ic);
10109                         break;
10110                         
10111                 case DUMMY_READ_VOLATILE:
10112                         genDummyRead (ic);
10113                         break;
10114                         
10115                 default :
10116                         ic = ic;
10117                 }
10118         }
10119         
10120         
10121         /* now we are ready to call the
10122         peep hole optimizer */
10123         if (!options.nopeep) {
10124                 peepHole (&lineHead);
10125         }
10126         /* now do the actual printing */
10127         printLine (lineHead,codeOutFile);
10128         
10129 #ifdef PCODE_DEBUG
10130         DFPRINTF((stderr,"printing pBlock\n\n"));
10131         printpBlock(stdout,pb);
10132 #endif
10133         
10134         return;
10135 }