Fix for bugs #1080519 & #1115662.
[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
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68
69 /* this is the down and dirty file with all kinds of 
70 kludgy & hacky stuff. This is what it is all about
71 CODE GENERATION for a specific MCU . some of the
72 routines may be reusable, will have to see */
73
74 static char *zero = "#0x00";
75 static char *one  = "#0x01";
76 static char *spname = "sp";
77
78 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
79 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
80 static char **fReturn = fReturnpic14;
81
82 static char *accUse[] = {"a","b"};
83
84 //static short rbank = -1;
85
86 static struct {
87         short r0Pushed;
88         short r1Pushed;
89         short accInUse;
90         short inLine;
91         short debugLine;
92         short nRegsSaved;
93         set *sendSet;
94 } _G;
95
96 /* Resolved ifx structure. This structure stores information
97 about an iCode ifx that makes it easier to generate code.
98 */
99 typedef struct resolvedIfx {
100         symbol *lbl;     /* pointer to a label */
101         int condition;   /* true or false ifx */
102         int generated;   /* set true when the code associated with the ifx
103                           * is generated */
104 } resolvedIfx;
105
106 extern int pic14_ptrRegReq ;
107 extern int pic14_nRegs;
108 extern FILE *codeOutFile;
109 static void saverbank (int, iCode *,bool);
110
111 static lineNode *lineHead = NULL;
112 static lineNode *lineCurr = NULL;
113
114 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
115 0xE0, 0xC0, 0x80, 0x00};
116 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
117 0x07, 0x03, 0x01, 0x00};
118
119 static  pBlock *pb;
120
121 /*-----------------------------------------------------------------*/
122 /*      my_powof2(n) - If `n' is an integaer power of 2, then the          */
123 /*                                 exponent of 2 is returned, otherwise -1 is      */
124 /*                                 returned.                                                                       */
125 /* note that this is similar to the function `powof2' in SDCCsymt  */
126 /* if(n == 2^y)                                                                                                    */
127 /*       return y;                                                                                                         */
128 /* return -1;                                                                                                      */
129 /*-----------------------------------------------------------------*/
130 static int my_powof2 (unsigned long num)
131 {
132         if(num) {
133                 if( (num & (num-1)) == 0) {
134                         int nshifts = -1;
135                         while(num) {
136                                 num>>=1;
137                                 nshifts++;
138                         }
139                         return nshifts;
140                 }
141         }
142         
143         return -1;
144 }
145
146 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
147 {
148         
149         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
150                 line_no,
151                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
152                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
153                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
154                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
155                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
156                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
157                 ((result) ? AOP_SIZE(result) : 0));
158         
159 }
160
161 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
162 {
163         
164         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
165                 line_no,
166                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
167                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
168                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
169                 ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
170                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
171                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
172         
173 }
174
175 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 {
177         va_list ap;
178         char lb[INITIAL_INLINEASM];  
179         char *lbp = lb;
180         
181         if(!debug_verbose)
182                 return;
183         
184         va_start(ap,fmt);   
185         
186         if (inst && *inst) {
187                 if (fmt && *fmt)
188                         sprintf(lb,"%s\t",inst);
189                 else
190                         sprintf(lb,"%s",inst);
191                 vsprintf(lb+(strlen(lb)),fmt,ap);
192         }  else
193                 vsprintf(lb,fmt,ap);
194         
195         while (isspace(*lbp)) lbp++;
196         
197         if (lbp && *lbp) 
198                 lineCurr = (lineCurr ?
199                 connectLine(lineCurr,newLineNode(lb)) :
200         (lineHead = newLineNode(lb)));
201         lineCurr->isInline = _G.inLine;
202         lineCurr->isDebug  = _G.debugLine;
203         
204         addpCode2pBlock(pb,newpCodeCharP(lb));
205         
206         va_end(ap);
207 }
208
209
210 void emitpLabel(int key)
211 {
212         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
213 }
214
215 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
216 {
217         if(pcop)
218                 addpCode2pBlock(pb,newpCode(poc,pcop));
219         else
220                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
221 }
222
223 void emitpcodeNULLop(PIC_OPCODE poc)
224 {
225         
226         addpCode2pBlock(pb,newpCode(poc,NULL));
227         
228 }
229
230
231 /*-----------------------------------------------------------------*/
232 /* pic14_emitcode - writes the code into a file : for now it is simple    */
233 /*-----------------------------------------------------------------*/
234 void pic14_emitcode (char *inst,char *fmt, ...)
235 {
236         va_list ap;
237         char lb[INITIAL_INLINEASM];  
238         char *lbp = lb;
239         
240         va_start(ap,fmt);   
241         
242         if (inst && *inst) {
243                 if (fmt && *fmt)
244                         sprintf(lb,"%s\t",inst);
245                 else
246                         sprintf(lb,"%s",inst);
247                 vsprintf(lb+(strlen(lb)),fmt,ap);
248         }  else
249                 vsprintf(lb,fmt,ap);
250         
251         while (isspace(*lbp)) lbp++;
252         
253         if (lbp && *lbp) 
254                 lineCurr = (lineCurr ?
255                 connectLine(lineCurr,newLineNode(lb)) :
256         (lineHead = newLineNode(lb)));
257         lineCurr->isInline = _G.inLine;
258         lineCurr->isDebug  = _G.debugLine;
259         
260         if(debug_verbose)
261                 addpCode2pBlock(pb,newpCodeCharP(lb));
262         
263         va_end(ap);
264 }
265
266 /*-----------------------------------------------------------------*/
267 /* pic14_emitDebuggerSymbol - associate the current code location  */
268 /*       with a debugger symbol                                                                            */
269 /*-----------------------------------------------------------------*/
270 void
271 pic14_emitDebuggerSymbol (char * debugSym)
272 {
273         _G.debugLine = 1;
274         pic14_emitcode ("", ";%s ==.", debugSym);
275         _G.debugLine = 0;
276 }
277
278
279 /*-----------------------------------------------------------------*/
280 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
281 /*-----------------------------------------------------------------*/
282 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
283 {
284         bool r0iu = FALSE , r1iu = FALSE;
285         bool r0ou = FALSE , r1ou = FALSE;
286         
287         /* the logic: if r0 & r1 used in the instruction
288         then we are in trouble otherwise */
289         
290         /* first check if r0 & r1 are used by this
291         instruction, in which case we are in trouble */
292         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
293                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
294         {
295                 goto endOfWorld;          
296         }
297         
298         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
299         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
300         
301         /* if no usage of r0 then return it */
302         if (!r0iu && !r0ou) {
303                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
304                 (*aopp)->type = AOP_R0;
305                 
306                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
307         }
308         
309         /* if no usage of r1 then return it */
310         if (!r1iu && !r1ou) {
311                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
312                 (*aopp)->type = AOP_R1;
313                 
314                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
315         }    
316         
317         /* now we know they both have usage */
318         /* if r0 not used in this instruction */
319         if (!r0iu) {
320                 /* push it if not already pushed */
321                 if (!_G.r0Pushed) {
322                         //pic14_emitcode ("push","%s",
323                         //                pic14_regWithIdx(R0_IDX)->dname);
324                         _G.r0Pushed++ ;
325                 }
326                 
327                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
328                 (*aopp)->type = AOP_R0;
329                 
330                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
331         }
332         
333         /* if r1 not used then */
334         
335         if (!r1iu) {
336                 /* push it if not already pushed */
337                 if (!_G.r1Pushed) {
338                         //pic14_emitcode ("push","%s",
339                         //                pic14_regWithIdx(R1_IDX)->dname);
340                         _G.r1Pushed++ ;
341                 }
342                 
343                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
344                 (*aopp)->type = AOP_R1;
345                 return pic14_regWithIdx(R1_IDX);
346         }
347         
348 endOfWorld :
349         /* I said end of world but not quite end of world yet */
350         /* if this is a result then we can push it on the stack*/
351         if (result) {
352                 (*aopp)->type = AOP_STK;        
353                 return NULL;
354         }
355         
356         /* other wise this is true end of the world */
357         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
358                 "getFreePtr should never reach here");
359         exit(0);
360 }
361
362 /*-----------------------------------------------------------------*/
363 /* newAsmop - creates a new asmOp                                                                  */
364 /*-----------------------------------------------------------------*/
365 asmop *newAsmop (short type)
366 {
367         asmop *aop;
368         
369         aop = Safe_calloc(1,sizeof(asmop));
370         aop->type = type;
371         return aop;
372 }
373
374 static void genSetDPTR(int n)
375 {
376         if (!n)
377         {
378                 pic14_emitcode(";", "Select standard DPTR");
379                 pic14_emitcode("mov", "dps, #0x00");
380         }
381         else
382         {
383                 pic14_emitcode(";", "Select alternate DPTR");
384                 pic14_emitcode("mov", "dps, #0x01");
385         }
386 }
387
388 /*-----------------------------------------------------------------*/
389 /* resolveIfx - converts an iCode ifx into a form more useful for  */
390 /*                              generating code                                                                    */
391 /*-----------------------------------------------------------------*/
392 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
393 {
394         if(!resIfx) 
395                 return;
396         
397         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
398         
399         resIfx->condition = 1;  /* assume that the ifx is true */
400         resIfx->generated = 0;  /* indicate that the ifx has not been used */
401         
402         if(!ifx) {
403                 resIfx->lbl = newiTempLabel(NULL);      /* oops, there is no ifx. so create a label */
404                                                                                         /*
405                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
406                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
407                 */
408         } else {
409                 if(IC_TRUE(ifx)) {
410                         resIfx->lbl = IC_TRUE(ifx);
411                 } else {
412                         resIfx->lbl = IC_FALSE(ifx);
413                         resIfx->condition = 0;
414                 }
415                 /*
416                 if(IC_TRUE(ifx)) 
417                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
418                 if(IC_FALSE(ifx)) 
419                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
420                 */
421         }
422         
423         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
424         
425 }
426 /*-----------------------------------------------------------------*/
427 /* pointerCode - returns the code for a pointer type                       */
428 /*-----------------------------------------------------------------*/
429 static int pointerCode (sym_link *etype)
430 {
431         
432         return PTR_TYPE(SPEC_OCLS(etype));
433         
434 }
435
436 /*-----------------------------------------------------------------*/
437 /* aopForSym - for a true symbol                                                                   */
438 /*-----------------------------------------------------------------*/
439 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
440 {
441         asmop *aop;
442         memmap *space= SPEC_OCLS(sym->etype);
443         
444         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
445         /* if already has one */
446         if (sym->aop)
447                 return sym->aop;
448         
449         /* assign depending on the storage class */
450         /* if it is on the stack or indirectly addressable */
451         /* space we need to assign either r0 or r1 to it         */    
452         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
453                 sym->aop = aop = newAsmop(0);
454                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
455                 aop->size = getSize(sym->type);
456                 
457                 /* now assign the address of the variable to 
458                 the pointer register */
459                 if (aop->type != AOP_STK) {
460                         
461                         if (sym->onStack) {
462                                 if ( _G.accInUse )
463                                         pic14_emitcode("push","acc");
464                                 
465                                 pic14_emitcode("mov","a,_bp");
466                                 pic14_emitcode("add","a,#0x%02x",
467                                         ((sym->stack < 0) ?
468                                         ((char)(sym->stack - _G.nRegsSaved )) :
469                                 ((char)sym->stack)) & 0xff);
470                                 pic14_emitcode("mov","%s,a",
471                                         aop->aopu.aop_ptr->name);
472                                 
473                                 if ( _G.accInUse )
474                                         pic14_emitcode("pop","acc");
475                         } else
476                                 pic14_emitcode("mov","%s,#%s",
477                                 aop->aopu.aop_ptr->name,
478                                 sym->rname);
479                         aop->paged = space->paged;
480                 } else
481                         aop->aopu.aop_stk = sym->stack;
482                 return aop;
483         }
484         
485         if (sym->onStack && options.stack10bit)
486         {
487                 /* It's on the 10 bit stack, which is located in
488                 * far data space.
489                 */
490                 
491                 //DEBUGpic14_emitcode(";","%d",__LINE__);
492                 
493                 if ( _G.accInUse )
494                         pic14_emitcode("push","acc");
495                 
496                 pic14_emitcode("mov","a,_bp");
497                 pic14_emitcode("add","a,#0x%02x",
498                         ((sym->stack < 0) ?
499                         ((char)(sym->stack - _G.nRegsSaved )) :
500                 ((char)sym->stack)) & 0xff);
501                 
502                 genSetDPTR(1);
503                 pic14_emitcode ("mov","dpx1,#0x40");
504                 pic14_emitcode ("mov","dph1,#0x00");
505                 pic14_emitcode ("mov","dpl1, a");
506                 genSetDPTR(0);
507                 
508                 if ( _G.accInUse )
509                         pic14_emitcode("pop","acc");
510                 
511                 sym->aop = aop = newAsmop(AOP_DPTR2);
512                 aop->size = getSize(sym->type); 
513                 return aop;
514         }
515         
516         //DEBUGpic14_emitcode(";","%d",__LINE__);
517         /* if in bit space */
518         if (IN_BITSPACE(space)) {
519                 sym->aop = aop = newAsmop (AOP_CRY);
520                 aop->aopu.aop_dir = sym->rname ;
521                 aop->size = getSize(sym->type);
522                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
523                 return aop;
524         }
525         /* if it is in direct space */
526         if (IN_DIRSPACE(space)) {
527                 sym->aop = aop = newAsmop (AOP_DIR);
528                 aop->aopu.aop_dir = sym->rname ;
529                 aop->size = getSize(sym->type);
530                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
531                 return aop;
532         }
533         
534         /* special case for a function */
535         if (IS_FUNC(sym->type)) {   
536                 
537                 sym->aop = aop = newAsmop(AOP_PCODE);
538                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
539                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
540                 PCOI(aop->aopu.pcop)->_function = 1;
541                 PCOI(aop->aopu.pcop)->index = 0;
542                 aop->size = FPTRSIZE; 
543                 /*
544                 sym->aop = aop = newAsmop(AOP_IMMD);    
545                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
546                 strcpy(aop->aopu.aop_immd,sym->rname);
547                 aop->size = FPTRSIZE; 
548                 */
549                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
550                 return aop;
551         }
552         
553         
554         /* only remaining is far space */
555         /* in which case DPTR gets the address */
556         sym->aop = aop = newAsmop(AOP_PCODE);
557         
558         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
559         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
560         PCOI(aop->aopu.pcop)->index = 0;
561         
562         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
563                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
564         
565         allocDirReg (IC_LEFT(ic));
566         
567         aop->size = FPTRSIZE; 
568         /*
569         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
570         sym->aop = aop = newAsmop(AOP_DPTR);
571         pic14_emitcode ("mov","dptr,#%s", sym->rname);
572         aop->size = getSize(sym->type);
573         
574           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
575         */
576         
577         /* if it is in code space */
578         if (IN_CODESPACE(space))
579                 aop->code = 1;
580         
581         return aop;       
582 }
583
584 /*-----------------------------------------------------------------*/
585 /* aopForRemat - rematerialzes an object                                                   */
586 /*-----------------------------------------------------------------*/
587 static asmop *aopForRemat (operand *op) // x symbol *sym)
588 {
589         symbol *sym = OP_SYMBOL(op);
590         iCode *ic = NULL;
591         asmop *aop = newAsmop(AOP_PCODE);
592         int val = 0;
593         int offset = 0;
594         
595         ic = sym->rematiCode;
596         
597         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
598         if(IS_OP_POINTER(op)) {
599                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
600         }
601         for (;;) {
602                 if (ic->op == '+') {
603                         val += (int) operandLitValue(IC_RIGHT(ic));
604                 } else if (ic->op == '-') {
605                         val -= (int) operandLitValue(IC_RIGHT(ic));
606                 } else
607                         break;
608                 
609                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
610         }
611         
612         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
613         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
614         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
615         PCOI(aop->aopu.pcop)->index = val;
616         
617         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
618                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
619                 val, IS_PTR_CONST(operandType(op)));
620         
621         //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
622         
623         allocDirReg (IC_LEFT(ic));
624         
625         return aop;              
626 }
627
628 int aopIdx (asmop *aop, int offset)
629 {
630         if(!aop)
631                 return -1;
632         
633         if(aop->type !=  AOP_REG)
634                 return -2;
635         
636         return aop->aopu.aop_reg[offset]->rIdx;
637         
638 }
639 /*-----------------------------------------------------------------*/
640 /* regsInCommon - two operands have some registers in common       */
641 /*-----------------------------------------------------------------*/
642 static bool regsInCommon (operand *op1, operand *op2)
643 {
644         symbol *sym1, *sym2;
645         int i;
646         
647         /* if they have registers in common */
648         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
649                 return FALSE ;
650         
651         sym1 = OP_SYMBOL(op1);
652         sym2 = OP_SYMBOL(op2);
653         
654         if (sym1->nRegs == 0 || sym2->nRegs == 0)
655                 return FALSE ;
656         
657         for (i = 0 ; i < sym1->nRegs ; i++) {
658                 int j;
659                 if (!sym1->regs[i])
660                         continue ;
661                 
662                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
663                         if (!sym2->regs[j])
664                                 continue ;
665                         
666                         if (sym2->regs[j] == sym1->regs[i])
667                                 return TRUE ;
668                 }
669         }
670         
671         return FALSE ;
672 }
673
674 /*-----------------------------------------------------------------*/
675 /* operandsEqu - equivalent                                                                        */
676 /*-----------------------------------------------------------------*/
677 static bool operandsEqu ( operand *op1, operand *op2)
678 {
679         symbol *sym1, *sym2;
680         
681         /* if they not symbols */
682         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
683                 return FALSE;
684         
685         sym1 = OP_SYMBOL(op1);
686         sym2 = OP_SYMBOL(op2);
687         
688         /* if both are itemps & one is spilt
689         and the other is not then false */
690         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
691                 sym1->isspilt != sym2->isspilt )
692                 return FALSE ;
693         
694         /* if they are the same */
695         if (sym1 == sym2)
696                 return TRUE ;
697         
698         if (sym1->rname[0] && sym2->rname[0]
699                 && strcmp (sym1->rname, sym2->rname) == 0)
700                 return TRUE;
701         
702         
703         /* if left is a tmp & right is not */
704         if (IS_ITEMP(op1)  && 
705                 !IS_ITEMP(op2) &&
706                 sym1->isspilt  &&
707                 (sym1->usl.spillLoc == sym2))
708                 return TRUE;
709         
710         if (IS_ITEMP(op2)  && 
711                 !IS_ITEMP(op1) &&
712                 sym2->isspilt  &&
713                 sym1->level > 0 &&
714                 (sym2->usl.spillLoc == sym1))
715                 return TRUE ;
716         
717         return FALSE ;
718 }
719
720 /*-----------------------------------------------------------------*/
721 /* pic14_sameRegs - two asmops have the same registers             */
722 /*-----------------------------------------------------------------*/
723 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
724 {
725         int i;
726         
727         if (aop1 == aop2)
728                 return TRUE ;
729         
730         if (aop1->type != AOP_REG ||
731                 aop2->type != AOP_REG )
732                 return FALSE ;
733         
734         if (aop1->size != aop2->size )
735                 return FALSE ;
736         
737         for (i = 0 ; i < aop1->size ; i++ )
738                 if (aop1->aopu.aop_reg[i] !=
739                         aop2->aopu.aop_reg[i] )
740                         return FALSE ;
741                 
742                 return TRUE ;
743 }
744
745 /*-----------------------------------------------------------------*/
746 /* aopOp - allocates an asmop for an operand  :                    */
747 /*-----------------------------------------------------------------*/
748 void aopOp (operand *op, iCode *ic, bool result)
749 {
750         asmop *aop;
751         symbol *sym;
752         int i;
753         
754         if (!op)
755                 return ;
756         
757         /* if this a literal */
758         if (IS_OP_LITERAL(op)) {
759                 op->aop = aop = newAsmop(AOP_LIT);
760                 aop->aopu.aop_lit = op->operand.valOperand;
761                 aop->size = getSize(operandType(op));
762                 return;
763         }
764         
765         {
766                 sym_link *type = operandType(op);
767                 if(IS_PTR_CONST(type))
768                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
769         }
770         
771         /* if already has a asmop then continue */
772         if (op->aop)
773                 return ;
774         
775         /* if the underlying symbol has a aop */
776         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
777                 DEBUGpic14_emitcode(";","%d",__LINE__);
778                 op->aop = OP_SYMBOL(op)->aop;
779                 return;
780         }
781         
782         /* if this is a true symbol */
783         if (IS_TRUE_SYMOP(op)) {          
784                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
785                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
786                 return ;
787         }
788         
789         /* this is a temporary : this has
790         only four choices :
791         a) register
792         b) spillocation
793         c) rematerialize 
794         d) conditional   
795         e) can be a return use only */
796         
797         sym = OP_SYMBOL(op);
798         
799         
800         /* if the type is a conditional */
801         if (sym->regType == REG_CND) {
802                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
803                 aop->size = 0;
804                 return;
805         }
806         
807         /* if it is spilt then two situations
808         a) is rematerialize 
809         b) has a spill location */
810         if (sym->isspilt || sym->nRegs == 0) {
811                 
812                 DEBUGpic14_emitcode(";","%d",__LINE__);
813                 /* rematerialize it NOW */
814                 if (sym->remat) {
815                         
816                         sym->aop = op->aop = aop = aopForRemat (op);
817                         aop->size = getSize(sym->type);
818                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
819                         return;
820                 }
821                 
822                 if (sym->accuse) {
823                         int i;
824                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825                         aop->size = getSize(sym->type);
826                         for ( i = 0 ; i < 2 ; i++ )
827                                 aop->aopu.aop_str[i] = accUse[i];
828                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
829                         return;  
830                 }
831                 
832                 if (sym->ruonly ) {
833                         if(sym->isptr) {        // && sym->uptr 
834                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
835                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
836                                 
837                                 //PCOI(aop->aopu.pcop)->_const = 0;
838                                 //PCOI(aop->aopu.pcop)->index = 0;
839                                 /*
840                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
841                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
842                                 */
843                                 //allocDirReg (IC_LEFT(ic));
844                                 
845                                 aop->size = getSize(sym->type);
846                                 DEBUGpic14_emitcode(";","%d",__LINE__);
847                                 return;
848                                 
849                         } else {
850                                 
851                                 unsigned i;
852                                 
853                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
854                                 aop->size = getSize(sym->type);
855                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
856                                         aop->aopu.aop_str[i] = fReturn[i];
857                                 
858                                 DEBUGpic14_emitcode(";","%d",__LINE__);
859                                 return;
860                         }
861                 }
862                 
863                 /* else spill location  */
864                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
865                         /* force a new aop if sizes differ */
866                         sym->usl.spillLoc->aop = NULL;
867                 }
868                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
869                         __FUNCTION__,__LINE__,
870                         sym->usl.spillLoc->rname,
871                         sym->rname, sym->usl.spillLoc->offset);
872                 
873                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
874                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
875                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
876                         getSize(sym->type), 
877                         sym->usl.spillLoc->offset);
878                 aop->size = getSize(sym->type);
879                 
880                 return;
881         }
882         
883         {
884                 sym_link *type = operandType(op);
885                 if(IS_PTR_CONST(type)) 
886                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
887         }
888         
889         /* must be in a register */
890         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
891         sym->aop = op->aop = aop = newAsmop(AOP_REG);
892         aop->size = sym->nRegs;
893         for ( i = 0 ; i < sym->nRegs ;i++)
894                 aop->aopu.aop_reg[i] = sym->regs[i];
895 }
896
897 /*-----------------------------------------------------------------*/
898 /* freeAsmop - free up the asmop given to an operand                       */
899 /*----------------------------------------------------------------*/
900 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
901 {       
902         asmop *aop ;
903         
904         if (!op)
905                 aop = aaop;
906         else 
907                 aop = op->aop;
908         
909         if (!aop)
910                 return ;
911         
912         if (aop->freed)
913                 goto dealloc; 
914         
915         aop->freed = 1;
916         
917         /* depending on the asmop type only three cases need work AOP_RO
918         , AOP_R1 && AOP_STK */
919 #if 0
920         switch (aop->type) {
921         case AOP_R0 :
922                 if (_G.r0Pushed ) {
923                         if (pop) {
924                                 pic14_emitcode ("pop","ar0");     
925                                 _G.r0Pushed--;
926                         }
927                 }
928                 bitVectUnSetBit(ic->rUsed,R0_IDX);
929                 break;
930                 
931         case AOP_R1 :
932                 if (_G.r1Pushed ) {
933                         if (pop) {
934                                 pic14_emitcode ("pop","ar1");
935                                 _G.r1Pushed--;
936                         }
937                 }
938                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
939                 break;
940                 
941         case AOP_STK :
942                 {
943                         int sz = aop->size;      
944                         int stk = aop->aopu.aop_stk + aop->size;
945                         bitVectUnSetBit(ic->rUsed,R0_IDX);
946                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
947                         
948                         getFreePtr(ic,&aop,FALSE);
949                         
950                         if (options.stack10bit)
951                         {
952                                 /* I'm not sure what to do here yet... */
953                                 /* #STUB */
954                                 fprintf(stderr, 
955                                         "*** Warning: probably generating bad code for "
956                                         "10 bit stack mode.\n");
957                         }
958                         
959                         if (stk) {
960                                 pic14_emitcode ("mov","a,_bp");
961                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
962                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
963                         } else {
964                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
965                         }
966                         
967                         while (sz--) {
968                                 pic14_emitcode("pop","acc");
969                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
970                                 if (!sz) break;
971                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
972                         }
973                         op->aop = aop;
974                         freeAsmop(op,NULL,ic,TRUE);
975                         if (_G.r0Pushed) {
976                                 pic14_emitcode("pop","ar0");
977                                 _G.r0Pushed--;
978                         }
979                         
980                         if (_G.r1Pushed) {
981                                 pic14_emitcode("pop","ar1");
982                                 _G.r1Pushed--;
983                         }         
984                 }
985         }
986 #endif
987         
988 dealloc:
989         /* all other cases just dealloc */
990         if (op ) {
991                 op->aop = NULL;
992                 if (IS_SYMOP(op)) {
993                         OP_SYMBOL(op)->aop = NULL;      
994                         /* if the symbol has a spill */
995                         if (SPIL_LOC(op))
996                                 SPIL_LOC(op)->aop = NULL;
997                 }
998         }
999 }
1000
1001 /*-----------------------------------------------------------------*/
1002 /* aopGet - for fetching value of the aop                                                  */
1003 /*-----------------------------------------------------------------*/
1004 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1005 {
1006         char *s = buffer ;
1007         char *rs;
1008         
1009         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1010         /* offset is greater than
1011         size then zero */
1012         if (offset > (aop->size - 1) &&
1013                 aop->type != AOP_LIT)
1014                 return zero;
1015         
1016         /* depending on type */
1017         switch (aop->type) {
1018                 
1019         case AOP_R0:
1020         case AOP_R1:
1021                 DEBUGpic14_emitcode(";","%d",__LINE__);
1022                 /* if we need to increment it */           
1023                 while (offset > aop->coff) {            
1024                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1025                         aop->coff++;
1026                 }
1027                 
1028                 while (offset < aop->coff) {
1029                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1030                         aop->coff--;
1031                 }
1032                 
1033                 aop->coff = offset ;
1034                 if (aop->paged) {
1035                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1036                         return (dname ? "acc" : "a");
1037                 }               
1038                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1039                 rs = Safe_calloc(1,strlen(s)+1);
1040                 strcpy(rs,s);   
1041                 return rs;
1042                 
1043         case AOP_DPTR:
1044         case AOP_DPTR2:
1045                 DEBUGpic14_emitcode(";","%d",__LINE__);
1046                 if (aop->type == AOP_DPTR2)
1047                 {
1048                         genSetDPTR(1);
1049                 }
1050                 
1051                 while (offset > aop->coff) {
1052                         pic14_emitcode ("inc","dptr");
1053                         aop->coff++;
1054                 }
1055                 
1056                 while (offset < aop->coff) {            
1057                         pic14_emitcode("lcall","__decdptr");
1058                         aop->coff--;
1059                 }
1060                 
1061                 aop->coff = offset;
1062                 if (aop->code) {
1063                         pic14_emitcode("clr","a");
1064                         pic14_emitcode("movc","a,@a+dptr");
1065                 }
1066                 else {
1067                         pic14_emitcode("movx","a,@dptr");
1068                 }
1069                 
1070                 if (aop->type == AOP_DPTR2)
1071                 {
1072                         genSetDPTR(0);
1073                 }
1074                 
1075                 return (dname ? "acc" : "a");
1076                 
1077                 
1078         case AOP_IMMD:
1079                 if (bit16) 
1080                         sprintf (s,"%s",aop->aopu.aop_immd);
1081                 else
1082                         if (offset) 
1083                                 sprintf(s,"(%s >> %d)",
1084                                 aop->aopu.aop_immd,
1085                                 offset*8);
1086                         else
1087                                 sprintf(s,"%s",
1088                                 aop->aopu.aop_immd);
1089                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1090                         rs = Safe_calloc(1,strlen(s)+1);
1091                         strcpy(rs,s);   
1092                         return rs;
1093                         
1094         case AOP_DIR:
1095                 if (offset) {
1096                         sprintf(s,"(%s + %d)",
1097                                 aop->aopu.aop_dir,
1098                                 offset);
1099                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1100                 } else
1101                         sprintf(s,"%s",aop->aopu.aop_dir);
1102                 rs = Safe_calloc(1,strlen(s)+1);
1103                 strcpy(rs,s);   
1104                 return rs;
1105                 
1106         case AOP_REG:
1107                 //if (dname) 
1108                 //        return aop->aopu.aop_reg[offset]->dname;
1109                 //else
1110                 return aop->aopu.aop_reg[offset]->name;
1111                 
1112         case AOP_CRY:
1113                 //pic14_emitcode(";","%d",__LINE__);
1114                 return aop->aopu.aop_dir;
1115                 
1116         case AOP_ACC:
1117                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1118                 return "AOP_accumulator_bug";
1119                 
1120         case AOP_LIT:
1121                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1122                 rs = Safe_calloc(1,strlen(s)+1);
1123                 strcpy(rs,s);   
1124                 return rs;
1125                 
1126         case AOP_STR:
1127                 aop->coff = offset ;
1128                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1129                         dname)
1130                         return "acc";
1131                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1132                 
1133                 return aop->aopu.aop_str[offset];
1134                 
1135         case AOP_PCODE:
1136                 {
1137                         pCodeOp *pcop = aop->aopu.pcop;
1138                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1139                         if(pcop->name) {
1140                                 if (offset) {
1141                                         DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1142                                         sprintf(s,"(%s+%d)", pcop->name,offset);
1143                                 } else {
1144                                         DEBUGpic14_emitcode(";","%s",pcop->name);
1145                                         sprintf(s,"%s", pcop->name);
1146                                 }
1147                         } else
1148                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1149                         
1150                 }
1151                 rs = Safe_calloc(1,strlen(s)+1);
1152                 strcpy(rs,s);   
1153                 return rs;
1154                 
1155   }
1156   
1157   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1158           "aopget got unsupported aop->type");
1159   exit(0);
1160 }
1161
1162
1163 /*-----------------------------------------------------------------*/
1164 /* popGetTempReg - create a new temporary pCodeOp                                  */
1165 /*-----------------------------------------------------------------*/
1166 pCodeOp *popGetTempReg(void)
1167 {
1168         
1169         pCodeOp *pcop;
1170         
1171         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1172         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1173                 PCOR(pcop)->r->wasUsed=1;
1174                 PCOR(pcop)->r->isFree=0;
1175         }
1176         
1177         return pcop;
1178 }
1179
1180 /*-----------------------------------------------------------------*/
1181 /* popReleaseTempReg - create a new temporary pCodeOp                              */
1182 /*-----------------------------------------------------------------*/
1183 void popReleaseTempReg(pCodeOp *pcop)
1184 {
1185         
1186         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1187                 PCOR(pcop)->r->isFree = 1;
1188         
1189 }
1190 /*-----------------------------------------------------------------*/
1191 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *popGetLabel(unsigned int key)
1194 {
1195         
1196         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1197         
1198         if(key>(unsigned int)max_key)
1199                 max_key = key;
1200         
1201         return newpCodeOpLabel(NULL,key+100+labelOffset);
1202 }
1203
1204 /*-------------------------------------------------------------------*/
1205 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1206 /*-------------------------------------------------------------------*/
1207 pCodeOp *popGetHighLabel(unsigned int key)
1208 {
1209         pCodeOp *pcop;
1210         pcop = popGetLabel(key);
1211         PCOLAB(pcop)->offset = 1;
1212         return pcop;
1213 }
1214
1215 /*-----------------------------------------------------------------*/
1216 /* popGetLit - asm operator to pcode operator conversion                           */
1217 /*-----------------------------------------------------------------*/
1218 pCodeOp *popGetLit(unsigned int lit)
1219 {
1220         
1221         return newpCodeOpLit(lit);
1222 }
1223
1224 /*-----------------------------------------------------------------*/
1225 /* popGetImmd - asm operator to pcode immediate conversion                 */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1228 {
1229         
1230         return newpCodeOpImmd(name, offset,index, 0, is_func);
1231 }
1232
1233
1234 /*-----------------------------------------------------------------*/
1235 /* popGetWithString - asm operator to pcode operator conversion                    */
1236 /*-----------------------------------------------------------------*/
1237 pCodeOp *popGetWithString(char *str, int isExtern)
1238 {
1239         pCodeOp *pcop;
1240         
1241         
1242         if(!str) {
1243                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1244                 exit (1);
1245         }
1246         
1247         pcop = newpCodeOp(str,PO_STR);
1248         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1249         
1250         return pcop;
1251 }
1252
1253 /*-----------------------------------------------------------------*/
1254 /* popRegFromString -                                                                                      */
1255 /*-----------------------------------------------------------------*/
1256 pCodeOp *popRegFromString(char *str, int size, int offset)
1257 {
1258         
1259         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1260         pcop->type = PO_DIR;
1261         
1262         DEBUGpic14_emitcode(";","%d",__LINE__);
1263         
1264         if(!str)
1265                 str = "BAD_STRING";
1266         
1267         pcop->name = Safe_calloc(1,strlen(str)+1);
1268         strcpy(pcop->name,str);
1269         
1270         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271         
1272         PCOR(pcop)->r = dirregWithName(pcop->name);
1273         if(PCOR(pcop)->r == NULL) {
1274                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1275                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1276                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1277         } else {
1278                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1279         }
1280         PCOR(pcop)->instance = offset;
1281         
1282         return pcop;
1283 }
1284
1285 /*-----------------------------------------------------------------*/
1286 /*-----------------------------------------------------------------*/
1287 pCodeOp *popRegFromIdx(int rIdx)
1288 {
1289         pCodeOp *pcop;
1290         
1291         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1292                 __FUNCTION__,__LINE__,rIdx);
1293         
1294         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295         
1296         PCOR(pcop)->rIdx = rIdx;
1297         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1298         PCOR(pcop)->r->isFree = 0;
1299         PCOR(pcop)->r->wasUsed = 1;
1300         
1301         pcop->type = PCOR(pcop)->r->pc_type;
1302         
1303         
1304         return pcop;
1305 }
1306
1307 /*-----------------------------------------------------------------*/
1308 /* popGet - asm operator to pcode operator conversion                      */
1309 /*-----------------------------------------------------------------*/
1310 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1311 {
1312         //char *s = buffer ;
1313         //char *rs;
1314         
1315         pCodeOp *pcop;
1316         
1317         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1318         /* offset is greater than
1319         size then zero */
1320         
1321         if (offset > (aop->size - 1) &&
1322                 aop->type != AOP_LIT)
1323                 return NULL;  //zero;
1324         
1325         /* depending on type */
1326         switch (aop->type) {
1327                 
1328         case AOP_R0:
1329         case AOP_R1:
1330         case AOP_DPTR:
1331         case AOP_DPTR2:
1332         case AOP_ACC:
1333                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1334                 return NULL;
1335                 
1336         case AOP_IMMD:
1337                 DEBUGpic14_emitcode(";","%d",__LINE__);
1338                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1339                 
1340         case AOP_DIR:
1341                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1342 #if 0
1343                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1344                 pcop->type = PO_DIR;
1345                 
1346                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1347                 strcpy(pcop->name,aop->aopu.aop_dir);   
1348                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1349                 if(PCOR(pcop)->r == NULL) {
1350                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1351                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1352                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1353                 } else {
1354                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1355                 }
1356                 PCOR(pcop)->instance = offset;
1357                 
1358                 return pcop;
1359 #endif
1360                 
1361         case AOP_REG:
1362                 {
1363                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1364                         
1365                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1366                         PCOR(pcop)->rIdx = rIdx;
1367                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1368                         PCOR(pcop)->r->wasUsed=1;
1369                         PCOR(pcop)->r->isFree=0;
1370                         
1371                         PCOR(pcop)->instance = offset;
1372                         pcop->type = PCOR(pcop)->r->pc_type;
1373                         //rs = aop->aopu.aop_reg[offset]->name;
1374                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1375                         return pcop;
1376                 }
1377                 
1378         case AOP_CRY:
1379                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1380                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1381                 //if(PCOR(pcop)->r == NULL)
1382                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1383                 return pcop;
1384                 
1385         case AOP_LIT:
1386                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1387                 
1388         case AOP_STR:
1389                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1390                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1391                 /*
1392                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1393                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1394                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1395                 pcop->type = PCOR(pcop)->r->pc_type;
1396                 pcop->name = PCOR(pcop)->r->name;
1397                 
1398                   return pcop;
1399                 */
1400                 
1401         case AOP_PCODE:
1402                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1403                         __LINE__, 
1404                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1405                 pcop = pCodeOpCopy(aop->aopu.pcop);
1406                 PCOI(pcop)->offset = offset;
1407                 return pcop;
1408         }
1409         
1410         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1411                 "popGet got unsupported aop->type");
1412         exit(0);
1413 }
1414 /*-----------------------------------------------------------------*/
1415 /* aopPut - puts a string for a aop                                                        */
1416 /*-----------------------------------------------------------------*/
1417 void aopPut (asmop *aop, char *s, int offset)
1418 {
1419         char *d = buffer ;
1420         symbol *lbl ;
1421         
1422         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1423         
1424         if (aop->size && offset > ( aop->size - 1)) {
1425                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1426                         "aopPut got offset > aop->size");
1427                 exit(0);
1428         }
1429         
1430         /* will assign value to value */
1431         /* depending on where it is ofcourse */
1432         switch (aop->type) {
1433         case AOP_DIR:
1434                 if (offset) {
1435                         sprintf(d,"(%s + %d)",
1436                                 aop->aopu.aop_dir,offset);
1437                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1438                         
1439                 } else
1440                         sprintf(d,"%s",aop->aopu.aop_dir);
1441                 
1442                 if (strcmp(d,s)) {
1443                         DEBUGpic14_emitcode(";","%d",__LINE__);
1444                         if(strcmp(s,"W"))
1445                                 pic14_emitcode("movf","%s,w",s);
1446                         pic14_emitcode("movwf","%s",d);
1447                         
1448                         if(strcmp(s,"W")) {
1449                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1450                                 if(offset >= aop->size) {
1451                                         emitpcode(POC_CLRF,popGet(aop,offset));
1452                                         break;
1453                                 } else
1454                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1455                         }
1456                         
1457                         emitpcode(POC_MOVWF,popGet(aop,offset));
1458                         
1459                         
1460                 }
1461                 break;
1462                 
1463         case AOP_REG:
1464                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1465                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1466                         /*
1467                         if (*s == '@'             ||
1468                         strcmp(s,"r0") == 0 ||
1469                         strcmp(s,"r1") == 0 ||
1470                         strcmp(s,"r2") == 0 ||
1471                         strcmp(s,"r3") == 0 ||
1472                         strcmp(s,"r4") == 0 ||
1473                         strcmp(s,"r5") == 0 ||
1474                         strcmp(s,"r6") == 0 || 
1475                         strcmp(s,"r7") == 0 )
1476                         pic14_emitcode("mov","%s,%s  ; %d",
1477                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1478                         else
1479                         */
1480                         
1481                         if(strcmp(s,"W")==0 )
1482                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1483                         
1484                         pic14_emitcode("movwf","%s",
1485                                 aop->aopu.aop_reg[offset]->name);
1486                         
1487                         if(strcmp(s,zero)==0) {
1488                                 emitpcode(POC_CLRF,popGet(aop,offset));
1489                                 
1490                         } else if(strcmp(s,"W")==0) {
1491                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1492                                 pcop->type = PO_GPR_REGISTER;
1493                                 
1494                                 PCOR(pcop)->rIdx = -1;
1495                                 PCOR(pcop)->r = NULL;
1496                                 
1497                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1498                                 pcop->name = Safe_strdup(s);
1499                                 emitpcode(POC_MOVFW,pcop);
1500                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1501                         } else if(strcmp(s,one)==0) {
1502                                 emitpcode(POC_CLRF,popGet(aop,offset));
1503                                 emitpcode(POC_INCF,popGet(aop,offset));
1504                         } else {
1505                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1506                         }
1507                 }
1508                 break;
1509                 
1510         case AOP_DPTR:
1511         case AOP_DPTR2:
1512                 
1513                 if (aop->type == AOP_DPTR2)
1514                 {
1515                         genSetDPTR(1);
1516                 }
1517                 
1518                 if (aop->code) {
1519                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1520                                 "aopPut writting to code space");
1521                         exit(0);
1522                 }
1523                 
1524                 while (offset > aop->coff) {
1525                         aop->coff++;
1526                         pic14_emitcode ("inc","dptr");
1527                 }
1528                 
1529                 while (offset < aop->coff) {
1530                         aop->coff-- ;
1531                         pic14_emitcode("lcall","__decdptr");
1532                 }
1533                 
1534                 aop->coff = offset;
1535                 
1536                 /* if not in accumulater */
1537                 MOVA(s);
1538                 
1539                 pic14_emitcode ("movx","@dptr,a");
1540                 
1541                 if (aop->type == AOP_DPTR2)
1542                 {
1543                         genSetDPTR(0);
1544                 }
1545                 break;
1546                 
1547         case AOP_R0:
1548         case AOP_R1:
1549                 while (offset > aop->coff) {
1550                         aop->coff++;
1551                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1552                 }
1553                 while (offset < aop->coff) {
1554                         aop->coff-- ;
1555                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1556                 }
1557                 aop->coff = offset;
1558                 
1559                 if (aop->paged) {
1560                         MOVA(s);                         
1561                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1562                         
1563                 } else
1564                         if (*s == '@') {
1565                                 MOVA(s);
1566                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1567                         } else
1568                                 if (strcmp(s,"r0") == 0 ||
1569                                         strcmp(s,"r1") == 0 ||
1570                                         strcmp(s,"r2") == 0 ||
1571                                         strcmp(s,"r3") == 0 ||
1572                                         strcmp(s,"r4") == 0 ||
1573                                         strcmp(s,"r5") == 0 ||
1574                                         strcmp(s,"r6") == 0 || 
1575                                         strcmp(s,"r7") == 0 ) {
1576                                         char buffer[10];
1577                                         sprintf(buffer,"a%s",s);
1578                                         pic14_emitcode("mov","@%s,%s",
1579                                                 aop->aopu.aop_ptr->name,buffer);
1580                                 } else
1581                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1582                                 
1583                                 break;
1584                                 
1585         case AOP_STK:
1586                 if (strcmp(s,"a") == 0)
1587                         pic14_emitcode("push","acc");
1588                 else
1589                         pic14_emitcode("push","%s",s);
1590                 
1591                 break;
1592                 
1593         case AOP_CRY:
1594                 /* if bit variable */
1595                 if (!aop->aopu.aop_dir) {
1596                         pic14_emitcode("clr","a");
1597                         pic14_emitcode("rlc","a");
1598                 } else {
1599                         if (s == zero) 
1600                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1601                         else
1602                                 if (s == one)
1603                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1604                                 else
1605                                         if (!strcmp(s,"c"))
1606                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1607                                         else {
1608                                                 lbl = newiTempLabel(NULL);
1609                                                 
1610                                                 if (strcmp(s,"a")) {
1611                                                         MOVA(s);
1612                                                 }
1613                                                 pic14_emitcode("clr","c");
1614                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1615                                                 pic14_emitcode("cpl","c");
1616                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1617                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1618                                         }
1619                 }
1620                 break;
1621                 
1622         case AOP_STR:
1623                 aop->coff = offset;
1624                 if (strcmp(aop->aopu.aop_str[offset],s))
1625                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1626                 break;
1627                 
1628         case AOP_ACC:
1629                 aop->coff = offset;
1630                 if (!offset && (strcmp(s,"acc") == 0))
1631                         break;
1632                 
1633                 if (strcmp(aop->aopu.aop_str[offset],s))
1634                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1635                 break;
1636                 
1637         default :
1638                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1639                         "aopPut got unsupported aop->type");
1640                 exit(0);
1641         }
1642         
1643 }
1644
1645 /*-----------------------------------------------------------------*/
1646 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1647 /*-----------------------------------------------------------------*/
1648 void mov2w (asmop *aop, int offset)
1649 {
1650         
1651         if(!aop)
1652                 return;
1653         
1654         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1655         
1656         if ( aop->type == AOP_PCODE ||
1657                 aop->type == AOP_LIT ||
1658                 aop->type == AOP_IMMD )
1659                 emitpcode(POC_MOVLW,popGet(aop,offset));
1660         else
1661                 emitpcode(POC_MOVFW,popGet(aop,offset));
1662         
1663 }
1664
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should        */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1669 {
1670         int size ;
1671         
1672         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1673         aop->coff = 0;
1674         if ((size = aop->size) <= 1)
1675                 return ;
1676         size-- ;
1677         switch (aop->type) {
1678         case AOP_R0 :
1679         case AOP_R1 :
1680                 while (size--)
1681                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1682                 break;                  
1683         case AOP_DPTR :
1684         case AOP_DPTR2:
1685                 if (aop->type == AOP_DPTR2)
1686                 {
1687                         genSetDPTR(1);
1688                 } 
1689                 while (size--)
1690                 {
1691                         pic14_emitcode("lcall","__decdptr");
1692                 }
1693                 
1694                 if (aop->type == AOP_DPTR2)
1695                 {
1696                         genSetDPTR(0);
1697                 }
1698                 break;
1699                 
1700         }
1701         
1702 }
1703
1704
1705 #if 0
1706 /*-----------------------------------------------------------------*/
1707 /* opIsGptr: returns non-zero if the passed operand is             */
1708 /* a generic pointer type.                                         */
1709 /*-----------------------------------------------------------------*/ 
1710 static int opIsGptr(operand *op)
1711 {
1712         sym_link *type = operandType(op);
1713         
1714         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1715         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1716         {
1717                 return 1;
1718         }
1719         return 0;          
1720 }
1721 #endif
1722
1723 /*-----------------------------------------------------------------*/
1724 /* pic14_getDataSize - get the operand data size                   */
1725 /*-----------------------------------------------------------------*/
1726 int pic14_getDataSize(operand *op)
1727 {
1728         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1729         
1730         
1731         return AOP_SIZE(op);
1732         
1733         // tsd- in the pic port, the genptr size is 1, so this code here
1734         // fails. ( in the 8051 port, the size was 4).
1735 #if 0
1736         int size;
1737         size = AOP_SIZE(op);
1738         if (size == GPTRSIZE)
1739         {
1740                 sym_link *type = operandType(op);
1741                 if (IS_GENPTR(type))
1742                 {
1743                         /* generic pointer; arithmetic operations
1744                         * should ignore the high byte (pointer type).
1745                         */
1746                         size--;
1747                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1748                 }
1749         }
1750         return size;
1751 #endif
1752 }
1753
1754 /*-----------------------------------------------------------------*/
1755 /* pic14_outAcc - output Acc                                       */
1756 /*-----------------------------------------------------------------*/
1757 void pic14_outAcc(operand *result)
1758 {
1759         int size,offset;
1760         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1761         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1762         
1763         
1764         size = pic14_getDataSize(result);
1765         if(size){
1766                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1767                 size--;
1768                 offset = 1;
1769                 /* unsigned or positive */
1770                 while(size--)
1771                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1772         }
1773         
1774 }
1775
1776 /*-----------------------------------------------------------------*/
1777 /* pic14_outBitC - output a bit C                                  */
1778 /*-----------------------------------------------------------------*/
1779 void pic14_outBitC(operand *result)
1780 {
1781         
1782         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1783         /* if the result is bit */
1784         if (AOP_TYPE(result) == AOP_CRY) 
1785                 aopPut(AOP(result),"c",0);
1786         else {
1787                 pic14_emitcode("clr","a  ; %d", __LINE__);
1788                 pic14_emitcode("rlc","a");
1789                 pic14_outAcc(result);
1790         }
1791 }
1792
1793 /*-----------------------------------------------------------------*/
1794 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1795 /*-----------------------------------------------------------------*/
1796 void pic14_toBoolean(operand *oper)
1797 {
1798         int size = AOP_SIZE(oper) - 1;
1799         int offset = 1;
1800         
1801         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1802         
1803         if ( AOP_TYPE(oper) != AOP_ACC) {
1804                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1805         }
1806         while (size--) {
1807                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1808         }
1809 }
1810
1811
1812 /*-----------------------------------------------------------------*/
1813 /* genNot - generate code for ! operation                          */
1814 /*-----------------------------------------------------------------*/
1815 static void genNot (iCode *ic)
1816 {
1817         symbol *tlbl;
1818         int size;
1819         
1820         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1821         /* assign asmOps to operand & result */
1822         aopOp (IC_LEFT(ic),ic,FALSE);
1823         aopOp (IC_RESULT(ic),ic,TRUE);
1824         
1825         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1826         /* if in bit space then a special case */
1827         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1828                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1829                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1830                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1831                 } else {
1832                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1833                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1834                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1835                 }
1836                 goto release;
1837         }
1838         
1839         size = AOP_SIZE(IC_LEFT(ic));
1840         if(size == 1) {
1841                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1842                 emitpcode(POC_ANDLW,popGetLit(1));
1843                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1844                 goto release;
1845         }
1846         pic14_toBoolean(IC_LEFT(ic));
1847         
1848         tlbl = newiTempLabel(NULL);
1849         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1850         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1851         pic14_outBitC(IC_RESULT(ic));
1852         
1853 release:        
1854         /* release the aops */
1855         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1856         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1857 }
1858
1859
1860 /*-----------------------------------------------------------------*/
1861 /* genCpl - generate code for complement                                                   */
1862 /*-----------------------------------------------------------------*/
1863 static void genCpl (iCode *ic)
1864 {
1865         operand *left, *result;
1866         int size, offset=0;  
1867         
1868         
1869         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1870         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1871         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1872         
1873         /* if both are in bit space then 
1874         a special case */
1875         if (AOP_TYPE(result) == AOP_CRY &&
1876                 AOP_TYPE(left) == AOP_CRY ) { 
1877                 
1878                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1879                 pic14_emitcode("cpl","c"); 
1880                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1881                 goto release; 
1882         } 
1883         
1884         size = AOP_SIZE(result);
1885         while (size--) {
1886                 
1887                 if(AOP_TYPE(left) == AOP_ACC) 
1888                         emitpcode(POC_XORLW, popGetLit(0xff));
1889                 else
1890                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1891                 
1892                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1893                 offset++;
1894         }
1895         
1896         
1897 release:
1898         /* release the aops */
1899         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1900         freeAsmop(result,NULL,ic,TRUE);
1901 }
1902
1903 /*-----------------------------------------------------------------*/
1904 /* genUminusFloat - unary minus for floating points                        */
1905 /*-----------------------------------------------------------------*/
1906 static void genUminusFloat(operand *op,operand *result)
1907 {
1908         int size ,offset =0 ;
1909         char *l;
1910         
1911         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1912         /* for this we just need to flip the 
1913         first it then copy the rest in place */
1914         size = AOP_SIZE(op) - 1;
1915         l = aopGet(AOP(op),3,FALSE,FALSE);
1916         
1917         MOVA(l);          
1918         
1919         pic14_emitcode("cpl","acc.7");
1920         aopPut(AOP(result),"a",3);      
1921         
1922         while(size--) {
1923                 aopPut(AOP(result),
1924                         aopGet(AOP(op),offset,FALSE,FALSE),
1925                         offset);
1926                 offset++;
1927         }                
1928 }
1929
1930 /*-----------------------------------------------------------------*/
1931 /* genUminus - unary minus code generation                                                 */
1932 /*-----------------------------------------------------------------*/
1933 static void genUminus (iCode *ic)
1934 {
1935         int size, i;
1936         sym_link *optype, *rtype;
1937         
1938         
1939         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1940         /* assign asmops */
1941         aopOp(IC_LEFT(ic),ic,FALSE);
1942         aopOp(IC_RESULT(ic),ic,TRUE);
1943         
1944         /* if both in bit space then special
1945         case */
1946         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1947                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1948                 
1949                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
1950                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1951                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
1952                 
1953                 goto release; 
1954         } 
1955         
1956         optype = operandType(IC_LEFT(ic));
1957         rtype = operandType(IC_RESULT(ic));
1958         
1959         /* if float then do float stuff */
1960         if (IS_FLOAT(optype)) {
1961                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1962                 goto release;
1963         }
1964         
1965         /* otherwise subtract from zero by taking the 2's complement */
1966         size = AOP_SIZE(IC_LEFT(ic));
1967         
1968         for(i=0; i<size; i++) {
1969                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1970                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1971                 else {
1972                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1973                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1974                 }
1975         }
1976         
1977         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1978         for(i=1; i<size; i++) {
1979                 emitSKPNZ;
1980                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1981         }
1982         
1983 release:
1984         /* release the aops */
1985         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1986         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
1987 }
1988
1989 /*-----------------------------------------------------------------*/
1990 /* saveRegisters - will look for a call and save the registers     */
1991 /*-----------------------------------------------------------------*/
1992 static void saveRegisters(iCode *lic) 
1993 {
1994         int i;
1995         iCode *ic;
1996         bitVect *rsave;
1997         sym_link *dtype;
1998         
1999         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2000         /* look for call */
2001         for (ic = lic ; ic ; ic = ic->next) 
2002                 if (ic->op == CALL || ic->op == PCALL)
2003                         break;
2004                 
2005                 if (!ic) {
2006                         fprintf(stderr,"found parameter push with no function call\n");
2007                         return ;
2008                 }
2009                 
2010                 /* if the registers have been saved already then
2011                 do nothing */
2012                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2013                         return ;
2014                 
2015                         /* find the registers in use at this time 
2016                 and push them away to safety */
2017                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2018                         ic->rUsed);
2019                 
2020                 ic->regsSaved = 1;
2021                 if (options.useXstack) {
2022                         if (bitVectBitValue(rsave,R0_IDX))
2023                                 pic14_emitcode("mov","b,r0");
2024                         pic14_emitcode("mov","r0,%s",spname);
2025                         for (i = 0 ; i < pic14_nRegs ; i++) {
2026                                 if (bitVectBitValue(rsave,i)) {
2027                                         if (i == R0_IDX)
2028                                                 pic14_emitcode("mov","a,b");
2029                                         else
2030                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2031                                         pic14_emitcode("movx","@r0,a");
2032                                         pic14_emitcode("inc","r0");
2033                                 }
2034                         }
2035                         pic14_emitcode("mov","%s,r0",spname);
2036                         if (bitVectBitValue(rsave,R0_IDX))
2037                                 pic14_emitcode("mov","r0,b");     
2038                 }// else
2039                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2040                 //        if (bitVectBitValue(rsave,i))
2041                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2042                 //}
2043                 
2044                 dtype = operandType(IC_LEFT(ic));
2045                 if (currFunc && dtype && 
2046                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2047                         IFFUNC_ISISR(currFunc->type) &&
2048                         !ic->bankSaved) 
2049                         
2050                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2051                 
2052 }
2053 /*-----------------------------------------------------------------*/
2054 /* unsaveRegisters - pop the pushed registers                                      */
2055 /*-----------------------------------------------------------------*/
2056 static void unsaveRegisters (iCode *ic)
2057 {
2058         int i;
2059         bitVect *rsave;
2060         
2061         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2062         /* find the registers in use at this time 
2063         and push them away to safety */
2064         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2065                 ic->rUsed);
2066         
2067         if (options.useXstack) {
2068                 pic14_emitcode("mov","r0,%s",spname); 
2069                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2070                         if (bitVectBitValue(rsave,i)) {
2071                                 pic14_emitcode("dec","r0");
2072                                 pic14_emitcode("movx","a,@r0");
2073                                 if (i == R0_IDX)
2074                                         pic14_emitcode("mov","b,a");
2075                                 else
2076                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2077                         }       
2078                         
2079                 }
2080                 pic14_emitcode("mov","%s,r0",spname);
2081                 if (bitVectBitValue(rsave,R0_IDX))
2082                         pic14_emitcode("mov","r0,b");
2083         } //else
2084         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2085         //      if (bitVectBitValue(rsave,i))
2086         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2087         //}
2088         
2089 }  
2090
2091
2092 /*-----------------------------------------------------------------*/
2093 /* pushSide -                            */
2094 /*-----------------------------------------------------------------*/
2095 static void pushSide(operand * oper, int size)
2096 {
2097 #if 0
2098         int offset = 0;
2099         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2100         while (size--) {
2101                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2102                 if (AOP_TYPE(oper) != AOP_REG &&
2103                         AOP_TYPE(oper) != AOP_DIR &&
2104                         strcmp(l,"a") ) {
2105                         pic14_emitcode("mov","a,%s",l);
2106                         pic14_emitcode("push","acc");
2107                 } else
2108                         pic14_emitcode("push","%s",l);
2109         }
2110 #endif
2111 }
2112
2113 /*-----------------------------------------------------------------*/
2114 /* assignResultValue -                           */
2115 /*-----------------------------------------------------------------*/
2116 static void assignResultValue(operand * oper)
2117 {
2118         int size = AOP_SIZE(oper);
2119         
2120         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2121         
2122         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2123         
2124         while (size--) {
2125                 if (GpsuedoStkPtr++)
2126                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2127                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2128         }
2129 }
2130
2131
2132 /*-----------------------------------------------------------------*/
2133 /* genIpush - genrate code for pushing this gets a little complex  */
2134 /*-----------------------------------------------------------------*/
2135 static void genIpush (iCode *ic)
2136 {
2137         
2138         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2139 #if 0
2140         int size, offset = 0 ;
2141         char *l;
2142         
2143         
2144         /* if this is not a parm push : ie. it is spill push 
2145         and spill push is always done on the local stack */
2146         if (!ic->parmPush) {
2147                 
2148                 /* and the item is spilt then do nothing */
2149                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2150                         return ;
2151                 
2152                 aopOp(IC_LEFT(ic),ic,FALSE);
2153                 size = AOP_SIZE(IC_LEFT(ic));
2154                 /* push it on the stack */
2155                 while(size--) {
2156                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2157                         if (*l == '#') {
2158                                 MOVA(l);
2159                                 l = "acc";
2160                         }
2161                         pic14_emitcode("push","%s",l);
2162                 }
2163                 return ;                
2164         }
2165         
2166         /* this is a paramter push: in this case we call
2167         the routine to find the call and save those
2168         registers that need to be saved */   
2169         saveRegisters(ic);
2170         
2171         /* then do the push */
2172         aopOp(IC_LEFT(ic),ic,FALSE);
2173         
2174         
2175         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2176         size = AOP_SIZE(IC_LEFT(ic));
2177         
2178         while (size--) {
2179                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2180                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2181                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2182                         strcmp(l,"a") ) {
2183                         pic14_emitcode("mov","a,%s",l);
2184                         pic14_emitcode("push","acc");
2185                 } else
2186                         pic14_emitcode("push","%s",l);
2187         }         
2188         
2189         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2190 #endif
2191 }
2192
2193 /*-----------------------------------------------------------------*/
2194 /* genIpop - recover the registers: can happen only for spilling   */
2195 /*-----------------------------------------------------------------*/
2196 static void genIpop (iCode *ic)
2197 {
2198         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2199 #if 0
2200         int size,offset ;
2201         
2202         
2203         /* if the temp was not pushed then */
2204         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2205                 return ;
2206         
2207         aopOp(IC_LEFT(ic),ic,FALSE);
2208         size = AOP_SIZE(IC_LEFT(ic));
2209         offset = (size-1);
2210         while (size--) 
2211                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2212                 FALSE,TRUE));
2213         
2214         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2215 #endif
2216 }
2217
2218 /*-----------------------------------------------------------------*/
2219 /* unsaverbank - restores the resgister bank from stack                    */
2220 /*-----------------------------------------------------------------*/
2221 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2222 {
2223         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2224 #if 0
2225         int i;
2226         asmop *aop ;
2227         regs *r = NULL;
2228         
2229         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2230         if (popPsw) {
2231                 if (options.useXstack) {
2232                         aop = newAsmop(0);
2233                         r = getFreePtr(ic,&aop,FALSE);
2234                         
2235                         
2236                         pic14_emitcode("mov","%s,_spx",r->name);
2237                         pic14_emitcode("movx","a,@%s",r->name);
2238                         pic14_emitcode("mov","psw,a");
2239                         pic14_emitcode("dec","%s",r->name);
2240                         
2241                 }else
2242                         pic14_emitcode ("pop","psw");
2243         }
2244         
2245         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2246                 if (options.useXstack) {           
2247                         pic14_emitcode("movx","a,@%s",r->name);
2248                         //pic14_emitcode("mov","(%s+%d),a",
2249                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2250                         pic14_emitcode("dec","%s",r->name);
2251                         
2252                 } else 
2253                         pic14_emitcode("pop",""); //"(%s+%d)",
2254                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2255         }
2256         
2257         if (options.useXstack) {
2258                 
2259                 pic14_emitcode("mov","_spx,%s",r->name);
2260                 freeAsmop(NULL,aop,ic,TRUE);
2261                 
2262         }
2263 #endif 
2264 }
2265
2266 /*-----------------------------------------------------------------*/
2267 /* saverbank - saves an entire register bank on the stack                  */
2268 /*-----------------------------------------------------------------*/
2269 static void saverbank (int bank, iCode *ic, bool pushPsw)
2270 {
2271         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2272 #if 0
2273         int i;
2274         asmop *aop ;
2275         regs *r = NULL;
2276         
2277         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2278         if (options.useXstack) {
2279                 
2280                 aop = newAsmop(0);
2281                 r = getFreePtr(ic,&aop,FALSE);  
2282                 pic14_emitcode("mov","%s,_spx",r->name);
2283                 
2284         }
2285         
2286         for (i = 0 ; i < pic14_nRegs ;i++) {
2287                 if (options.useXstack) {
2288                         pic14_emitcode("inc","%s",r->name);
2289                         //pic14_emitcode("mov","a,(%s+%d)",
2290                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2291                         pic14_emitcode("movx","@%s,a",r->name);                 
2292                 } else 
2293                         pic14_emitcode("push","");// "(%s+%d)",
2294                 //regspic14[i].base,8*bank+regspic14[i].offset);
2295         }
2296         
2297         if (pushPsw) {
2298                 if (options.useXstack) {
2299                         pic14_emitcode("mov","a,psw");
2300                         pic14_emitcode("movx","@%s,a",r->name); 
2301                         pic14_emitcode("inc","%s",r->name);
2302                         pic14_emitcode("mov","_spx,%s",r->name);                 
2303                         freeAsmop (NULL,aop,ic,TRUE);
2304                         
2305                 } else
2306                         pic14_emitcode("push","psw");
2307                 
2308                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2309         }
2310         ic->bankSaved = 1;
2311 #endif
2312 }
2313
2314 /*-----------------------------------------------------------------*/
2315 /* genCall - generates a call statement                                                    */
2316 /*-----------------------------------------------------------------*/
2317 static void genCall (iCode *ic)
2318 {
2319         sym_link *dtype;         
2320         symbol *sym;
2321         unsigned char *name;
2322         int isExtern;
2323         
2324         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2325         
2326         /* if caller saves & we have not saved then */
2327         if (!ic->regsSaved)
2328                 saveRegisters(ic);
2329         
2330                 /* if we are calling a function that is not using
2331                 the same register bank then we need to save the
2332         destination registers on the stack */
2333         dtype = operandType(IC_LEFT(ic));
2334         if (currFunc && dtype && 
2335                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2336                 IFFUNC_ISISR(currFunc->type) &&
2337                 !ic->bankSaved) 
2338                 
2339                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2340         
2341         /* if send set is not empty the assign */
2342         if (_G.sendSet) {
2343                 iCode *sic;
2344                 /* For the Pic port, there is no data stack.
2345                 * So parameters passed to functions are stored
2346                 * in registers. (The pCode optimizer will get
2347                 * rid of most of these :).
2348                 */
2349                 int psuedoStkPtr=-1;
2350                 int firstTimeThruLoop = 1;
2351                 
2352                 _G.sendSet = reverseSet(_G.sendSet);
2353                 
2354                 /* First figure how many parameters are getting passed */
2355                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2356                 sic = setNextItem(_G.sendSet)) {
2357                         
2358                         aopOp(IC_LEFT(sic),sic,FALSE);
2359                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2360                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2361                 }
2362                 
2363                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2364                 sic = setNextItem(_G.sendSet)) {
2365                         int size, offset = 0;
2366                         
2367                         aopOp(IC_LEFT(sic),sic,FALSE);
2368                         size = AOP_SIZE(IC_LEFT(sic));
2369                         
2370                         while (size--) {
2371                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2372                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2373                                 
2374                                 if(!firstTimeThruLoop) {
2375                                         /* If this is not the first time we've been through the loop
2376                                         * then we need to save the parameter in a temporary
2377                                         * register. The last byte of the last parameter is
2378                                         * passed in W. */
2379                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2380                                         
2381                                 }
2382                                 firstTimeThruLoop=0;
2383                                 
2384                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2385                                 offset++;
2386                         }
2387                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2388                 }
2389                 _G.sendSet = NULL;
2390         }
2391         /* make the call */
2392         sym = OP_SYMBOL(IC_LEFT(ic));
2393         name = sym->rname[0] ? sym->rname : sym->name;
2394         isExtern = IS_EXTERN(sym->etype);
2395         if (isExtern) {
2396                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2397         }
2398         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2399         if (isExtern) {
2400                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2401         }
2402         GpsuedoStkPtr=0;
2403         /* if we need assign a result value */
2404         if ((IS_ITEMP(IC_RESULT(ic)) && 
2405                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2406                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2407                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2408                 
2409                 _G.accInUse++;
2410                 aopOp(IC_RESULT(ic),ic,FALSE);
2411                 _G.accInUse--;
2412                 
2413                 assignResultValue(IC_RESULT(ic));
2414                 
2415                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2416                         AopType(AOP_TYPE(IC_RESULT(ic))));
2417                 
2418                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2419         }
2420         
2421         /* adjust the stack for parameters if 
2422         required */
2423         if (ic->parmBytes) {
2424                 int i;
2425                 if (ic->parmBytes > 3) {
2426                         pic14_emitcode("mov","a,%s",spname);
2427                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2428                         pic14_emitcode("mov","%s,a",spname);
2429                 } else 
2430                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2431                                 pic14_emitcode("dec","%s",spname);
2432                         
2433         }
2434         
2435         /* if register bank was saved then pop them */
2436         if (ic->bankSaved)
2437                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2438         
2439         /* if we hade saved some registers then unsave them */
2440         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2441                 unsaveRegisters (ic);
2442         
2443         
2444 }
2445
2446 /*-----------------------------------------------------------------*/
2447 /* genPcall - generates a call by pointer statement                        */
2448 /*-----------------------------------------------------------------*/
2449 static void genPcall (iCode *ic)
2450 {
2451         sym_link *dtype;
2452         symbol *albl = newiTempLabel(NULL);
2453         symbol *blbl = newiTempLabel(NULL);
2454         PIC_OPCODE poc;
2455         pCodeOp *pcop;
2456         operand *left;
2457         
2458         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2459         /* if caller saves & we have not saved then */
2460         if (!ic->regsSaved)
2461                 saveRegisters(ic);
2462         
2463                 /* if we are calling a function that is not using
2464                 the same register bank then we need to save the
2465         destination registers on the stack */
2466         dtype = operandType(IC_LEFT(ic));
2467         if (currFunc && dtype && 
2468                 IFFUNC_ISISR(currFunc->type) &&
2469                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2470                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2471         
2472         left = IC_LEFT(ic);
2473         aopOp(left,ic,FALSE);
2474         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2475         
2476         pushSide(IC_LEFT(ic), FPTRSIZE);
2477         
2478         /* if send set is not empty, assign parameters */
2479         if (_G.sendSet) {
2480                 
2481                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2482                 /* no way to pass args - W always gets used to make the call */
2483         }
2484         /* first idea - factor out a common helper function and call it.
2485         But don't know how to get it generated only once in its own block
2486         
2487         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2488                 char *rname;
2489                 char *buffer;
2490                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2491                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2492                 buffer = Safe_calloc(1,strlen(rname)+16);
2493                 sprintf(buffer, "%s_goto_helper", rname);
2494                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2495                 free(buffer);
2496         }
2497         */
2498         emitpcode(POC_CALL,popGetLabel(albl->key));
2499         pcop = popGetLabel(blbl->key);
2500         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2501         emitpcode(POC_GOTO,pcop);
2502         emitpLabel(albl->key);
2503         
2504         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2505         
2506         emitpcode(poc,popGet(AOP(left),1));
2507         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2508         emitpcode(poc,popGet(AOP(left),0));
2509         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2510         
2511         emitpLabel(blbl->key);
2512         
2513         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2514         
2515         /* if we need to assign a result value */
2516         if ((IS_ITEMP(IC_RESULT(ic)) &&
2517                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2518                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2519                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2520                 
2521                 _G.accInUse++;
2522                 aopOp(IC_RESULT(ic),ic,FALSE);
2523                 _G.accInUse--;
2524                 
2525                 assignResultValue(IC_RESULT(ic));
2526                 
2527                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2528         }
2529         
2530         /* if register bank was saved then unsave them */
2531         if (currFunc && dtype && 
2532                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2533                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534         
2535                 /* if we hade saved some registers then
2536         unsave them */
2537         if (ic->regsSaved)
2538                 unsaveRegisters (ic);
2539         
2540 }
2541
2542 /*-----------------------------------------------------------------*/
2543 /* resultRemat - result  is rematerializable                                       */
2544 /*-----------------------------------------------------------------*/
2545 static int resultRemat (iCode *ic)
2546 {
2547         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2548         if (SKIP_IC(ic) || ic->op == IFX)
2549                 return 0;
2550         
2551         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2552                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2553                 if (sym->remat && !POINTER_SET(ic)) 
2554                         return 1;
2555         }
2556         
2557         return 0;
2558 }
2559
2560 #if defined(__BORLANDC__) || defined(_MSC_VER)
2561 #define STRCASECMP stricmp
2562 #else
2563 #define STRCASECMP strcasecmp
2564 #endif
2565
2566 #if 0
2567 /*-----------------------------------------------------------------*/
2568 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2569 /*-----------------------------------------------------------------*/
2570 static bool inExcludeList(char *s)
2571 {
2572         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2573         int i =0;
2574         
2575         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2576         if (options.excludeRegs[i] &&
2577                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2578                 return FALSE ;
2579         
2580         for ( i = 0 ; options.excludeRegs[i]; i++) {
2581                 if (options.excludeRegs[i] &&
2582                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2583                         return TRUE;
2584         }
2585         return FALSE ;
2586 }
2587 #endif
2588
2589 /*-----------------------------------------------------------------*/
2590 /* genFunction - generated code for function entry                                 */
2591 /*-----------------------------------------------------------------*/
2592 static void genFunction (iCode *ic)
2593 {
2594         symbol *sym;
2595         sym_link *ftype;
2596         
2597         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2598         
2599         labelOffset += (max_key+4);
2600         max_key=0;
2601         GpsuedoStkPtr=0;
2602         _G.nRegsSaved = 0;
2603         /* create the function header */
2604         pic14_emitcode(";","-----------------------------------------");
2605         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2606         pic14_emitcode(";","-----------------------------------------");
2607         
2608         pic14_emitcode("","%s:",sym->rname);
2609         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2610         
2611         ftype = operandType(IC_LEFT(ic));
2612         
2613         /* if critical function then turn interrupts off */
2614         if (IFFUNC_ISCRITICAL(ftype))
2615                 pic14_emitcode("clr","ea");
2616         
2617                 /* here we need to generate the equates for the
2618         register bank if required */
2619 #if 0
2620         if (FUNC_REGBANK(ftype) != rbank) {
2621                 int i ;
2622                 
2623                 rbank = FUNC_REGBANK(ftype);
2624                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2625                         if (strcmp(regspic14[i].base,"0") == 0)
2626                                 pic14_emitcode("","%s = 0x%02x",
2627                                 regspic14[i].dname,
2628                                 8*rbank+regspic14[i].offset);
2629                         else
2630                                 pic14_emitcode ("","%s = %s + 0x%02x",
2631                                 regspic14[i].dname,
2632                                 regspic14[i].base,
2633                                 8*rbank+regspic14[i].offset);
2634                 }
2635         }
2636 #endif
2637         
2638         /* if this is an interrupt service routine */
2639         if (IFFUNC_ISISR(sym->type)) {
2640         /*  already done in pic14createInterruptVect() - delete me
2641         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2642         emitpcodeNULLop(POC_NOP);
2643         emitpcodeNULLop(POC_NOP);
2644         emitpcodeNULLop(POC_NOP);
2645                 */
2646                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2647                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2648                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2649                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2650                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2651                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2652                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2653                 
2654                 pBlockConvert2ISR(pb);
2655 #if 0  
2656                 if (!inExcludeList("acc"))              
2657                         pic14_emitcode ("push","acc");  
2658                 if (!inExcludeList("b"))
2659                         pic14_emitcode ("push","b");
2660                 if (!inExcludeList("dpl"))
2661                         pic14_emitcode ("push","dpl");
2662                 if (!inExcludeList("dph"))
2663                         pic14_emitcode ("push","dph");
2664                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2665                 {
2666                         pic14_emitcode ("push", "dpx");
2667                         /* Make sure we're using standard DPTR */
2668                         pic14_emitcode ("push", "dps");
2669                         pic14_emitcode ("mov", "dps, #0x00");
2670                         if (options.stack10bit)
2671                         { 
2672                                 /* This ISR could conceivably use DPTR2. Better save it. */
2673                                 pic14_emitcode ("push", "dpl1");
2674                                 pic14_emitcode ("push", "dph1");
2675                                 pic14_emitcode ("push", "dpx1");
2676                         }
2677                 }
2678                 /* if this isr has no bank i.e. is going to
2679                 run with bank 0 , then we need to save more
2680                 registers :-) */
2681                 if (!FUNC_REGBANK(sym->type)) {
2682                         
2683                 /* if this function does not call any other
2684                 function then we can be economical and
2685                         save only those registers that are used */
2686                         if (! IFFUNC_HASFCALL(sym->type)) {
2687                                 int i;
2688                                 
2689                                 /* if any registers used */
2690                                 if (sym->regsUsed) {
2691                                         /* save the registers used */
2692                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2693                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2694                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2695                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2696                                         }
2697                                 }
2698                                 
2699                         } else {
2700                         /* this function has    a function call cannot
2701                         determines register usage so we will have the
2702                                 entire bank */
2703                                 saverbank(0,ic,FALSE);
2704                         }       
2705                 }
2706 #endif
2707         } else {
2708         /* if callee-save to be used for this function
2709                 then save the registers being used in this function */
2710                 if (IFFUNC_CALLEESAVES(sym->type)) {
2711                         int i;
2712                         
2713                         /* if any registers used */
2714                         if (sym->regsUsed) {
2715                                 /* save the registers used */
2716                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2717                                         if (bitVectBitValue(sym->regsUsed,i) ||
2718                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2719                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2720                                                 _G.nRegsSaved++;
2721                                         }
2722                                 }
2723                         }
2724                 }
2725         }
2726         
2727         /* set the register bank to the desired value */
2728         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2729                 pic14_emitcode("push","psw");
2730                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2731         }
2732         
2733         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2734                 
2735                 if (options.useXstack) {
2736                         pic14_emitcode("mov","r0,%s",spname);
2737                         pic14_emitcode("mov","a,_bp");
2738                         pic14_emitcode("movx","@r0,a");
2739                         pic14_emitcode("inc","%s",spname);
2740                 }
2741                 else
2742                 {
2743                         /* set up the stack */
2744                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2745                 }
2746                 pic14_emitcode ("mov","_bp,%s",spname);
2747         }
2748         
2749         /* adjust the stack for the function */
2750         if (sym->stack) {
2751                 
2752                 int i = sym->stack;
2753                 if (i > 256 ) 
2754                         werror(W_STACK_OVERFLOW,sym->name);
2755                 
2756                 if (i > 3 && sym->recvSize < 4) {                
2757                         
2758                         pic14_emitcode ("mov","a,sp");
2759                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2760                         pic14_emitcode ("mov","sp,a");
2761                         
2762                 }
2763                 else
2764                         while(i--)
2765                                 pic14_emitcode("inc","sp");
2766         }
2767         
2768         if (sym->xstack) {
2769                 
2770                 pic14_emitcode ("mov","a,_spx");
2771                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2772                 pic14_emitcode ("mov","_spx,a");
2773         }
2774         
2775 }
2776
2777 /*-----------------------------------------------------------------*/
2778 /* genEndFunction - generates epilogue for functions                       */
2779 /*-----------------------------------------------------------------*/
2780 static void genEndFunction (iCode *ic)
2781 {
2782         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2783         
2784         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2785         
2786         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2787         {
2788                 pic14_emitcode ("mov","%s,_bp",spname);
2789         }
2790         
2791         /* if use external stack but some variables were
2792         added to the local stack then decrement the
2793         local stack */
2794         if (options.useXstack && sym->stack) {    
2795                 pic14_emitcode("mov","a,sp");
2796                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2797                 pic14_emitcode("mov","sp,a");
2798         }
2799         
2800         
2801         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2802                 if (options.useXstack) {
2803                         pic14_emitcode("mov","r0,%s",spname);
2804                         pic14_emitcode("movx","a,@r0");
2805                         pic14_emitcode("mov","_bp,a");
2806                         pic14_emitcode("dec","%s",spname);
2807                 }
2808                 else
2809                 {
2810                         pic14_emitcode ("pop","_bp");
2811                 }
2812         }
2813         
2814         /* restore the register bank    */        
2815         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2816                 pic14_emitcode ("pop","psw");
2817         
2818         if (IFFUNC_ISISR(sym->type)) {
2819                 
2820                 /* now we need to restore the registers */
2821                 /* if this isr has no bank i.e. is going to
2822                 run with bank 0 , then we need to save more
2823 registers :-) */
2824                 if (!FUNC_REGBANK(sym->type)) {
2825                         
2826                 /* if this function does not call any other
2827                 function then we can be economical and
2828                         save only those registers that are used */
2829                         if (! IFFUNC_HASFCALL(sym->type)) {
2830                                 int i;
2831                                 
2832                                 /* if any registers used */
2833                                 if (sym->regsUsed) {
2834                                         /* save the registers used */
2835                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2836                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2837                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2838                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2839                                         }
2840                                 }
2841                                 
2842                         } else {
2843                         /* this function has    a function call cannot
2844                         determines register usage so we will have the
2845                                 entire bank */
2846                                 unsaverbank(0,ic,FALSE);
2847                         }       
2848                 }
2849 #if 0
2850                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2851                 {
2852                         if (options.stack10bit)
2853                         {
2854                                 pic14_emitcode ("pop", "dpx1");
2855                                 pic14_emitcode ("pop", "dph1");
2856                                 pic14_emitcode ("pop", "dpl1");
2857                         } 
2858                         pic14_emitcode ("pop", "dps");
2859                         pic14_emitcode ("pop", "dpx");
2860                 }
2861                 if (!inExcludeList("dph"))
2862                         pic14_emitcode ("pop","dph");
2863                 if (!inExcludeList("dpl"))
2864                         pic14_emitcode ("pop","dpl");
2865                 if (!inExcludeList("b"))
2866                         pic14_emitcode ("pop","b");
2867                 if (!inExcludeList("acc"))
2868                         pic14_emitcode ("pop","acc");
2869                 
2870                 if (IFFUNC_ISCRITICAL(sym->type))
2871                         pic14_emitcode("setb","ea");
2872 #endif
2873                 
2874                 /* if debug then send end of function */
2875                 /*      if (options.debug && currFunc) { */
2876                 if (currFunc) {
2877                         debugFile->writeEndFunction (currFunc, ic, 1);
2878                 }
2879                 
2880                 pic14_emitcode ("reti","");
2881                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2882                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2883                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2884                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2885                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2886                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2887                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2888                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2889                 emitpcodeNULLop(POC_RETFIE);
2890         }
2891         else {
2892                 if (IFFUNC_ISCRITICAL(sym->type))
2893                         pic14_emitcode("setb","ea");
2894                 
2895                 if (IFFUNC_CALLEESAVES(sym->type)) {
2896                         int i;
2897                         
2898                         /* if any registers used */
2899                         if (sym->regsUsed) {
2900                                 /* save the registers used */
2901                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2902                                         if (bitVectBitValue(sym->regsUsed,i) ||
2903                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2904                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2905                                 }
2906                         }
2907                         
2908                 }
2909                 
2910                 /* if debug then send end of function */
2911                 if (currFunc) {
2912                         debugFile->writeEndFunction (currFunc, ic, 1);
2913                 }
2914                 
2915                 pic14_emitcode ("return","");
2916                 emitpcodeNULLop(POC_RETURN);
2917                 
2918                 /* Mark the end of a function */
2919                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2920         }
2921         
2922 }
2923
2924 /*-----------------------------------------------------------------*/
2925 /* genRet - generate code for return statement                                     */
2926 /*-----------------------------------------------------------------*/
2927 static void genRet (iCode *ic)
2928 {
2929         int size,offset = 0 , pushed = 0;
2930         
2931         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2932         /* if we have no return value then
2933         just generate the "ret" */
2934         if (!IC_LEFT(ic)) 
2935                 goto jumpret;           
2936         
2937                 /* we have something to return then
2938         move the return value into place */
2939         aopOp(IC_LEFT(ic),ic,FALSE);
2940         size = AOP_SIZE(IC_LEFT(ic));
2941         
2942         while (size--) {
2943                 char *l ;
2944                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2945                         /* #NOCHANGE */
2946                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
2947                                 FALSE,TRUE);
2948                         pic14_emitcode("push","%s",l);
2949                         pushed++;
2950                 } else {
2951                         l = aopGet(AOP(IC_LEFT(ic)),offset,
2952                                 FALSE,FALSE);
2953                         if (strcmp(fReturn[offset],l)) {
2954                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
2955                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2956                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2957                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2958                                         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2959                                 }else {
2960                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2961                                 }
2962                                 if(size) {
2963                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2964                                 }
2965                                 offset++;
2966                         }
2967                 }
2968         }
2969         
2970         if (pushed) {
2971                 while(pushed) {
2972                         pushed--;
2973                         if (strcmp(fReturn[pushed],"a"))
2974                                 pic14_emitcode("pop",fReturn[pushed]);
2975                         else
2976                                 pic14_emitcode("pop","acc");
2977                 }
2978         }
2979         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2980         
2981 jumpret:
2982         /* generate a jump to the return label
2983         if the next is not the return statement */
2984         if (!(ic->next && ic->next->op == LABEL &&
2985                 IC_LABEL(ic->next) == returnLabel)) {
2986                 
2987                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2988                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2989         }
2990         
2991 }
2992
2993 /*-----------------------------------------------------------------*/
2994 /* genLabel - generates a label                                                                    */
2995 /*-----------------------------------------------------------------*/
2996 static void genLabel (iCode *ic)
2997 {
2998         /* special case never generate */
2999         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3000         if (IC_LABEL(ic) == entryLabel)
3001                 return ;
3002         
3003         emitpLabel(IC_LABEL(ic)->key);
3004         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3005 }
3006
3007 /*-----------------------------------------------------------------*/
3008 /* genGoto - generates a goto                                                                      */
3009 /*-----------------------------------------------------------------*/
3010 //tsd
3011 static void genGoto (iCode *ic)
3012 {
3013         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3014         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3015 }
3016
3017
3018 /*-----------------------------------------------------------------*/
3019 /* genMultbits :- multiplication of bits                                                   */
3020 /*-----------------------------------------------------------------*/
3021 static void genMultbits (operand *left, 
3022                                                  operand *right, 
3023                                                  operand *result)
3024 {
3025         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3026         
3027         if(!pic14_sameRegs(AOP(result),AOP(right)))
3028                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3029         
3030         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3031         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3032         emitpcode(POC_BCF,  popGet(AOP(result),0));
3033         
3034 }
3035
3036
3037 /*-----------------------------------------------------------------*/
3038 /* genMultOneByte : 8 bit multiplication & division                        */
3039 /*-----------------------------------------------------------------*/
3040 static void genMultOneByte (operand *left,
3041                                                         operand *right,
3042                                                         operand *result)
3043 {
3044         sym_link *opetype = operandType(result);
3045         
3046         // symbol *lbl ;
3047         int size,offset;
3048         
3049         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3050         DEBUGpic14_AopType(__LINE__,left,right,result);
3051         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3052         
3053         /* (if two literals, the value is computed before) */
3054         /* if one literal, literal on the right */
3055         if (AOP_TYPE(left) == AOP_LIT){
3056                 operand *t = right;
3057                 right = left;
3058                 left = t;
3059         }
3060         
3061         size = AOP_SIZE(result);
3062         if(size == 1) {
3063                 
3064                 if (AOP_TYPE(right) == AOP_LIT){
3065                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3066                                 aopGet(AOP(right),0,FALSE,FALSE), 
3067                                 aopGet(AOP(left),0,FALSE,FALSE), 
3068                                 aopGet(AOP(result),0,FALSE,FALSE));
3069                         pic14_emitcode("call","genMultLit");
3070                 } else {
3071                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3072                                 aopGet(AOP(right),0,FALSE,FALSE), 
3073                                 aopGet(AOP(left),0,FALSE,FALSE), 
3074                                 aopGet(AOP(result),0,FALSE,FALSE));
3075                         pic14_emitcode("call","genMult8X8_8");
3076                         
3077                 }
3078                 genMult8X8_8 (left, right,result);
3079                 
3080                 
3081                 /* signed or unsigned */
3082                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3083                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3084                 //MOVA(l);               
3085                 //pic14_emitcode("mul","ab");
3086                 /* if result size = 1, mul signed = mul unsigned */
3087                 //aopPut(AOP(result),"a",0);
3088                 
3089         } else {        // (size > 1)
3090                 
3091                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3092                         aopGet(AOP(right),0,FALSE,FALSE), 
3093                         aopGet(AOP(left),0,FALSE,FALSE), 
3094                         aopGet(AOP(result),0,FALSE,FALSE));
3095                 
3096                 if (SPEC_USIGN(opetype)){
3097                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3098                         genUMult8X8_16 (left, right, result, NULL);
3099                         
3100                         if (size > 2) {
3101                                 /* for filling the MSBs */
3102                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3103                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3104                         }
3105                 }
3106                 else{
3107                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3108                         
3109                         pic14_emitcode("mov","a,b");
3110                         
3111                         /* adjust the MSB if left or right neg */
3112                         
3113                         /* if one literal */
3114                         if (AOP_TYPE(right) == AOP_LIT){
3115                                 pic14_emitcode("multiply ","right is a lit");
3116                                 /* AND literal negative */
3117                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3118                                         /* adjust MSB (c==0 after mul) */
3119                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3120                                 }
3121                         }
3122                         else{
3123                                 genSMult8X8_16 (left, right, result, NULL);
3124                         }
3125                         
3126                         if(size > 2){
3127                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3128                                 /* get the sign */
3129                                 pic14_emitcode("rlc","a");
3130                                 pic14_emitcode("subb","a,acc");
3131                         }
3132                 }
3133                 
3134                 size -= 2;
3135                 offset = 2;
3136                 if (size > 0)
3137                         while (size--)
3138                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3139                         //aopPut(AOP(result),"a",offset++);
3140         }
3141 }
3142
3143 /*-----------------------------------------------------------------*/
3144 /* genMult - generates code for multiplication                                     */
3145 /*-----------------------------------------------------------------*/
3146 static void genMult (iCode *ic)
3147 {
3148         operand *left = IC_LEFT(ic);
3149         operand *right = IC_RIGHT(ic);
3150         operand *result= IC_RESULT(ic); 
3151         
3152         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3153         /* assign the amsops */
3154         aopOp (left,ic,FALSE);
3155         aopOp (right,ic,FALSE);
3156         aopOp (result,ic,TRUE);
3157         
3158         DEBUGpic14_AopType(__LINE__,left,right,result);
3159         
3160         /* special cases first */
3161         /* both are bits */
3162         if (AOP_TYPE(left) == AOP_CRY &&
3163                 AOP_TYPE(right)== AOP_CRY) {
3164                 genMultbits(left,right,result);
3165                 goto release ;
3166         }
3167         
3168         /* if both are of size == 1 */
3169         if (AOP_SIZE(left) == 1 &&
3170                 AOP_SIZE(right) == 1 ) {
3171                 genMultOneByte(left,right,result);
3172                 goto release ;
3173         }
3174         
3175         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3176         
3177         /* should have been converted to function call */
3178         //assert(0) ;
3179         
3180 release :
3181         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3183         freeAsmop(result,NULL,ic,TRUE); 
3184 }
3185
3186 /*-----------------------------------------------------------------*/
3187 /* genDivbits :- division of bits                                                                  */
3188 /*-----------------------------------------------------------------*/
3189 static void genDivbits (operand *left, 
3190                                                 operand *right, 
3191                                                 operand *result)
3192 {
3193         
3194         char *l;
3195         
3196         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3197         /* the result must be bit */      
3198         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3199         l = aopGet(AOP(left),0,FALSE,FALSE);
3200         
3201         MOVA(l);          
3202         
3203         pic14_emitcode("div","ab");
3204         pic14_emitcode("rrc","a");
3205         aopPut(AOP(result),"c",0);
3206 }
3207
3208 /*-----------------------------------------------------------------*/
3209 /* genDivOneByte : 8 bit division                                                                  */
3210 /*-----------------------------------------------------------------*/
3211 static void genDivOneByte (operand *left,
3212                                                    operand *right,
3213                                                    operand *result)
3214 {
3215         sym_link *opetype = operandType(result);
3216         char *l ;
3217         symbol *lbl ;
3218         int size,offset;
3219         
3220         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3221         size = AOP_SIZE(result) - 1;
3222         offset = 1;
3223         /* signed or unsigned */
3224         if (SPEC_USIGN(opetype)) {
3225                 /* unsigned is easy */
3226                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3227                 l = aopGet(AOP(left),0,FALSE,FALSE);
3228                 MOVA(l);                
3229                 pic14_emitcode("div","ab");
3230                 aopPut(AOP(result),"a",0);
3231                 while (size--)
3232                         aopPut(AOP(result),zero,offset++);
3233                 return ;
3234         }
3235         
3236         /* signed is a little bit more difficult */
3237         
3238         /* save the signs of the operands */
3239         l = aopGet(AOP(left),0,FALSE,FALSE);      
3240         MOVA(l);          
3241         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3242         pic14_emitcode("push","acc"); /* save it on the stack */
3243         
3244         /* now sign adjust for both left & right */
3245         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3246         MOVA(l);                 
3247         lbl = newiTempLabel(NULL);
3248         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3249         pic14_emitcode("cpl","a");   
3250         pic14_emitcode("inc","a");
3251         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3252         pic14_emitcode("mov","b,a");
3253         
3254         /* sign adjust left side */
3255         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3256         MOVA(l);
3257         
3258         lbl = newiTempLabel(NULL);
3259         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3260         pic14_emitcode("cpl","a");
3261         pic14_emitcode("inc","a");
3262         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263         
3264         /* now the division */
3265         pic14_emitcode("div","ab");
3266         /* we are interested in the lower order
3267         only */
3268         pic14_emitcode("mov","b,a");
3269         lbl = newiTempLabel(NULL);
3270         pic14_emitcode("pop","acc");     
3271         /* if there was an over flow we don't 
3272         adjust the sign of the result */
3273         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3274         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3275         CLRC;
3276         pic14_emitcode("clr","a");
3277         pic14_emitcode("subb","a,b");
3278         pic14_emitcode("mov","b,a");
3279         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3280         
3281         /* now we are done */
3282         aopPut(AOP(result),"b",0);
3283         if(size > 0){
3284                 pic14_emitcode("mov","c,b.7");
3285                 pic14_emitcode("subb","a,acc");   
3286         }
3287         while (size--)
3288                 aopPut(AOP(result),"a",offset++);
3289         
3290 }
3291
3292 /*-----------------------------------------------------------------*/
3293 /* genDiv - generates code for division                                                    */
3294 /*-----------------------------------------------------------------*/
3295 static void genDiv (iCode *ic)
3296 {
3297         operand *left = IC_LEFT(ic);
3298         operand *right = IC_RIGHT(ic);
3299         operand *result= IC_RESULT(ic); 
3300         
3301         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3302         /* assign the amsops */
3303         aopOp (left,ic,FALSE);
3304         aopOp (right,ic,FALSE);
3305         aopOp (result,ic,TRUE);
3306         
3307         /* special cases first */
3308         /* both are bits */
3309         if (AOP_TYPE(left) == AOP_CRY &&
3310                 AOP_TYPE(right)== AOP_CRY) {
3311                 genDivbits(left,right,result);
3312                 goto release ;
3313         }
3314         
3315         /* if both are of size == 1 */
3316         if (AOP_SIZE(left) == 1 &&
3317                 AOP_SIZE(right) == 1 ) {
3318                 genDivOneByte(left,right,result);
3319                 goto release ;
3320         }
3321         
3322         /* should have been converted to function call */
3323         assert(0);
3324 release :
3325         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3326         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3327         freeAsmop(result,NULL,ic,TRUE); 
3328 }
3329
3330 /*-----------------------------------------------------------------*/
3331 /* genModbits :- modulus of bits                                                                   */
3332 /*-----------------------------------------------------------------*/
3333 static void genModbits (operand *left, 
3334                                                 operand *right, 
3335                                                 operand *result)
3336 {
3337         
3338         char *l;
3339         
3340         /* the result must be bit */      
3341         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3342         l = aopGet(AOP(left),0,FALSE,FALSE);
3343         
3344         MOVA(l);
3345         
3346         pic14_emitcode("div","ab");
3347         pic14_emitcode("mov","a,b");
3348         pic14_emitcode("rrc","a");
3349         aopPut(AOP(result),"c",0);
3350 }
3351
3352 /*-----------------------------------------------------------------*/
3353 /* genModOneByte : 8 bit modulus                                                                   */
3354 /*-----------------------------------------------------------------*/
3355 static void genModOneByte (operand *left,
3356                                                    operand *right,
3357                                                    operand *result)
3358 {
3359         sym_link *opetype = operandType(result);
3360         char *l ;
3361         symbol *lbl ;
3362         
3363         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3364         /* signed or unsigned */
3365         if (SPEC_USIGN(opetype)) {
3366                 /* unsigned is easy */
3367                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3368                 l = aopGet(AOP(left),0,FALSE,FALSE);
3369                 MOVA(l);        
3370                 pic14_emitcode("div","ab");
3371                 aopPut(AOP(result),"b",0);
3372                 return ;
3373         }
3374         
3375         /* signed is a little bit more difficult */
3376         
3377         /* save the signs of the operands */
3378         l = aopGet(AOP(left),0,FALSE,FALSE);      
3379         MOVA(l);
3380         
3381         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3382         pic14_emitcode("push","acc"); /* save it on the stack */
3383         
3384         /* now sign adjust for both left & right */
3385         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3386         MOVA(l);
3387         
3388         lbl = newiTempLabel(NULL);
3389         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3390         pic14_emitcode("cpl","a");   
3391         pic14_emitcode("inc","a");
3392         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3393         pic14_emitcode("mov","b,a"); 
3394         
3395         /* sign adjust left side */
3396         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3397         MOVA(l);
3398         
3399         lbl = newiTempLabel(NULL);
3400         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3401         pic14_emitcode("cpl","a");   
3402         pic14_emitcode("inc","a");
3403         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3404         
3405         /* now the multiplication */
3406         pic14_emitcode("div","ab");
3407         /* we are interested in the lower order
3408         only */
3409         lbl = newiTempLabel(NULL);
3410         pic14_emitcode("pop","acc");     
3411         /* if there was an over flow we don't 
3412         adjust the sign of the result */
3413         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3414         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415         CLRC ;
3416         pic14_emitcode("clr","a");
3417         pic14_emitcode("subb","a,b");
3418         pic14_emitcode("mov","b,a");
3419         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3420         
3421         /* now we are done */
3422         aopPut(AOP(result),"b",0);
3423         
3424 }
3425
3426 /*-----------------------------------------------------------------*/
3427 /* genMod - generates code for division                                                    */
3428 /*-----------------------------------------------------------------*/
3429 static void genMod (iCode *ic)
3430 {
3431         operand *left = IC_LEFT(ic);
3432         operand *right = IC_RIGHT(ic);
3433         operand *result= IC_RESULT(ic);  
3434         
3435         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3436         /* assign the amsops */
3437         aopOp (left,ic,FALSE);
3438         aopOp (right,ic,FALSE);
3439         aopOp (result,ic,TRUE);
3440         
3441         /* special cases first */
3442         /* both are bits */
3443         if (AOP_TYPE(left) == AOP_CRY &&
3444                 AOP_TYPE(right)== AOP_CRY) {
3445                 genModbits(left,right,result);
3446                 goto release ;
3447         }
3448         
3449         /* if both are of size == 1 */
3450         if (AOP_SIZE(left) == 1 &&
3451                 AOP_SIZE(right) == 1 ) {
3452                 genModOneByte(left,right,result);
3453                 goto release ;
3454         }
3455         
3456         /* should have been converted to function call */
3457         assert(0);
3458         
3459 release :
3460         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3461         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3462         freeAsmop(result,NULL,ic,TRUE); 
3463 }
3464
3465 /*-----------------------------------------------------------------*/
3466 /* genIfxJump :- will create a jump depending on the ifx                   */
3467 /*-----------------------------------------------------------------*/
3468 /*
3469 note: May need to add parameter to indicate when a variable is in bit space.
3470 */
3471 static void genIfxJump (iCode *ic, char *jval)
3472 {
3473         
3474         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3475         /* if true label then we jump if condition
3476         supplied is true */
3477         if ( IC_TRUE(ic) ) {
3478                 
3479                 if(strcmp(jval,"a") == 0)
3480                         emitSKPZ;
3481                 else if (strcmp(jval,"c") == 0)
3482                         emitSKPC;
3483                 else {
3484                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3485                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3486                 }
3487                 
3488                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3489                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3490                 
3491         }
3492         else {
3493                 /* false label is present */
3494                 if(strcmp(jval,"a") == 0)
3495                         emitSKPNZ;
3496                 else if (strcmp(jval,"c") == 0)
3497                         emitSKPNC;
3498                 else {
3499                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3500                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3501                 }
3502                 
3503                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3504                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3505                 
3506         }
3507         
3508         
3509         /* mark the icode as generated */
3510         ic->generated = 1;
3511 }
3512
3513 /*-----------------------------------------------------------------*/
3514 /* genSkip                                                                                                                 */
3515 /*-----------------------------------------------------------------*/
3516 static void genSkip(iCode *ifx,int status_bit)
3517 {
3518         if(!ifx)
3519                 return;
3520         
3521         if ( IC_TRUE(ifx) ) {
3522                 switch(status_bit) {
3523                 case 'z':
3524                         emitSKPNZ;
3525                         break;
3526                         
3527                 case 'c':
3528                         emitSKPNC;
3529                         break;
3530                         
3531                 case 'd':
3532                         emitSKPDC;
3533                         break;
3534                         
3535                 }
3536                 
3537                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3538                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3539                 
3540         } else {
3541                 
3542                 switch(status_bit) {
3543                         
3544                 case 'z':
3545                         emitSKPZ;
3546                         break;
3547                         
3548                 case 'c':
3549                         emitSKPC;
3550                         break;
3551                         
3552                 case 'd':
3553                         emitSKPDC;
3554                         break;
3555                 }
3556                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3557                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3558                 
3559         }
3560         
3561 }
3562
3563 /*-----------------------------------------------------------------*/
3564 /* genSkipc                                                                                                        */
3565 /*-----------------------------------------------------------------*/
3566 static void genSkipc(resolvedIfx *rifx)
3567 {
3568         if(!rifx)
3569                 return;
3570         
3571         if(rifx->condition)
3572                 emitSKPC;
3573         else
3574                 emitSKPNC;
3575         
3576         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3577         rifx->generated = 1;
3578 }
3579
3580 /*-----------------------------------------------------------------*/
3581 /* genSkipz2                                                                                                       */
3582 /*-----------------------------------------------------------------*/
3583 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3584 {
3585         if(!rifx)
3586                 return;
3587         
3588         if( (rifx->condition ^ invert_condition) & 1)
3589                 emitSKPZ;
3590         else
3591                 emitSKPNZ;
3592         
3593         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3594         rifx->generated = 1;
3595 }
3596
3597 /*-----------------------------------------------------------------*/
3598 /* genSkipz                                                        */
3599 /*-----------------------------------------------------------------*/
3600 static void genSkipz(iCode *ifx, int condition)
3601 {
3602         if(!ifx)
3603                 return;
3604         
3605         if(condition)
3606                 emitSKPNZ;
3607         else
3608                 emitSKPZ;
3609         
3610         if ( IC_TRUE(ifx) )
3611                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3612         else
3613                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3614         
3615         if ( IC_TRUE(ifx) )
3616                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3617         else
3618                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3619         
3620 }
3621 /*-----------------------------------------------------------------*/
3622 /* genSkipCond                                                     */
3623 /*-----------------------------------------------------------------*/
3624 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3625 {
3626         if(!rifx)
3627                 return;
3628         
3629         if(rifx->condition)
3630                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3631         else
3632                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3633         
3634         
3635         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3636         rifx->generated = 1;
3637 }
3638
3639 #if 0
3640 /*-----------------------------------------------------------------*/
3641 /* genChkZeroes :- greater or less than comparison                 */
3642 /*     For each byte in a literal that is zero, inclusive or the   */
3643 /*     the corresponding byte in the operand with W                */
3644 /*     returns true if any of the bytes are zero                   */
3645 /*-----------------------------------------------------------------*/
3646 static int genChkZeroes(operand *op, int lit,  int size)
3647 {
3648         
3649         int i;
3650         int flag =1;
3651         
3652         while(size--) {
3653                 i = (lit >> (size*8)) & 0xff;
3654                 
3655                 if(i==0) {
3656                         if(flag) 
3657                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3658                         else
3659                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3660                         flag = 0;
3661                 }
3662         }
3663         
3664         return (flag==0);
3665 }
3666 #endif
3667
3668 /*-----------------------------------------------------------------*/
3669 /* genCmp :- greater or less than comparison                       */
3670 /*-----------------------------------------------------------------*/
3671 static void genCmp (operand *left,operand *right,
3672                                         operand *result, iCode *ifx, int sign)
3673 {
3674         int size; //, offset = 0 ;
3675         unsigned long lit = 0L,i = 0;
3676         resolvedIfx rFalseIfx;
3677         //  resolvedIfx rTrueIfx;
3678         symbol *truelbl;
3679         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3680         /*
3681         if(ifx) {
3682         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3683         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3684         }
3685         */
3686         
3687         resolveIfx(&rFalseIfx,ifx);
3688         truelbl  = newiTempLabel(NULL);
3689         size = max(AOP_SIZE(left),AOP_SIZE(right));
3690         
3691         DEBUGpic14_AopType(__LINE__,left,right,result);
3692         
3693 #define _swapp
3694         
3695         /* if literal is on the right then swap with left */
3696         if ((AOP_TYPE(right) == AOP_LIT)) {
3697                 operand *tmp = right ;
3698                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3699                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3700 #ifdef _swapp
3701                 
3702                 lit = (lit - 1) & mask;
3703                 right = left;
3704                 left = tmp;
3705                 rFalseIfx.condition ^= 1;
3706 #endif
3707                 
3708         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3709                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3710         }
3711         
3712         
3713         //if(IC_TRUE(ifx) == NULL)
3714         /* if left & right are bit variables */
3715         if (AOP_TYPE(left) == AOP_CRY &&
3716                 AOP_TYPE(right) == AOP_CRY ) {
3717                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3718                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3719         } else {
3720         /* subtract right from left if at the
3721         end the carry flag is set then we know that
3722                 left is greater than right */
3723                 
3724                 symbol *lbl  = newiTempLabel(NULL);
3725                 
3726 #ifndef _swapp
3727                 if(AOP_TYPE(right) == AOP_LIT) {
3728                         
3729                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3730                         
3731                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3732                         
3733                         /* special cases */
3734                         
3735                         if(lit == 0) {
3736                                 
3737                                 if(sign != 0) 
3738                                         genSkipCond(&rFalseIfx,left,size-1,7);
3739                                 else 
3740                                         /* no need to compare to 0...*/
3741                                         /* NOTE: this is a de-generate compare that most certainly 
3742                                         *       creates some dead code. */
3743                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3744                                 
3745                                 if(ifx) ifx->generated = 1;
3746                                 return;
3747                                 
3748                         }
3749                         size--;
3750                         
3751                         if(size == 0) {
3752                                 //i = (lit >> (size*8)) & 0xff;
3753                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3754                                 
3755                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3756                                 
3757                                 i = ((0-lit) & 0xff);
3758                                 if(sign) {
3759                                         if( i == 0x81) { 
3760                                         /* lit is 0x7f, all signed chars are less than
3761                                                 * this except for 0x7f itself */
3762                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3763                                                 genSkipz2(&rFalseIfx,0);
3764                                         } else {
3765                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3766                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3767                                                 genSkipc(&rFalseIfx);
3768                                         }
3769                                         
3770                                 } else {
3771                                         if(lit == 1) {
3772                                                 genSkipz2(&rFalseIfx,1);
3773                                         } else {
3774                                                 emitpcode(POC_ADDLW, popGetLit(i));
3775                                                 genSkipc(&rFalseIfx);
3776                                         }
3777                                 }
3778                                 
3779                                 if(ifx) ifx->generated = 1;
3780                                 return;
3781                         }
3782                         
3783                         /* chars are out of the way. now do ints and longs */
3784                         
3785                         
3786                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3787                         
3788                         /* special cases */
3789                         
3790                         if(sign) {
3791                                 
3792                                 if(lit == 0) {
3793                                         genSkipCond(&rFalseIfx,left,size,7);
3794                                         if(ifx) ifx->generated = 1;
3795                                         return;
3796                                 }
3797                                 
3798                                 if(lit <0x100) {
3799                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3800                                         
3801                                         //rFalseIfx.condition ^= 1;
3802                                         //genSkipCond(&rFalseIfx,left,size,7);
3803                                         //rFalseIfx.condition ^= 1;
3804                                         
3805                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3806                                         if(rFalseIfx.condition)
3807                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3808                                         else
3809                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3810                                         
3811                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3812                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3813                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3814                                         
3815                                         while(size > 1)
3816                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3817                                         
3818                                         if(rFalseIfx.condition) {
3819                                                 emitSKPZ;
3820                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3821                                                 
3822                                         } else {
3823                                                 emitSKPNZ;
3824                                         }
3825                                         
3826                                         genSkipc(&rFalseIfx);
3827                                         emitpLabel(truelbl->key);
3828                                         if(ifx) ifx->generated = 1;
3829                                         return;
3830                                         
3831                                 }
3832                                 
3833                                 if(size == 1) {
3834                                         
3835                                         if( (lit & 0xff) == 0) {
3836                                                 /* lower byte is zero */
3837                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3838                                                 i = ((lit >> 8) & 0xff) ^0x80;
3839                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3840                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3841                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3842                                                 genSkipc(&rFalseIfx);
3843                                                 
3844                                                 
3845                                                 if(ifx) ifx->generated = 1;
3846                                                 return;
3847                                                 
3848                                         }
3849                                 } else {
3850                                         /* Special cases for signed longs */
3851                                         if( (lit & 0xffffff) == 0) {
3852                                                 /* lower byte is zero */
3853                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3854                                                 i = ((lit >> 8*3) & 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                                         
3866                                 }
3867                                 
3868                                 
3869                                 if(lit & (0x80 << (size*8))) {
3870                                         /* lit is negative */
3871                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3872                                         
3873                                         //genSkipCond(&rFalseIfx,left,size,7);
3874                                         
3875                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3876                                         
3877                                         if(rFalseIfx.condition)
3878                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3879                                         else
3880                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3881                                         
3882                                         
3883                                 } else {
3884                                         /* lit is positive */
3885                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3886                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3887                                         if(rFalseIfx.condition)
3888                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3889                                         else
3890                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3891                                         
3892                                 }
3893                                 
3894                                 /* There are no more special cases, so perform a general compare */
3895                                 
3896                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3897                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3898                                 
3899                                 while(size--) {
3900                                         
3901                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3902                                         emitSKPNZ;
3903                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3904                                 }
3905                                 //rFalseIfx.condition ^= 1;
3906                                 genSkipc(&rFalseIfx);
3907                                 
3908                                 emitpLabel(truelbl->key);
3909                                 
3910                                 if(ifx) ifx->generated = 1;
3911                                 return;
3912                                 
3913                                 
3914                         }
3915
3916
3917                         /* sign is out of the way. So now do an unsigned compare */
3918                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3919
3920
3921                         /* General case - compare to an unsigned literal on the right.*/
3922
3923                         i = (lit >> (size*8)) & 0xff;
3924                         emitpcode(POC_MOVLW, popGetLit(i));
3925                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3926                         while(size--) {
3927                                 i = (lit >> (size*8)) & 0xff;
3928                                 
3929                                 if(i) {
3930                                         emitpcode(POC_MOVLW, popGetLit(i));
3931                                         emitSKPNZ;
3932                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3933                                 } else {
3934                                 /* this byte of the lit is zero, 
3935                                         *if it's not the last then OR in the variable */
3936                                         if(size)
3937                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
3938                                 }
3939                         }
3940
3941
3942                 emitpLabel(lbl->key);
3943                 //if(emitFinalCheck)
3944                 genSkipc(&rFalseIfx);
3945                 if(sign)
3946                         emitpLabel(truelbl->key);
3947
3948                 if(ifx) ifx->generated = 1;
3949                 return;
3950
3951
3952                 }
3953 #endif  // _swapp
3954
3955                 if(AOP_TYPE(left) == AOP_LIT) {
3956                         //symbol *lbl = newiTempLabel(NULL);
3957                         
3958                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3959                         
3960                         
3961                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3962                         
3963                         /* Special cases */
3964                         if((lit == 0) && (sign == 0)){
3965                                 
3966                                 size--;
3967                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3968                                 while(size) 
3969                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
3970                                 
3971                                 genSkipz2(&rFalseIfx,0);
3972                                 if(ifx) ifx->generated = 1;
3973                                 return;
3974                         }
3975                         
3976                         if(size==1) {
3977                                 /* Special cases */
3978                                 lit &= 0xff;
3979                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3980                                         /* degenerate compare can never be true */
3981                                         if(rFalseIfx.condition == 0)
3982                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3983                                         
3984                                         if(ifx) ifx->generated = 1;
3985                                         return;
3986                                 }
3987                                 
3988                                 if(sign) {
3989                                         /* signed comparisons to a literal byte */
3990                                         
3991                                         int lp1 = (lit+1) & 0xff;
3992                                         
3993                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3994                                         switch (lp1) {
3995                                         case 0:
3996                                                 rFalseIfx.condition ^= 1;
3997                                                 genSkipCond(&rFalseIfx,right,0,7);
3998                                                 break;
3999                                         case 0x7f:
4000                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4001                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
4002                                                 genSkipz2(&rFalseIfx,1);
4003                                                 break;
4004                                         default:
4005                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4006                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4007                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4008                                                 rFalseIfx.condition ^= 1;
4009                                                 genSkipc(&rFalseIfx);
4010                                                 break;
4011                                         }
4012                                         if(ifx) ifx->generated = 1;
4013                                 } else {
4014                                         /* unsigned comparisons to a literal byte */
4015                                         
4016                                         switch(lit & 0xff ) {
4017                                         case 0:
4018                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4019                                                 genSkipz2(&rFalseIfx,0);
4020                                                 if(ifx) ifx->generated = 1;
4021                                                 break;
4022                                         case 0x7f:
4023                                                 genSkipCond(&rFalseIfx,right,0,7);
4024                                                 if(ifx) ifx->generated = 1;
4025                                                 break;
4026                                                 
4027                                         default:
4028                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4029                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4030                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4031                                                 rFalseIfx.condition ^= 1;
4032                                                 if (AOP_TYPE(result) == AOP_CRY) {
4033                                                         genSkipc(&rFalseIfx);
4034                                                         if(ifx) ifx->generated = 1;
4035                                                 } else {
4036                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4037                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4038                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4039                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4040                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4041                                                 }       
4042                                                 break;
4043                                         }
4044                                 }
4045                                 
4046                                 //goto check_carry;
4047                                 return;
4048                                 
4049                         } else {
4050                                 
4051                                 /* Size is greater than 1 */
4052                                 
4053                                 if(sign) {
4054                                         int lp1 = lit+1;
4055                                         
4056                                         size--;
4057                                         
4058                                         if(lp1 == 0) {
4059                                                 /* this means lit = 0xffffffff, or -1 */
4060                                                 
4061                                                 
4062                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4063                                                 rFalseIfx.condition ^= 1;
4064                                                 genSkipCond(&rFalseIfx,right,size,7);
4065                                                 if(ifx) ifx->generated = 1;
4066                                                 return;
4067                                         }
4068                                         
4069                                         if(lit == 0) {
4070                                                 int s = size;
4071                                                 
4072                                                 if(rFalseIfx.condition) {
4073                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4074                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4075                                                 }
4076                                                 
4077                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4078                                                 while(size--)
4079                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4080                                                 
4081                                                 
4082                                                 emitSKPZ;
4083                                                 if(rFalseIfx.condition) {
4084                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4085                                                         emitpLabel(truelbl->key);
4086                                                 }else {
4087                                                         rFalseIfx.condition ^= 1;
4088                                                         genSkipCond(&rFalseIfx,right,s,7);
4089                                                 }
4090                                                 
4091                                                 if(ifx) ifx->generated = 1;
4092                                                 return;
4093                                         }
4094                                         
4095                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4096                                                 /* lower byte of signed word is zero */
4097                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4098                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4099                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4100                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4101                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4102                                                 rFalseIfx.condition ^= 1;
4103                                                 genSkipc(&rFalseIfx);
4104                                                 
4105                                                 
4106                                                 if(ifx) ifx->generated = 1;
4107                                                 return;
4108                                         }
4109                                         
4110                                         if(lit & (0x80 << (size*8))) {
4111                                                 /* Lit is less than zero */
4112                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4113                                                 //rFalseIfx.condition ^= 1;
4114                                                 //genSkipCond(&rFalseIfx,left,size,7);
4115                                                 //rFalseIfx.condition ^= 1;
4116                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4117                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4118                                                 
4119                                                 if(rFalseIfx.condition)
4120                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4121                                                 else
4122                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4123                                                 
4124                                                 
4125                                         } else {
4126                                                 /* Lit is greater than or equal to zero */
4127                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4128                                                 //rFalseIfx.condition ^= 1;
4129                                                 //genSkipCond(&rFalseIfx,right,size,7);
4130                                                 //rFalseIfx.condition ^= 1;
4131                                                 
4132                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4134                                                 
4135                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4136                                                 if(rFalseIfx.condition)
4137                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4138                                                 else
4139                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4140                                                 
4141                                         }
4142                                         
4143                                         
4144                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4145                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4146                                         
4147                                         while(size--) {
4148                                                 
4149                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4150                                                 emitSKPNZ;
4151                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4152                                         }
4153                                         rFalseIfx.condition ^= 1;
4154                                         //rFalseIfx.condition = 1;
4155                                         genSkipc(&rFalseIfx);
4156                                         
4157                                         emitpLabel(truelbl->key);
4158                                         
4159                                         if(ifx) ifx->generated = 1;
4160                                         return;
4161                                         // end of if (sign)
4162                                 } else {
4163                                         
4164                                         /* compare word or long to an unsigned literal on the right.*/
4165                                         
4166                                         
4167                                         size--;
4168                                         if(lit < 0xff) {
4169                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4170                                                 switch (lit) {
4171                                                 case 0:
4172                                                         break; /* handled above */
4173                                                 /*
4174                                                 case 0xff:
4175                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4176                                                         while(size--)
4177                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4178                                                         genSkipz2(&rFalseIfx,0);
4179                                                         break;
4180                                                 */
4181                                                 default:
4182                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4183                                                         while(--size)
4184                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4185                                                         
4186                                                         emitSKPZ;
4187                                                         if(rFalseIfx.condition)
4188                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4189                                                         else
4190                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4191                                                         
4192                                                         
4193                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4194                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4195                                                         
4196                                                         rFalseIfx.condition ^= 1;
4197                                                         genSkipc(&rFalseIfx);
4198                                                 }
4199                                                 
4200                                                 emitpLabel(truelbl->key);
4201                                                 
4202                                                 if(ifx) ifx->generated = 1;
4203                                                 return;
4204                                         }
4205                                         
4206                                         
4207                                         lit++;
4208                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4209                                         i = (lit >> (size*8)) & 0xff;
4210                                         
4211                                         emitpcode(POC_MOVLW, popGetLit(i));
4212                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4213                                         
4214                                         while(size--) {
4215                                                 i = (lit >> (size*8)) & 0xff;
4216                                                 
4217                                                 if(i) {
4218                                                         emitpcode(POC_MOVLW, popGetLit(i));
4219                                                         emitSKPNZ;
4220                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4221                                                 } else {
4222                                                 /* this byte of the lit is zero, 
4223                                                         *if it's not the last then OR in the variable */
4224                                                         if(size)
4225                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4226                                                 }
4227                                         }
4228                                         
4229                                         
4230                                         emitpLabel(lbl->key);
4231                                         
4232                                         rFalseIfx.condition ^= 1;
4233                                         genSkipc(&rFalseIfx);
4234                                 }
4235                                 
4236                                 if(sign)
4237                                         emitpLabel(truelbl->key);
4238                                 if(ifx) ifx->generated = 1;
4239                                 return;
4240                         }
4241                 }
4242                 /* Compare two variables */
4243                 
4244                 DEBUGpic14_emitcode(";sign","%d",sign);
4245                 
4246                 size--;
4247                 if(sign) {
4248                         /* Sigh. thus sucks... */
4249                         if(size) {
4250                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4251                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4252                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4253                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4254                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4255                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4256                         } else {
4257                                 /* Signed char comparison */
4258                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4259                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4260                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4261                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4262                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4263                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4264                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4265                                 
4266                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4267                                 genSkipc(&rFalseIfx);
4268                                 
4269                                 if(ifx) ifx->generated = 1;
4270                                 return;
4271                         }
4272                         
4273                 } else {
4274                         
4275                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4276                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4277                 }
4278                 
4279                 
4280                 /* The rest of the bytes of a multi-byte compare */
4281                 while (size) {
4282                         
4283                         emitSKPZ;
4284                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4285                         size--;
4286                         
4287                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4288                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4289                         
4290                         
4291                 }
4292                 
4293                 emitpLabel(lbl->key);
4294                 
4295                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4296                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4297                         (AOP_TYPE(result) == AOP_REG)) {
4298                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4299                         emitpcode(POC_RLF, popGet(AOP(result),0));
4300                 } else {
4301                         genSkipc(&rFalseIfx);
4302                 }       
4303                 //genSkipc(&rFalseIfx);
4304                 if(ifx) ifx->generated = 1;
4305                 
4306                 return;
4307                 
4308         }
4309         
4310         // check_carry:
4311         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4312                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4313                 pic14_outBitC(result);
4314         } else {
4315                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4316                 /* if the result is used in the next
4317                 ifx conditional branch then generate
4318                 code a little differently */
4319                 if (ifx )
4320                         genIfxJump (ifx,"c");
4321                 else
4322                         pic14_outBitC(result);
4323                 /* leave the result in acc */
4324         }
4325         
4326 }
4327
4328 /*-----------------------------------------------------------------*/
4329 /* genCmpGt :- greater than comparison                             */
4330 /*-----------------------------------------------------------------*/
4331 static void genCmpGt (iCode *ic, iCode *ifx)
4332 {
4333         operand *left, *right, *result;
4334         sym_link *letype , *retype;
4335         int sign ;
4336         
4337         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4338         left = IC_LEFT(ic);
4339         right= IC_RIGHT(ic);
4340         result = IC_RESULT(ic);
4341         
4342         letype = getSpec(operandType(left));
4343         retype =getSpec(operandType(right));
4344         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4345         /* assign the amsops */
4346         aopOp (left,ic,FALSE);
4347         aopOp (right,ic,FALSE);
4348         aopOp (result,ic,TRUE);
4349         
4350         genCmp(right, left, result, ifx, sign);
4351         
4352         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4353         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4354         freeAsmop(result,NULL,ic,TRUE); 
4355 }
4356
4357 /*-----------------------------------------------------------------*/
4358 /* genCmpLt - less than comparisons                                */
4359 /*-----------------------------------------------------------------*/
4360 static void genCmpLt (iCode *ic, iCode *ifx)
4361 {
4362         operand *left, *right, *result;
4363         sym_link *letype , *retype;
4364         int sign ;
4365         
4366         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4367         left = IC_LEFT(ic);
4368         right= IC_RIGHT(ic);
4369         result = IC_RESULT(ic);
4370         
4371         letype = getSpec(operandType(left));
4372         retype =getSpec(operandType(right));
4373         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4374         
4375         /* assign the amsops */
4376         aopOp (left,ic,FALSE);
4377         aopOp (right,ic,FALSE);
4378         aopOp (result,ic,TRUE);
4379         
4380         genCmp(left, right, result, ifx, sign);
4381         
4382         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4383         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4384         freeAsmop(result,NULL,ic,TRUE); 
4385 }
4386
4387 /*-----------------------------------------------------------------*/
4388 /* genc16bit2lit - compare a 16 bit value to a literal             */
4389 /*-----------------------------------------------------------------*/
4390 static void genc16bit2lit(operand *op, int lit, int offset)
4391 {
4392         int i;
4393         
4394         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4395         if( (lit&0xff) == 0) 
4396                 i=1;
4397         else
4398                 i=0;
4399         
4400         switch( BYTEofLONG(lit,i)) { 
4401         case 0:
4402                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4403                 break;
4404         case 1:
4405                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4406                 break;
4407         case 0xff:
4408                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4409                 break;
4410         default:
4411                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4412                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4413         }
4414         
4415         i ^= 1;
4416         
4417         switch( BYTEofLONG(lit,i)) { 
4418         case 0:
4419                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4420                 break;
4421         case 1:
4422                 emitSKPNZ;
4423                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4424                 break;
4425         case 0xff:
4426                 emitSKPNZ;
4427                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4428                 break;
4429         default:
4430                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4431                 emitSKPNZ;
4432                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4433                 
4434         }
4435         
4436 }
4437
4438 /*-----------------------------------------------------------------*/
4439 /* gencjneshort - compare and jump if not equal                    */
4440 /*-----------------------------------------------------------------*/
4441 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4442 {
4443         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4444         int offset = 0;
4445         int res_offset = 0;  /* the result may be a different size then left or right */
4446         int res_size = AOP_SIZE(result);
4447         resolvedIfx rIfx;
4448         symbol *lbl;
4449         
4450         unsigned long lit = 0L;
4451         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4452         DEBUGpic14_AopType(__LINE__,left,right,result);
4453         if(result)
4454                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4455         resolveIfx(&rIfx,ifx);
4456         lbl =  newiTempLabel(NULL);
4457         
4458         
4459         /* if the left side is a literal or 
4460         if the right is in a pointer register and left 
4461         is not */
4462         if ((AOP_TYPE(left) == AOP_LIT) || 
4463                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4464                 operand *t = right;
4465                 right = left;
4466                 left = t;
4467         }
4468         if(AOP_TYPE(right) == AOP_LIT)
4469                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4470         
4471         /* if the right side is a literal then anything goes */
4472         if (AOP_TYPE(right) == AOP_LIT &&
4473                 AOP_TYPE(left) != AOP_DIR ) {
4474                 switch(size) {
4475                 case 2:
4476                         genc16bit2lit(left, lit, 0);
4477                         emitSKPNZ;
4478                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4479                         break;
4480                 default:
4481                         while (size--) {
4482                                 if(lit & 0xff) {
4483                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4484                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4485                                 } else {
4486                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4487                                 }
4488                                 
4489                                 emitSKPNZ;
4490                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4491                                 offset++;
4492                                 if(res_offset < res_size-1)
4493                                         res_offset++;
4494                                 lit >>= 8;
4495                         }
4496                         break;
4497                 }
4498         }
4499         
4500         /* if the right side is in a register or in direct space or
4501         if the left is a pointer register & right is not */    
4502         else if (AOP_TYPE(right) == AOP_REG ||
4503                 AOP_TYPE(right) == AOP_DIR || 
4504                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4505                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4506                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4507                 int lbl_key = lbl->key;
4508                 
4509                 if(result) {
4510                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4511                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4512                 }else {
4513                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4514                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4515                                 __FUNCTION__,__LINE__);
4516                         return;
4517                 }
4518                 
4519                 /*     switch(size) { */
4520                 /*     case 2: */
4521                 /*       genc16bit2lit(left, lit, 0); */
4522                 /*       emitSKPNZ; */
4523                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4524                 /*       break; */
4525                 /*     default: */
4526                 while (size--) {
4527                         int emit_skip=1;
4528                         if((AOP_TYPE(left) == AOP_DIR) && 
4529                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4530                                 
4531                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4532                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4533                                 
4534                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4535                                 
4536                                 switch (lit & 0xff) {
4537                                 case 0:
4538                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4539                                         break;
4540                                 case 1:
4541                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4542                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4543                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4544                                         emit_skip=0;
4545                                         break;
4546                                 case 0xff:
4547                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4548                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4549                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4550                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4551                                         emit_skip=0;
4552                                         break;
4553                                 default:
4554                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4555                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4556                                 }
4557                                 lit >>= 8;
4558                                 
4559                         } else {
4560                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4561                         }
4562                         if(emit_skip) {
4563                                 if(AOP_TYPE(result) == AOP_CRY) {
4564                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4565                                         if(rIfx.condition)
4566                                                 emitSKPNZ;
4567                                         else
4568                                                 emitSKPZ;
4569                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4570                                 } else {
4571                                         /* fix me. probably need to check result size too */
4572                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4573                                         if(rIfx.condition)
4574                                                 emitSKPZ;
4575                                         else
4576                                                 emitSKPNZ;
4577                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4578                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4579                                 }
4580                                 if(ifx)
4581                                         ifx->generated=1;
4582                         }
4583                         emit_skip++;
4584                         offset++;
4585                         if(res_offset < res_size-1)
4586                                 res_offset++;
4587                 }
4588                 /*       break; */
4589                 /*     } */
4590         } else if(AOP_TYPE(right) == AOP_REG &&
4591                 AOP_TYPE(left) != AOP_DIR){
4592                 
4593                 while(size--) {
4594                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4595                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4596                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4597                         if(rIfx.condition)
4598                                 emitSKPNZ;
4599                         else
4600                                 emitSKPZ;
4601                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4602                         offset++;
4603                         if(res_offset < res_size-1)
4604                                 res_offset++;
4605                 }
4606                 
4607         }else{
4608                 /* right is a pointer reg need both a & b */
4609                 while(size--) {
4610                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4611                         if(strcmp(l,"b"))
4612                                 pic14_emitcode("mov","b,%s",l);
4613                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4614                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4615                         offset++;
4616                 }
4617         }
4618         
4619         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4620         if(!rIfx.condition)
4621                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4622         
4623         emitpLabel(lbl->key);
4624         
4625         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4626         
4627         if(ifx)
4628                 ifx->generated = 1;
4629 }
4630
4631 #if 0
4632 /*-----------------------------------------------------------------*/
4633 /* gencjne - compare and jump if not equal                         */
4634 /*-----------------------------------------------------------------*/
4635 static void gencjne(operand *left, operand *right, iCode *ifx)
4636 {
4637         symbol *tlbl  = newiTempLabel(NULL);
4638         
4639         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4640         gencjneshort(left, right, lbl);
4641         
4642         pic14_emitcode("mov","a,%s",one);
4643         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4644         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4645         pic14_emitcode("clr","a");
4646         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4647         
4648         emitpLabel(lbl->key);
4649         emitpLabel(tlbl->key);
4650         
4651 }
4652 #endif
4653
4654 /*-----------------------------------------------------------------*/
4655 /* genCmpEq - generates code for equal to                          */
4656 /*-----------------------------------------------------------------*/
4657 static void genCmpEq (iCode *ic, iCode *ifx)
4658 {
4659         operand *left, *right, *result;
4660         unsigned long lit = 0L;
4661         int size,offset=0;
4662         
4663         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4664         
4665         if(ifx)
4666                 DEBUGpic14_emitcode ("; ifx is non-null","");
4667         else
4668                 DEBUGpic14_emitcode ("; ifx is null","");
4669         
4670         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4671         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4672         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4673         
4674         size = max(AOP_SIZE(left),AOP_SIZE(right));
4675         
4676         DEBUGpic14_AopType(__LINE__,left,right,result);
4677         
4678         /* if literal, literal on the right or 
4679         if the right is in a pointer register and left 
4680         is not */
4681         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4682                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4683                 operand *tmp = right ;
4684                 right = left;
4685                 left = tmp;
4686         }
4687         
4688         
4689         if(ifx && !AOP_SIZE(result)){
4690                 symbol *tlbl;
4691                 /* if they are both bit variables */
4692                 if (AOP_TYPE(left) == AOP_CRY &&
4693                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4694                         if(AOP_TYPE(right) == AOP_LIT){
4695                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4696                                 if(lit == 0L){
4697                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4698                                         pic14_emitcode("cpl","c");
4699                                 } else if(lit == 1L) {
4700                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4701                                 } else {
4702                                         pic14_emitcode("clr","c");
4703                                 }
4704                                 /* AOP_TYPE(right) == AOP_CRY */
4705                         } else {
4706                                 symbol *lbl = newiTempLabel(NULL);
4707                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4708                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4709                                 pic14_emitcode("cpl","c");
4710                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4711                         }
4712                         /* if true label then we jump if condition
4713                         supplied is true */
4714                         tlbl = newiTempLabel(NULL);
4715                         if ( IC_TRUE(ifx) ) {
4716                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4717                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4718                         } else {
4719                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4720                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4721                         }
4722                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4723                         
4724                         {
4725                                 /* left and right are both bit variables, result is carry */
4726                                 resolvedIfx rIfx;
4727                                 
4728                                 resolveIfx(&rIfx,ifx);
4729                                 
4730                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4731                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4732                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4733                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4734                                 genSkipz2(&rIfx,0);
4735                         }
4736                 } else {
4737                         
4738                         /* They're not both bit variables. Is the right a literal? */
4739                         if(AOP_TYPE(right) == AOP_LIT) {
4740                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4741                                 
4742                                 switch(size) {
4743                                         
4744                                 case 1:
4745                                         switch(lit & 0xff) {
4746                                         case 1:
4747                                                 if ( IC_TRUE(ifx) ) {
4748                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4749                                                         emitSKPNZ;
4750                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4751                                                 } else {
4752                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4753                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4754                                                 }
4755                                                 break;
4756                                         case 0xff:
4757                                                 if ( IC_TRUE(ifx) ) {
4758                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4759                                                         emitSKPNZ;
4760                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4761                                                 } else {
4762                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4763                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4764                                                 }
4765                                                 break;
4766                                         default:
4767                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4768                                                 if(lit)
4769                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4770                                                 genSkip(ifx,'z');
4771                                         }
4772                                         
4773                                         
4774                                         /* end of size == 1 */
4775                                         break;
4776                                         
4777                                         case 2:
4778                                                 genc16bit2lit(left,lit,offset);
4779                                                 genSkip(ifx,'z');
4780                                                 break;
4781                                                 /* end of size == 2 */
4782                                                 
4783                                         default:
4784                                                 /* size is 4 */
4785                                                 if(lit==0) {
4786                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4787                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4788                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4789                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4790                                                         
4791                                                 } else {
4792                                                         
4793                                                         /* search for patterns that can be optimized */
4794                                                         
4795                                                         genc16bit2lit(left,lit,0);
4796                                                         lit >>= 16;
4797                                                         if(lit) {
4798                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4799                                                                 //genSkip(ifx,'z');
4800                                                                 genc16bit2lit(left,lit,2);
4801                                                         } else {
4802                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4803                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4804                                                                 
4805                                                         }
4806                                                         
4807                                                 }
4808                                                 
4809                                                 genSkip(ifx,'z');
4810                                 }
4811                                 
4812                                 ifx->generated = 1;
4813                                 goto release ;
4814                                 
4815                                 
4816                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4817                                 /* we know the left is not a bit, but that the right is */
4818                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4819                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4820                                         popGet(AOP(right),offset));
4821                                 emitpcode(POC_XORLW,popGetLit(1));
4822                                 
4823                                 /* if the two are equal, then W will be 0 and the Z bit is set
4824                                 * we could test Z now, or go ahead and check the high order bytes if
4825                                 * the variable we're comparing is larger than a byte. */
4826                                 
4827                                 while(--size)
4828                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4829                                 
4830                                 if ( IC_TRUE(ifx) ) {
4831                                         emitSKPNZ;
4832                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4833                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4834                                 } else {
4835                                         emitSKPZ;
4836                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4837                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4838                                 }
4839                                 
4840                         } else {
4841                                 /* They're both variables that are larger than bits */
4842                                 int s = size;
4843                                 
4844                                 tlbl = newiTempLabel(NULL);
4845                                 
4846                                 while(size--) {
4847                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4848                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4849                                         
4850                                         if ( IC_TRUE(ifx) ) {
4851                                                 if(size) {
4852                                                         emitSKPZ;
4853                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4854                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4855                                                 } else {
4856                                                         emitSKPNZ;
4857                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4858                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4859                                                 }
4860                                         } else {
4861                                                 emitSKPZ;
4862                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4863                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4864                                         }
4865                                         offset++;
4866                                 }
4867                                 if(s>1 && IC_TRUE(ifx)) {
4868                                         emitpLabel(tlbl->key);
4869                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4870                                 }
4871                         }
4872                 }
4873                 /* mark the icode as generated */
4874                 ifx->generated = 1;
4875                 goto release ;
4876         }
4877   
4878   /* if they are both bit variables */
4879   if (AOP_TYPE(left) == AOP_CRY &&
4880           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4881           if(AOP_TYPE(right) == AOP_LIT){
4882                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4883                   if(lit == 0L){
4884                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4885                           pic14_emitcode("cpl","c");
4886                   } else if(lit == 1L) {
4887                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4888                   } else {
4889                           pic14_emitcode("clr","c");
4890                   }
4891                   /* AOP_TYPE(right) == AOP_CRY */
4892           } else {
4893                   symbol *lbl = newiTempLabel(NULL);
4894                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4895                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4896                   pic14_emitcode("cpl","c");
4897                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4898           }
4899           /* c = 1 if egal */
4900           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4901                   pic14_outBitC(result);
4902                   goto release ;
4903           }
4904           if (ifx) {
4905                   genIfxJump (ifx,"c");
4906                   goto release ;
4907           }
4908           /* if the result is used in an arithmetic operation
4909           then put the result in place */
4910           pic14_outBitC(result);
4911   } else {
4912           
4913           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4914           gencjne(left,right,result,ifx);
4915           /*
4916           if(ifx) 
4917           gencjne(left,right,newiTempLabel(NULL));
4918           else {
4919           if(IC_TRUE(ifx)->key)
4920           gencjne(left,right,IC_TRUE(ifx)->key);
4921           else
4922           gencjne(left,right,IC_FALSE(ifx)->key);
4923           ifx->generated = 1;
4924           goto release ;
4925           }
4926           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4927           aopPut(AOP(result),"a",0);
4928           goto release ;
4929           }
4930           
4931                 if (ifx) {
4932                 genIfxJump (ifx,"a");
4933                 goto release ;
4934                 }
4935           */
4936           /* if the result is used in an arithmetic operation
4937           then put the result in place */
4938           /*
4939           if (AOP_TYPE(result) != AOP_CRY) 
4940           pic14_outAcc(result);
4941           */
4942           /* leave the result in acc */
4943   }
4944   
4945 release:
4946   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4947   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4948   freeAsmop(result,NULL,ic,TRUE);
4949 }
4950
4951 /*-----------------------------------------------------------------*/
4952 /* ifxForOp - returns the icode containing the ifx for operand     */
4953 /*-----------------------------------------------------------------*/
4954 static iCode *ifxForOp ( operand *op, iCode *ic )
4955 {
4956         /* if true symbol then needs to be assigned */
4957         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4958         if (IS_TRUE_SYMOP(op))
4959                 return NULL ;
4960         
4961         /* if this has register type condition and
4962         the next instruction is ifx with the same operand
4963         and live to of the operand is upto the ifx only then */
4964         if (ic->next &&
4965                 ic->next->op == IFX &&
4966                 IC_COND(ic->next)->key == op->key &&
4967                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4968                 return ic->next;
4969         
4970         if (ic->next &&
4971                 ic->next->op == IFX &&
4972                 IC_COND(ic->next)->key == op->key) {
4973                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4974                 return ic->next;
4975         }
4976         
4977         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4978         if (ic->next &&
4979                 ic->next->op == IFX)
4980                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4981         
4982         if (ic->next &&
4983                 ic->next->op == IFX &&
4984                 IC_COND(ic->next)->key == op->key) {
4985                 DEBUGpic14_emitcode ("; "," key is okay");
4986                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4987                         OP_SYMBOL(op)->liveTo,
4988                         ic->next->seq);
4989         }
4990         
4991         
4992         return NULL;
4993 }
4994 /*-----------------------------------------------------------------*/
4995 /* genAndOp - for && operation                                     */
4996 /*-----------------------------------------------------------------*/
4997 static void genAndOp (iCode *ic)
4998 {
4999         operand *left,*right, *result;
5000         /*     symbol *tlbl; */
5001         
5002         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5003         /* note here that && operations that are in an
5004         if statement are taken away by backPatchLabels
5005         only those used in arthmetic operations remain */
5006         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5007         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5008         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5009         
5010         DEBUGpic14_AopType(__LINE__,left,right,result);
5011         
5012         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5013         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5014         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5015         
5016         /* if both are bit variables */
5017         /*     if (AOP_TYPE(left) == AOP_CRY && */
5018         /*         AOP_TYPE(right) == AOP_CRY ) { */
5019         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5020         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5021         /*         pic14_outBitC(result); */
5022         /*     } else { */
5023         /*         tlbl = newiTempLabel(NULL); */
5024         /*         pic14_toBoolean(left);     */
5025         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5026         /*         pic14_toBoolean(right); */
5027         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5028         /*         pic14_outBitAcc(result); */
5029         /*     } */
5030         
5031         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5033         freeAsmop(result,NULL,ic,TRUE);
5034 }
5035
5036
5037 /*-----------------------------------------------------------------*/
5038 /* genOrOp - for || operation                                      */
5039 /*-----------------------------------------------------------------*/
5040 /*
5041 tsd pic port -
5042 modified this code, but it doesn't appear to ever get called
5043 */
5044
5045 static void genOrOp (iCode *ic)
5046 {
5047         operand *left,*right, *result;
5048         symbol *tlbl;
5049         
5050         /* note here that || operations that are in an
5051         if statement are taken away by backPatchLabels
5052         only those used in arthmetic operations remain */
5053         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5054         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5055         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5056         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5057         
5058         DEBUGpic14_AopType(__LINE__,left,right,result);
5059         
5060         /* if both are bit variables */
5061         if (AOP_TYPE(left) == AOP_CRY &&
5062                 AOP_TYPE(right) == AOP_CRY ) {
5063                 pic14_emitcode("clrc","");
5064                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5065                         AOP(left)->aopu.aop_dir,
5066                         AOP(left)->aopu.aop_dir);
5067                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5068                         AOP(right)->aopu.aop_dir,
5069                         AOP(right)->aopu.aop_dir);
5070                 pic14_emitcode("setc","");
5071                 
5072         } else {
5073                 tlbl = newiTempLabel(NULL);
5074                 pic14_toBoolean(left);
5075                 emitSKPZ;
5076                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5077                 pic14_toBoolean(right);
5078                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5079                 
5080                 pic14_outBitAcc(result);
5081         }
5082         
5083         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5085         freeAsmop(result,NULL,ic,TRUE);            
5086 }
5087
5088 /*-----------------------------------------------------------------*/
5089 /* isLiteralBit - test if lit == 2^n                               */
5090 /*-----------------------------------------------------------------*/
5091 static int isLiteralBit(unsigned long lit)
5092 {
5093         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5094                 0x100L,0x200L,0x400L,0x800L,
5095                 0x1000L,0x2000L,0x4000L,0x8000L,
5096                 0x10000L,0x20000L,0x40000L,0x80000L,
5097                 0x100000L,0x200000L,0x400000L,0x800000L,
5098                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5099                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5100         int idx;
5101         
5102         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5103         for(idx = 0; idx < 32; idx++)
5104                 if(lit == pw[idx])
5105                         return idx+1;
5106                 return 0;
5107 }
5108
5109 /*-----------------------------------------------------------------*/
5110 /* continueIfTrue -                                                */
5111 /*-----------------------------------------------------------------*/
5112 static void continueIfTrue (iCode *ic)
5113 {
5114         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5115         if(IC_TRUE(ic))
5116                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5117         ic->generated = 1;
5118 }
5119
5120 /*-----------------------------------------------------------------*/
5121 /* jmpIfTrue -                                                     */
5122 /*-----------------------------------------------------------------*/
5123 static void jumpIfTrue (iCode *ic)
5124 {
5125         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5126         if(!IC_TRUE(ic))
5127                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5128         ic->generated = 1;
5129 }
5130
5131 /*-----------------------------------------------------------------*/
5132 /* jmpTrueOrFalse -                                                */
5133 /*-----------------------------------------------------------------*/
5134 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5135 {
5136         // ugly but optimized by peephole
5137         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5138         if(IC_TRUE(ic)){
5139                 symbol *nlbl = newiTempLabel(NULL);
5140                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5141                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5142                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5143                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5144         }
5145         else{
5146                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5147                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5148         }
5149         ic->generated = 1;
5150 }
5151
5152 /*-----------------------------------------------------------------*/
5153 /* genAnd  - code for and                                          */
5154 /*-----------------------------------------------------------------*/
5155 static void genAnd (iCode *ic, iCode *ifx)
5156 {
5157         operand *left, *right, *result;
5158         int size, offset=0;  
5159         unsigned long lit = 0L;
5160         int bytelit = 0;
5161         resolvedIfx rIfx;
5162         
5163         
5164         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5165         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5166         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5167         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5168         
5169         resolveIfx(&rIfx,ifx);
5170         
5171         /* if left is a literal & right is not then exchange them */
5172         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5173                 AOP_NEEDSACC(left)) {
5174                 operand *tmp = right ;
5175                 right = left;
5176                 left = tmp;
5177         }
5178         
5179         /* if result = right then exchange them */
5180         if(pic14_sameRegs(AOP(result),AOP(right))){
5181                 operand *tmp = right ;
5182                 right = left;
5183                 left = tmp;
5184         }
5185         
5186         /* if right is bit then exchange them */
5187         if (AOP_TYPE(right) == AOP_CRY &&
5188                 AOP_TYPE(left) != AOP_CRY){
5189                 operand *tmp = right ;
5190                 right = left;
5191                 left = tmp;
5192         }
5193         if(AOP_TYPE(right) == AOP_LIT)
5194                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5195         
5196         size = AOP_SIZE(result);
5197         
5198         DEBUGpic14_AopType(__LINE__,left,right,result);
5199         
5200         // if(bit & yy)
5201         // result = bit & yy;
5202         if (AOP_TYPE(left) == AOP_CRY){
5203                 // c = bit & literal;
5204                 if(AOP_TYPE(right) == AOP_LIT){
5205                         if(lit & 1) {
5206                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5207                                         // no change
5208                                         goto release;
5209                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5210                         } else {
5211                                 // bit(result) = 0;
5212                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5213                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5214                                         goto release;
5215                                 }
5216                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5217                                         jumpIfTrue(ifx);
5218                                         goto release;
5219                                 }
5220                                 pic14_emitcode("clr","c");
5221                         }
5222                 } else {
5223                         if (AOP_TYPE(right) == AOP_CRY){
5224                                 // c = bit & bit;
5225                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5226                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5227                         } else {
5228                                 // c = bit & val;
5229                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5230                                 // c = lsb
5231                                 pic14_emitcode("rrc","a");
5232                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5233                         }
5234                 }
5235                 // bit = c
5236                 // val = c
5237                 if(size)
5238                         pic14_outBitC(result);
5239                 // if(bit & ...)
5240                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5241                         genIfxJump(ifx, "c");           
5242                 goto release ;
5243         }
5244         
5245         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5246         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5247         if((AOP_TYPE(right) == AOP_LIT) &&
5248                 (AOP_TYPE(result) == AOP_CRY) &&
5249                 (AOP_TYPE(left) != AOP_CRY)){
5250                 int posbit = isLiteralBit(lit);
5251                 /* left &  2^n */
5252                 if(posbit){
5253                         posbit--;
5254                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5255                         // bit = left & 2^n
5256                         if(size)
5257                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5258                         // if(left &  2^n)
5259                         else{
5260                                 if(ifx){
5261                                         int offset = 0;
5262                                         while (posbit > 7) {
5263                                                 posbit -= 8;
5264                                                 offset++;
5265                                         }
5266                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5267                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5268                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5269                                         
5270                                         ifx->generated = 1;
5271                                 }
5272                                 goto release;
5273                         }
5274                 } else {
5275                         symbol *tlbl = newiTempLabel(NULL);
5276                         int sizel = AOP_SIZE(left);
5277                         if(size)
5278                                 pic14_emitcode("setb","c");
5279                         while(sizel--){
5280                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5281                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5282                                         // byte ==  2^n ?
5283                                         if((posbit = isLiteralBit(bytelit)) != 0)
5284                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5285                                         else{
5286                                                 if(bytelit != 0x0FFL)
5287                                                         pic14_emitcode("anl","a,%s",
5288                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5289                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5290                                         }
5291                                 }
5292                                 offset++;
5293                         }
5294                         // bit = left & literal
5295                         if(size){
5296                                 pic14_emitcode("clr","c");
5297                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5298                         }
5299                         // if(left & literal)
5300                         else{
5301                                 if(ifx)
5302                                         jmpTrueOrFalse(ifx, tlbl);
5303                                 goto release ;
5304                         }
5305                 }
5306                 pic14_outBitC(result);
5307                 goto release ;
5308         }
5309         
5310         /* if left is same as result */
5311         if(pic14_sameRegs(AOP(result),AOP(left))){
5312                 int know_W = -1;
5313                 for(;size--; offset++,lit>>=8) {
5314                         if(AOP_TYPE(right) == AOP_LIT){
5315                                 switch(lit & 0xff) {
5316                                 case 0x00:
5317                                         /*  and'ing with 0 has clears the result */
5318                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5319                                         break;
5320                                 case 0xff:
5321                                         /* and'ing with 0xff is a nop when the result and left are the same */
5322                                         break;
5323                                         
5324                                 default:
5325                                         {
5326                                                 int p = my_powof2( (~lit) & 0xff );
5327                                                 if(p>=0) {
5328                                                         /* only one bit is set in the literal, so use a bcf instruction */
5329                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5330                                                         
5331                                                 } else {
5332                                                         if(know_W != (int)(lit&0xff))
5333                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5334                                                         know_W = lit &0xff;
5335                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5336                                                 }
5337                                         }    
5338                                 }
5339                         } else {
5340                                 if (AOP_TYPE(left) == AOP_ACC) {
5341                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5342                                 } else {        
5343                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5344                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5345                                         
5346                                 }
5347                         }
5348                 }
5349                 
5350         } else {
5351                 // left & result in different registers
5352                 if(AOP_TYPE(result) == AOP_CRY){
5353                         // result = bit
5354                         // if(size), result in bit
5355                         // if(!size && ifx), conditional oper: if(left & right)
5356                         symbol *tlbl = newiTempLabel(NULL);
5357                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5358                         if(size)
5359                                 pic14_emitcode("setb","c");
5360                         while(sizer--){
5361                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5362                                 pic14_emitcode("anl","a,%s",
5363                                         aopGet(AOP(left),offset,FALSE,FALSE));
5364                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5365                                 offset++;
5366                         }
5367                         if(size){
5368                                 CLRC;
5369                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5370                                 pic14_outBitC(result);
5371                         } else if(ifx)
5372                                 jmpTrueOrFalse(ifx, tlbl);
5373                 } else {
5374                         for(;(size--);offset++) {
5375                                 // normal case
5376                                 // result = left & right
5377                                 if(AOP_TYPE(right) == AOP_LIT){
5378                                         int t = (lit >> (offset*8)) & 0x0FFL;
5379                                         switch(t) { 
5380                                         case 0x00:
5381                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5382                                                 break;
5383                                         case 0xff:
5384                                                 if(AOP_TYPE(left) != AOP_ACC) {
5385                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5386                                                 }
5387                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5388                                                 break;
5389                                         default:
5390                                                 if(AOP_TYPE(left) == AOP_ACC) {
5391                                                         emitpcode(POC_ANDLW, popGetLit(t));
5392                                                 } else {
5393                                                         emitpcode(POC_MOVLW, popGetLit(t));
5394                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5395                                                 }
5396                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5397                                         }
5398                                         continue;
5399                                 }
5400                                 
5401                                 if (AOP_TYPE(left) == AOP_ACC) {
5402                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5403                                 } else {
5404                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5405                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5406                                 }
5407                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5408                         }
5409                 }
5410         }
5411         
5412 release :
5413         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5414         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5415         freeAsmop(result,NULL,ic,TRUE);     
5416 }
5417
5418 /*-----------------------------------------------------------------*/
5419 /* genOr  - code for or                                            */
5420 /*-----------------------------------------------------------------*/
5421 static void genOr (iCode *ic, iCode *ifx)
5422 {
5423         operand *left, *right, *result;
5424         int size, offset=0;
5425         unsigned long lit = 0L;
5426         
5427         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5428         
5429         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5430         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5431         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5432         
5433         DEBUGpic14_AopType(__LINE__,left,right,result);
5434         
5435         /* if left is a literal & right is not then exchange them */
5436         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5437                 AOP_NEEDSACC(left)) {
5438                 operand *tmp = right ;
5439                 right = left;
5440                 left = tmp;
5441         }
5442         
5443         /* if result = right then exchange them */
5444         if(pic14_sameRegs(AOP(result),AOP(right))){
5445                 operand *tmp = right ;
5446                 right = left;
5447                 left = tmp;
5448         }
5449         
5450         /* if right is bit then exchange them */
5451         if (AOP_TYPE(right) == AOP_CRY &&
5452                 AOP_TYPE(left) != AOP_CRY){
5453                 operand *tmp = right ;
5454                 right = left;
5455                 left = tmp;
5456         }
5457         
5458         DEBUGpic14_AopType(__LINE__,left,right,result);
5459         
5460         if(AOP_TYPE(right) == AOP_LIT)
5461                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5462         
5463         size = AOP_SIZE(result);
5464         
5465         // if(bit | yy)
5466         // xx = bit | yy;
5467         if (AOP_TYPE(left) == AOP_CRY){
5468                 if(AOP_TYPE(right) == AOP_LIT){
5469                         // c = bit & literal;
5470                         if(lit){
5471                                 // lit != 0 => result = 1
5472                                 if(AOP_TYPE(result) == AOP_CRY){
5473                                         if(size)
5474                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5475                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5476                                         //   AOP(result)->aopu.aop_dir,
5477                                         //   AOP(result)->aopu.aop_dir);
5478                                         else if(ifx)
5479                                                 continueIfTrue(ifx);
5480                                         goto release;
5481                                 }
5482                         } else {
5483                                 // lit == 0 => result = left
5484                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5485                                         goto release;
5486                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5487                         }
5488                 } else {
5489                         if (AOP_TYPE(right) == AOP_CRY){
5490                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5491                                         // c = bit | bit;
5492                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5493                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5494                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5495                                         
5496                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5497                                                 AOP(result)->aopu.aop_dir,
5498                                                 AOP(result)->aopu.aop_dir);
5499                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5500                                                 AOP(right)->aopu.aop_dir,
5501                                                 AOP(right)->aopu.aop_dir);
5502                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5503                                                 AOP(result)->aopu.aop_dir,
5504                                                 AOP(result)->aopu.aop_dir);
5505                                 } else {
5506                                         if( AOP_TYPE(result) == AOP_ACC) {
5507                                                 emitpcode(POC_MOVLW, popGetLit(0));
5508                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5509                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5510                                                 emitpcode(POC_MOVLW, popGetLit(1));
5511                                                 
5512                                         } else {
5513                                                 
5514                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5515                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5516                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5517                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5518                                                 
5519                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5520                                                         AOP(result)->aopu.aop_dir,
5521                                                         AOP(result)->aopu.aop_dir);
5522                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5523                                                         AOP(right)->aopu.aop_dir,
5524                                                         AOP(right)->aopu.aop_dir);
5525                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5526                                                         AOP(left)->aopu.aop_dir,
5527                                                         AOP(left)->aopu.aop_dir);
5528                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5529                                                         AOP(result)->aopu.aop_dir,
5530                                                         AOP(result)->aopu.aop_dir);
5531                                         }
5532                                 }
5533                         } else {
5534                                 // c = bit | val;
5535                                 symbol *tlbl = newiTempLabel(NULL);
5536                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5537                                 
5538                                 
5539                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5540                                 if( AOP_TYPE(right) == AOP_ACC) {
5541                                         emitpcode(POC_IORLW, popGetLit(0));
5542                                         emitSKPNZ;
5543                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5544                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5545                                 }
5546                                 
5547                                 
5548                                 
5549                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5550                                         pic14_emitcode(";XXX setb","c");
5551                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5552                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5553                                 pic14_toBoolean(right);
5554                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5555                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5556                                         jmpTrueOrFalse(ifx, tlbl);
5557                                         goto release;
5558                                 } else {
5559                                         CLRC;
5560                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5561                                 }
5562                         }
5563                 }
5564                 // bit = c
5565                 // val = c
5566                 if(size)
5567                         pic14_outBitC(result);
5568                 // if(bit | ...)
5569                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5570                         genIfxJump(ifx, "c");           
5571                 goto release ;
5572         }
5573
5574         // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5575         // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5576         if((AOP_TYPE(right) == AOP_LIT) &&
5577           (AOP_TYPE(result) == AOP_CRY) &&
5578           (AOP_TYPE(left) != AOP_CRY)){
5579                 if(lit){
5580                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5581                         // result = 1
5582                         if(size)
5583                                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5584                         else 
5585                                 continueIfTrue(ifx);
5586                         goto release;
5587                 } else {
5588                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5589                         // lit = 0, result = boolean(left)
5590                         if(size)
5591                                 pic14_emitcode(";XXX setb","c");
5592                         pic14_toBoolean(right);
5593                         if(size){
5594                                 symbol *tlbl = newiTempLabel(NULL);
5595                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5596                                 CLRC;
5597                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5598                         } else {
5599                                 genIfxJump (ifx,"a");
5600                                 goto release;
5601                         }
5602                 }
5603                 pic14_outBitC(result);
5604                 goto release ;
5605         }
5606
5607         /* if left is same as result */
5608         if(pic14_sameRegs(AOP(result),AOP(left))){
5609                 int know_W = -1;
5610                 for(;size--; offset++,lit>>=8) {
5611                         if(AOP_TYPE(right) == AOP_LIT){
5612                                 if((lit & 0xff) == 0)
5613                                         /*  or'ing with 0 has no effect */
5614                                         continue;
5615                                 else {
5616                                         int p = my_powof2(lit & 0xff);
5617                                         if(p>=0) {
5618                                                 /* only one bit is set in the literal, so use a bsf instruction */
5619                                                 emitpcode(POC_BSF,
5620                                                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5621                                         } else {
5622                                                 if(know_W != (int)(lit & 0xff))
5623                                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5624                                                 know_W = lit & 0xff;
5625                                                 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5626                                         }
5627                                         
5628                                 }
5629                         } else {
5630                                 if (AOP_TYPE(left) == AOP_ACC) {
5631                                         emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5632                                         pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5633                                 } else {        
5634                                         emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5635                                         emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5636                                         
5637                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5638                                         pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5639                                         
5640                                 }
5641                         }
5642                 }
5643         } else {
5644                 // left & result in different registers
5645                 if(AOP_TYPE(result) == AOP_CRY){
5646                         // result = bit
5647                         // if(size), result in bit
5648                         // if(!size && ifx), conditional oper: if(left | right)
5649                         symbol *tlbl = newiTempLabel(NULL);
5650                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5651                         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5652                         
5653                         
5654                         if(size)
5655                                 pic14_emitcode(";XXX setb","c");
5656                         while(sizer--){
5657                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5658                                 pic14_emitcode(";XXX orl","a,%s",
5659                                         aopGet(AOP(left),offset,FALSE,FALSE));
5660                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661                                 offset++;
5662                         }
5663                         if(size){
5664                                 CLRC;
5665                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5666                                 pic14_outBitC(result);
5667                         } else if(ifx)
5668                                 jmpTrueOrFalse(ifx, tlbl);
5669                 } else for(;(size--);offset++){
5670                         // normal case
5671                         // result = left | right
5672                         if(AOP_TYPE(right) == AOP_LIT){
5673                                 int t = (lit >> (offset*8)) & 0x0FFL;
5674                                 switch(t) { 
5675                                 case 0x00:
5676                                         if (AOP_TYPE(left) != AOP_ACC) {
5677                                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5678                                         }
5679                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5680                                         
5681                                         break;
5682                                 default:
5683                                         if (AOP_TYPE(left) == AOP_ACC) {
5684                                                 emitpcode(POC_IORLW,  popGetLit(t));
5685                                         } else {
5686                                                 emitpcode(POC_MOVLW,  popGetLit(t));
5687                                                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5688                                         }
5689                                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5690                                 }
5691                                 continue;
5692                         }
5693                         
5694                         // faster than result <- left, anl result,right
5695                         // and better if result is SFR
5696                         if (AOP_TYPE(left) == AOP_ACC) {
5697                                 emitpcode(POC_IORFW,popGet(AOP(right),offset));
5698                         } else {
5699                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5700                                 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5701                         }
5702                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5703                 }
5704         }
5705
5706 release :
5707         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5708         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5709         freeAsmop(result,NULL,ic,TRUE);     
5710 }
5711
5712 /*-----------------------------------------------------------------*/
5713 /* genXor - code for xclusive or                                   */
5714 /*-----------------------------------------------------------------*/
5715 static void genXor (iCode *ic, iCode *ifx)
5716 {
5717         operand *left, *right, *result;
5718         int size, offset=0;
5719         unsigned long lit = 0L;
5720         
5721         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5722         
5723         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5724         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5725         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5726         
5727         /* if left is a literal & right is not ||
5728         if left needs acc & right does not */
5729         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5730                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5731                 operand *tmp = right ;
5732                 right = left;
5733                 left = tmp;
5734         }
5735         
5736         /* if result = right then exchange them */
5737         if(pic14_sameRegs(AOP(result),AOP(right))){
5738                 operand *tmp = right ;
5739                 right = left;
5740                 left = tmp;
5741         }
5742         
5743         /* if right is bit then exchange them */
5744         if (AOP_TYPE(right) == AOP_CRY &&
5745                 AOP_TYPE(left) != AOP_CRY){
5746                 operand *tmp = right ;
5747                 right = left;
5748                 left = tmp;
5749         }
5750         if(AOP_TYPE(right) == AOP_LIT)
5751                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5752         
5753         size = AOP_SIZE(result);
5754         
5755         // if(bit ^ yy)
5756         // xx = bit ^ yy;
5757         if (AOP_TYPE(left) == AOP_CRY){
5758                 if(AOP_TYPE(right) == AOP_LIT){
5759                         // c = bit & literal;
5760                         if(lit>>1){
5761                                 // lit>>1  != 0 => result = 1
5762                                 if(AOP_TYPE(result) == AOP_CRY){
5763                                         if(size)
5764                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5765                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5766                                         else if(ifx)
5767                                                 continueIfTrue(ifx);
5768                                         goto release;
5769                                 }
5770                                 pic14_emitcode("setb","c");
5771                         } else{
5772                                 // lit == (0 or 1)
5773                                 if(lit == 0){
5774                                         // lit == 0, result = left
5775                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5776                                                 goto release;
5777                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5778                                 } else{
5779                                         // lit == 1, result = not(left)
5780                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5781                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5782                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5783                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5784                                                 goto release;
5785                                         } else {
5786                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5787                                                 pic14_emitcode("cpl","c");
5788                                         }
5789                                 }
5790                         }
5791                         
5792                 } else {
5793                         // right != literal
5794                         symbol *tlbl = newiTempLabel(NULL);
5795                         if (AOP_TYPE(right) == AOP_CRY){
5796                                 // c = bit ^ bit;
5797                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5798                         }
5799                         else{
5800                                 int sizer = AOP_SIZE(right);
5801                                 // c = bit ^ val
5802                                 // if val>>1 != 0, result = 1
5803                                 pic14_emitcode("setb","c");
5804                                 while(sizer){
5805                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5806                                         if(sizer == 1)
5807                                                 // test the msb of the lsb
5808                                                 pic14_emitcode("anl","a,#0xfe");
5809                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5810                                         sizer--;
5811                                 }
5812                                 // val = (0,1)
5813                                 pic14_emitcode("rrc","a");
5814                         }
5815                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5816                         pic14_emitcode("cpl","c");
5817                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5818                 }
5819                 // bit = c
5820                 // val = c
5821                 if(size)
5822                         pic14_outBitC(result);
5823                 // if(bit | ...)
5824                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5825                         genIfxJump(ifx, "c");           
5826                 goto release ;
5827         }
5828         
5829         if(pic14_sameRegs(AOP(result),AOP(left))){
5830                 /* if left is same as result */
5831                 for(;size--; offset++) {
5832                         if(AOP_TYPE(right) == AOP_LIT){
5833                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5834                                 if(t == 0x00L)
5835                                         continue;
5836                                 else
5837                                         if (IS_AOP_PREG(left)) {
5838                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5839                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5840                                                 aopPut(AOP(result),"a",offset);
5841                                         } else {
5842                                                 emitpcode(POC_MOVLW, popGetLit(t));
5843                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5844                                                 pic14_emitcode("xrl","%s,%s",
5845                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5846                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5847                                         }
5848                         } else {
5849                                 if (AOP_TYPE(left) == AOP_ACC)
5850                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5851                                 else {
5852                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5853                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5854                                         /*
5855                                         if (IS_AOP_PREG(left)) {
5856                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5857                                         aopPut(AOP(result),"a",offset);
5858                                         } else
5859                                         pic14_emitcode("xrl","%s,a",
5860                                         aopGet(AOP(left),offset,FALSE,TRUE));
5861                                         */
5862                                 }
5863                         }
5864                 }
5865         } else {
5866                 // left & result in different registers
5867                 if(AOP_TYPE(result) == AOP_CRY){
5868                         // result = bit
5869                         // if(size), result in bit
5870                         // if(!size && ifx), conditional oper: if(left ^ right)
5871                         symbol *tlbl = newiTempLabel(NULL);
5872                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5873                         if(size)
5874                                 pic14_emitcode("setb","c");
5875                         while(sizer--){
5876                                 if((AOP_TYPE(right) == AOP_LIT) &&
5877                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5878                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5879                                 } else {
5880                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5881                                         pic14_emitcode("xrl","a,%s",
5882                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5883                                 }
5884                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5885                                 offset++;
5886                         }
5887                         if(size){
5888                                 CLRC;
5889                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5890                                 pic14_outBitC(result);
5891                         } else if(ifx)
5892                                 jmpTrueOrFalse(ifx, tlbl);
5893                 } else for(;(size--);offset++){
5894                         // normal case
5895                         // result = left & right
5896                         if(AOP_TYPE(right) == AOP_LIT){
5897                                 int t = (lit >> (offset*8)) & 0x0FFL;
5898                                 switch(t) { 
5899                                 case 0x00:
5900                                         if (AOP_TYPE(left) != AOP_ACC) {
5901                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5902                                         }
5903                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5904                                         pic14_emitcode("movf","%s,w",
5905                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5906                                         pic14_emitcode("movwf","%s",
5907                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5908                                         break;
5909                                 case 0xff:
5910                                         if (AOP_TYPE(left) == AOP_ACC) {
5911                                                 emitpcode(POC_XORLW, popGetLit(t));
5912                                         } else {
5913                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5914                                         }
5915                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5916                                         break;
5917                                 default:
5918                                         if (AOP_TYPE(left) == AOP_ACC) {
5919                                                 emitpcode(POC_XORLW, popGetLit(t));
5920                                         } else {
5921                                                 emitpcode(POC_MOVLW, popGetLit(t));
5922                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5923                                         }
5924                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5925                                         pic14_emitcode("movlw","0x%x",t);
5926                                         pic14_emitcode("xorwf","%s,w",
5927                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5928                                         pic14_emitcode("movwf","%s",
5929                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5930                                         
5931                                 }
5932                                 continue;
5933                         }
5934                         
5935                         // faster than result <- left, anl result,right
5936                         // and better if result is SFR
5937                         if (AOP_TYPE(left) == AOP_ACC) {
5938                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5939                         } else {
5940                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5941                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5942                         }
5943                         if ( AOP_TYPE(result) != AOP_ACC){
5944                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5945                         }
5946                 }
5947         }
5948         
5949 release :
5950         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5951         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5952         freeAsmop(result,NULL,ic,TRUE);     
5953 }
5954
5955 /*-----------------------------------------------------------------*/
5956 /* genInline - write the inline code out                           */
5957 /*-----------------------------------------------------------------*/
5958 static void genInline (iCode *ic)
5959 {
5960         char *buffer, *bp, *bp1;
5961         
5962         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5963         
5964         _G.inLine += (!options.asmpeep);
5965         
5966         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5967         strcpy(buffer,IC_INLINE(ic));
5968         
5969         /* emit each line as a code */
5970         while (*bp) {
5971                 if (*bp == '\n') {
5972                         *bp++ = '\0';
5973                         
5974                         if(*bp1)
5975                                 addpCode2pBlock(pb,AssembleLine(bp1));
5976                         bp1 = bp;
5977                 } else {
5978                         if (*bp == ':') {
5979                                 bp++;
5980                                 *bp = '\0';
5981                                 bp++;
5982                                 pic14_emitcode(bp1,"");
5983                                 bp1 = bp;
5984                         } else
5985                                 bp++;
5986                 }
5987         }
5988         if ((bp1 != bp) && *bp1)
5989                 addpCode2pBlock(pb,AssembleLine(bp1));
5990         
5991         Safe_free(buffer);
5992         
5993         _G.inLine -= (!options.asmpeep);
5994 }
5995
5996 /*-----------------------------------------------------------------*/
5997 /* genRRC - rotate right with carry                                */
5998 /*-----------------------------------------------------------------*/
5999 static void genRRC (iCode *ic)
6000 {
6001         operand *left , *result ;
6002         int size, offset = 0, same;
6003         
6004         /* rotate right with carry */
6005         left = IC_LEFT(ic);
6006         result=IC_RESULT(ic);
6007         aopOp (left,ic,FALSE);
6008         aopOp (result,ic,FALSE);
6009         
6010         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6011         
6012         same = pic14_sameRegs(AOP(result),AOP(left));
6013         
6014         size = AOP_SIZE(result);    
6015         
6016         /* get the lsb and put it into the carry */
6017         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6018         
6019         offset = 0 ;
6020         
6021         while(size--) {
6022                 
6023                 if(same) {
6024                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6025                 } else {
6026                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6027                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6028                 }
6029                 
6030                 offset++;
6031         }
6032         
6033         freeAsmop(left,NULL,ic,TRUE);
6034         freeAsmop(result,NULL,ic,TRUE);
6035 }
6036
6037 /*-----------------------------------------------------------------*/
6038 /* genRLC - generate code for rotate left with carry               */
6039 /*-----------------------------------------------------------------*/
6040 static void genRLC (iCode *ic)
6041 {    
6042         operand *left , *result ;
6043         int size, offset = 0;
6044         int same;
6045         
6046         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6047         /* rotate right with carry */
6048         left = IC_LEFT(ic);
6049         result=IC_RESULT(ic);
6050         aopOp (left,ic,FALSE);
6051         aopOp (result,ic,FALSE);
6052         
6053         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6054         
6055         same = pic14_sameRegs(AOP(result),AOP(left));
6056         
6057         /* move it to the result */
6058         size = AOP_SIZE(result);    
6059         
6060         /* get the msb and put it into the carry */
6061         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6062         
6063         offset = 0 ;
6064         
6065         while(size--) {
6066                 
6067                 if(same) {
6068                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6069                 } else {
6070                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6071                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6072                 }
6073                 
6074                 offset++;
6075         }
6076         
6077         
6078         freeAsmop(left,NULL,ic,TRUE);
6079         freeAsmop(result,NULL,ic,TRUE);
6080 }
6081
6082 /*-----------------------------------------------------------------*/
6083 /* genGetHbit - generates code get highest order bit               */
6084 /*-----------------------------------------------------------------*/
6085 static void genGetHbit (iCode *ic)
6086 {
6087         operand *left, *result;
6088         left = IC_LEFT(ic);
6089         result=IC_RESULT(ic);
6090         aopOp (left,ic,FALSE);
6091         aopOp (result,ic,FALSE);
6092         
6093         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6094         /* get the highest order byte into a */
6095         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6096         if(AOP_TYPE(result) == AOP_CRY){
6097                 pic14_emitcode("rlc","a");
6098                 pic14_outBitC(result);
6099         }
6100         else{
6101                 pic14_emitcode("rl","a");
6102                 pic14_emitcode("anl","a,#0x01");
6103                 pic14_outAcc(result);
6104         }
6105         
6106         
6107         freeAsmop(left,NULL,ic,TRUE);
6108         freeAsmop(result,NULL,ic,TRUE);
6109 }
6110
6111 /*-----------------------------------------------------------------*/
6112 /* AccRol - rotate left accumulator by known count                 */
6113 /*-----------------------------------------------------------------*/
6114 static void AccRol (operand *op,int offset,int shCount)
6115 {
6116         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6117         shCount &= 0x0007;              // shCount : 0..7
6118         switch(shCount){
6119         case 0 :
6120                 break;
6121         case 1 :
6122                 pic14_emitcode("rl","a");
6123                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6124                 break;
6125         case 2 :
6126                 pic14_emitcode("rl","a");
6127                 pic14_emitcode("rl","a");
6128                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6129                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6130                 break;
6131         case 3 :
6132                 pic14_emitcode("swap","a");
6133                 pic14_emitcode("rr","a");
6134                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6135                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6136                 break;
6137         case 4 :
6138                 pic14_emitcode("swap","a");
6139                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6140                 break;
6141         case 5 :
6142                 pic14_emitcode("swap","a");
6143                 pic14_emitcode("rl","a");
6144                 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6145                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6146                 break;
6147         case 6 :
6148                 pic14_emitcode("rr","a");
6149                 pic14_emitcode("rr","a");
6150                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6151                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6152                 break;
6153         case 7 :
6154                 pic14_emitcode("rr","a");
6155                 emitpcode(POC_RRF,popGet(AOP(op),offset));
6156                 break;
6157         }
6158 }
6159
6160 /*-----------------------------------------------------------------*/
6161 /* AccLsh - left shift accumulator by known count                  */
6162 /*-----------------------------------------------------------------*/
6163 static void AccLsh (operand *op,int offset,int shCount)
6164 {
6165         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6166         if(shCount != 0){
6167                 /*
6168                 if(shCount == 1) {
6169                         pic14_emitcode("add","a,acc");
6170                         emitCLRC;
6171                         emitpcode(POC_RLF,popGet(AOP(op),offset));
6172                 } else {
6173                         if(shCount == 2) {
6174                                 pic14_emitcode("add","a,acc");
6175                                 emitCLRC;
6176                                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6177                                 pic14_emitcode("add","a,acc");
6178                                 emitCLRC;
6179                                 emitpcode(POC_RLF,popGet(AOP(op),offset));
6180                         } else {
6181                 */
6182                 {
6183                         {
6184                                 /* rotate left accumulator */
6185                                 AccRol(op,offset,shCount);
6186                                 /* and kill the lower order bits */
6187                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6188                                 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6189                         }
6190                 }
6191         }
6192 }
6193
6194 /*-----------------------------------------------------------------*/
6195 /* AccRsh - right shift accumulator by known count                 */
6196 /*-----------------------------------------------------------------*/
6197 static void AccRsh (operand *op,int offset,int shCount)
6198 {
6199         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6200         if(shCount != 0){
6201                 if(shCount == 1){
6202                         CLRC;
6203                         pic14_emitcode("rrc","a");
6204                 } else {
6205                         /* rotate right accumulator */
6206                         AccRol(op,offset,8 - shCount);
6207                         /* and kill the higher order bits */
6208                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6209                 }
6210         }
6211 }
6212
6213 #if 0
6214 /*-----------------------------------------------------------------*/
6215 /* AccSRsh - signed right shift accumulator by known count                 */
6216 /*-----------------------------------------------------------------*/
6217 static void AccSRsh (int shCount)
6218 {
6219         symbol *tlbl ;
6220         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6221         if(shCount != 0){
6222                 if(shCount == 1){
6223                         pic14_emitcode("mov","c,acc.7");
6224                         pic14_emitcode("rrc","a");
6225                 } else if(shCount == 2){
6226                         pic14_emitcode("mov","c,acc.7");
6227                         pic14_emitcode("rrc","a");
6228                         pic14_emitcode("mov","c,acc.7");
6229                         pic14_emitcode("rrc","a");
6230                 } else {
6231                         tlbl = newiTempLabel(NULL);
6232                         /* rotate right accumulator */
6233                         AccRol(8 - shCount);
6234                         /* and kill the higher order bits */
6235                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6236                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6237                         pic14_emitcode("orl","a,#0x%02x",
6238                                 (unsigned char)~SRMask[shCount]);
6239                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6240                 }
6241         }
6242 }
6243 #endif
6244 /*-----------------------------------------------------------------*/
6245 /* shiftR1Left2Result - shift right one byte from left to result   */
6246 /*-----------------------------------------------------------------*/
6247 static void shiftR1Left2ResultSigned (operand *left, int offl,
6248                                                                           operand *result, int offr,
6249                                                                           int shCount)
6250 {
6251         int same;
6252         
6253         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6254         
6255         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6256         
6257         switch(shCount) {
6258         case 1:
6259                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6260                 if(same) 
6261                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6262                 else {
6263                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6264                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6265                 }
6266                 
6267                 break;
6268         case 2:
6269                 
6270                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6271                 if(same) 
6272                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6273                 else {
6274                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6275                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6276                 }
6277                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6278                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6279                 
6280                 break;
6281                 
6282         case 3:
6283                 if(same)
6284                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6285                 else {
6286                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6287                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6288                 }
6289                 
6290                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6291                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6292                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6293                 
6294                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6295                 emitpcode(POC_IORLW, popGetLit(0xe0));
6296                 
6297                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6298                 break;
6299                 
6300         case 4:
6301                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6302                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6303                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6304                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6305                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6306                 break;
6307         case 5:
6308                 if(same) {
6309                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6310                 } else {
6311                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6312                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6313                 }
6314                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6315                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6316                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6317                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6318                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6319                 break;
6320                 
6321         case 6:
6322                 if(same) {
6323                         emitpcode(POC_MOVLW, popGetLit(0x00));
6324                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6325                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6326                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6327                         emitpcode(POC_IORLW, popGetLit(0x01));
6328                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6329                 } else {
6330                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6331                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6332                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6333                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6334                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6335                 }
6336                 break;
6337                 
6338         case 7:
6339                 if(same) {
6340                         emitpcode(POC_MOVLW, popGetLit(0x00));
6341                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6342                         emitpcode(POC_MOVLW, popGetLit(0xff));
6343                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6344                 } else {
6345                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6346                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6347                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6348                 }
6349                 
6350         default:
6351                 break;
6352         }
6353 }
6354
6355 /*-----------------------------------------------------------------*/
6356 /* shiftR1Left2Result - shift right one byte from left to result   */
6357 /*-----------------------------------------------------------------*/
6358 static void shiftR1Left2Result (operand *left, int offl,
6359                                                                 operand *result, int offr,
6360                                                                 int shCount, int sign)
6361 {
6362         int same;
6363         
6364         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6365         
6366         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6367         
6368         /* Copy the msb into the carry if signed. */
6369         if(sign) {
6370                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6371                 return;
6372         }
6373         
6374         
6375         
6376         switch(shCount) {
6377         case 1:
6378                 emitCLRC;
6379                 if(same) 
6380                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6381                 else {
6382                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6383                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384                 }
6385                 break;
6386         case 2:
6387                 emitCLRC;
6388                 if(same) {
6389                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6390                 } else {
6391                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6392                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6393                 }
6394                 emitCLRC;
6395                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6396                 
6397                 break;
6398         case 3:
6399                 if(same)
6400                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6401                 else {
6402                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6403                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6404                 }
6405                 
6406                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6407                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6408                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6409                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6410                 break;
6411                 
6412         case 4:
6413                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6414                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6415                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416                 break;
6417                 
6418         case 5:
6419                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6420                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6421                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422                 emitCLRC;
6423                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6424                 
6425                 break;
6426         case 6:
6427                 
6428                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6429                 emitpcode(POC_ANDLW, popGetLit(0x80));
6430                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6431                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6432                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6433                 break;
6434                 
6435         case 7:
6436                 
6437                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6438                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6439                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6440                 
6441                 break;
6442                 
6443         default:
6444                 break;
6445         }
6446 }
6447
6448 /*-----------------------------------------------------------------*/
6449 /* shiftL1Left2Result - shift left one byte from left to result    */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftL1Left2Result (operand *left, int offl,
6452                                                                 operand *result, int offr, int shCount)
6453 {
6454         int same;
6455         
6456         //    char *l;
6457         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6458         
6459         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6460         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6461         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6462         //    MOVA(l);
6463         /* shift left accumulator */
6464         //AccLsh(shCount); // don't comment out just yet...
6465         //    aopPut(AOP(result),"a",offr);
6466         
6467         switch(shCount) {
6468         case 1:
6469                 /* Shift left 1 bit position */
6470                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6471                 if(same) {
6472                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6473                 } else {
6474                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6475                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6476                 }
6477                 break;
6478         case 2:
6479                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6480                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6481                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6482                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6483                 break;
6484         case 3:
6485                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6486                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6487                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6488                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6489                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6490                 break;
6491         case 4:
6492                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6493                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6494                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6495                 break;
6496         case 5:
6497                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6498                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6499                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6500                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6501                 break;
6502         case 6:
6503                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6504                 emitpcode(POC_ANDLW, popGetLit(0x30));
6505                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6506                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6507                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6508                 break;
6509         case 7:
6510                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6511                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6512                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6513                 break;
6514                 
6515         default:
6516                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6517         }
6518         
6519 }
6520
6521 /*-----------------------------------------------------------------*/
6522 /* movLeft2Result - move byte from left to result                  */
6523 /*-----------------------------------------------------------------*/
6524 static void movLeft2Result (operand *left, int offl,
6525                                                         operand *result, int offr)
6526 {
6527         char *l;
6528         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6529         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6530                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6531                 
6532                 if (*l == '@' && (IS_AOP_PREG(result))) {
6533                         pic14_emitcode("mov","a,%s",l);
6534                         aopPut(AOP(result),"a",offr);
6535                 } else {
6536                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6537                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6538                 }
6539         }
6540 }
6541
6542 /*-----------------------------------------------------------------*/
6543 /* shiftL2Left2Result - shift left two bytes from left to result   */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftL2Left2Result (operand *left, int offl,
6546                                                                 operand *result, int offr, int shCount)
6547 {
6548         
6549         
6550         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6551         
6552         if(pic14_sameRegs(AOP(result), AOP(left))) {
6553                 switch(shCount) {
6554                 case 0:
6555                         break;
6556                 case 1:
6557                 case 2:
6558                 case 3:
6559                         
6560                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6561                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6562                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6563                         
6564                         while(--shCount) {
6565                                 emitCLRC;
6566                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6567                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6568                         }
6569                         
6570                         break;
6571                 case 4:
6572                 case 5:
6573                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6574                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6575                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6576                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6577                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6578                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6579                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6580                         if(shCount >=5) {
6581                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6582                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6583                         }
6584                         break;
6585                 case 6:
6586                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6587                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6588                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6589                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6590                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6591                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6592                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6593                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6594                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6595                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6596                         break;
6597                 case 7:
6598                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6599                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6600                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6601                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6602                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6603                 }
6604                 
6605         } else {
6606                 switch(shCount) {
6607                 case 0:
6608                         break;
6609                 case 1:
6610                 case 2:
6611                 case 3:
6612                 /* note, use a mov/add for the shift since the mov has a
6613                         chance of getting optimized out */
6614                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6615                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6616                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6617                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6618                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6619                         
6620                         while(--shCount) {
6621                                 emitCLRC;
6622                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6623                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6624                         }
6625                         break;
6626                         
6627                 case 4:
6628                 case 5:
6629                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6630                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6631                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6632                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6633                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6634                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6635                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6636                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6637                         
6638                         
6639                         if(shCount == 5) {
6640                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6641                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6642                         }
6643                         break;
6644                 case 6:
6645                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6646                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6647                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6648                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6649                         
6650                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6651                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6652                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6653                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6654                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6655                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6656                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6657                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6658                         break;
6659                 case 7:
6660                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6661                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6662                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6663                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6664                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6665                 }
6666         }
6667         
6668 }
6669 /*-----------------------------------------------------------------*/
6670 /* shiftR2Left2Result - shift right two bytes from left to result  */
6671 /*-----------------------------------------------------------------*/
6672 static void shiftR2Left2Result (operand *left, int offl,
6673                                                                 operand *result, int offr,
6674                                                                 int shCount, int sign)
6675 {
6676         int same=0;
6677         
6678         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6679         same = pic14_sameRegs(AOP(result), AOP(left));
6680         
6681         if(same && ((offl + MSB16) == offr)){
6682                 same=1;
6683                 /* don't crash result[offr] */
6684                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6685                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6686         }
6687         /* else {
6688         movLeft2Result(left,offl, result, offr);
6689         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6690         }
6691         */
6692         /* a:x >> shCount (x = lsb(result))*/
6693         /*
6694         if(sign)
6695         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6696         else {
6697         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6698         */
6699         switch(shCount) {
6700         case 0:
6701                 break;
6702         case 1:
6703         case 2:
6704         case 3:
6705                 if(sign)
6706                         emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6707                 else
6708                         emitCLRC;
6709                 
6710                 if(same) {
6711                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6712                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6713                 } else {
6714                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6715                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6716                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6717                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6718                 }
6719                 
6720                 while(--shCount) {
6721                         if(sign)
6722                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6723                         else
6724                                 emitCLRC;
6725                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6726                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6727                 }
6728                 break;
6729         case 4:
6730         case 5:
6731                 if(same) {
6732                         
6733                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6734                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6735                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6736                         
6737                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6738                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6739                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6740                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6741                 } else {
6742                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6743                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6744                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6745                         
6746                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6747                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6748                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6749                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6750                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6751                 }
6752                 
6753                 if(shCount >=5) {
6754                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6755                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6756                 }
6757                 
6758                 if(sign) {
6759                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6760                         emitpcode(POC_BTFSC, 
6761                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6762                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6763                 }
6764                 
6765                 break;
6766                 
6767         case 6:
6768                 if(same) {
6769                         
6770                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6771                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6772                         
6773                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6774                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6775                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6776                         emitpcode(POC_ANDLW,popGetLit(0x03));
6777                         if(sign) {
6778                                 emitpcode(POC_BTFSC, 
6779                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6780                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6781                         }
6782                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6783                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6784                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6785                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6786                 } else {
6787                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6788                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6789                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6790                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6791                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6792                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6793                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6794                         emitpcode(POC_ANDLW,popGetLit(0x03));
6795                         if(sign) {
6796                                 emitpcode(POC_BTFSC, 
6797                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6798                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6799                         }
6800                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6801                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6802                         
6803                         
6804                 }
6805                 
6806                 break;
6807         case 7:
6808                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6809                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6810                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6812                 if(sign) {
6813                         emitSKPNC;
6814                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6815                 } else 
6816                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6817   }
6818 }
6819
6820
6821 /*-----------------------------------------------------------------*/
6822 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6823 /*-----------------------------------------------------------------*/
6824 static void shiftLLeftOrResult (operand *left, int offl,
6825                                                                 operand *result, int offr, int shCount)
6826 {
6827         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6828         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6829         /* shift left accumulator */
6830         AccLsh(left,offl,shCount);
6831         /* or with result */
6832         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6833         /* back to result */
6834         aopPut(AOP(result),"a",offr);
6835 }
6836
6837 /*-----------------------------------------------------------------*/
6838 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6839 /*-----------------------------------------------------------------*/
6840 static void shiftRLeftOrResult (operand *left, int offl,
6841                                                                 operand *result, int offr, int shCount)
6842 {
6843         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6844         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6845         /* shift right accumulator */
6846         AccRsh(left,offl,shCount);
6847         /* or with result */
6848         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6849         /* back to result */
6850         aopPut(AOP(result),"a",offr);
6851 }
6852
6853 /*-----------------------------------------------------------------*/
6854 /* genlshOne - left shift a one byte quantity by known count       */
6855 /*-----------------------------------------------------------------*/
6856 static void genlshOne (operand *result, operand *left, int shCount)
6857 {       
6858         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6859         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6860 }
6861
6862 /*-----------------------------------------------------------------*/
6863 /* genlshTwo - left shift two bytes by known amount != 0           */
6864 /*-----------------------------------------------------------------*/
6865 static void genlshTwo (operand *result,operand *left, int shCount)
6866 {
6867         int size;
6868         
6869         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6870         size = pic14_getDataSize(result);
6871         
6872         /* if shCount >= 8 */
6873         if (shCount >= 8) {
6874                 shCount -= 8 ;
6875                 
6876                 if (size > 1){
6877                         if (shCount)
6878                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6879                         else 
6880                                 movLeft2Result(left, LSB, result, MSB16);
6881                 }
6882                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6883         }
6884         
6885         /*  1 <= shCount <= 7 */
6886         else {  
6887                 if(size == 1)
6888                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6889                 else 
6890                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6891         }
6892 }
6893
6894 /*-----------------------------------------------------------------*/
6895 /* shiftLLong - shift left one long from left to result            */
6896 /* offl = LSB or MSB16                                             */
6897 /*-----------------------------------------------------------------*/
6898 static void shiftLLong (operand *left, operand *result, int offr )
6899 {
6900         char *l;
6901         int size = AOP_SIZE(result);
6902         
6903         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6904         if(size >= LSB+offr){
6905                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6906                 MOVA(l);
6907                 pic14_emitcode("add","a,acc");
6908                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6909                         size >= MSB16+offr && offr != LSB )
6910                         pic14_emitcode("xch","a,%s",
6911                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6912                 else      
6913                         aopPut(AOP(result),"a",LSB+offr);
6914         }
6915         
6916         if(size >= MSB16+offr){
6917                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6918                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6919                         MOVA(l);
6920                 }
6921                 pic14_emitcode("rlc","a");
6922                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6923                         size >= MSB24+offr && offr != LSB)
6924                         pic14_emitcode("xch","a,%s",
6925                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6926                 else      
6927                         aopPut(AOP(result),"a",MSB16+offr);
6928         }
6929         
6930         if(size >= MSB24+offr){
6931                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6932                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6933                         MOVA(l);
6934                 }
6935                 pic14_emitcode("rlc","a");
6936                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6937                         size >= MSB32+offr && offr != LSB )
6938                         pic14_emitcode("xch","a,%s",
6939                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6940                 else      
6941                         aopPut(AOP(result),"a",MSB24+offr);
6942         }
6943         
6944         if(size > MSB32+offr){
6945                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6946                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6947                         MOVA(l);  
6948                 }
6949                 pic14_emitcode("rlc","a");
6950                 aopPut(AOP(result),"a",MSB32+offr);
6951         }
6952         if(offr != LSB)
6953                 aopPut(AOP(result),zero,LSB);       
6954 }
6955
6956 /*-----------------------------------------------------------------*/
6957 /* genlshFour - shift four byte by a known amount != 0             */
6958 /*-----------------------------------------------------------------*/
6959 static void genlshFour (operand *result, operand *left, int shCount)
6960 {
6961         int size;
6962         
6963         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6964         size = AOP_SIZE(result);
6965         
6966         /* if shifting more that 3 bytes */
6967         if (shCount >= 24 ) {
6968                 shCount -= 24;
6969                 if (shCount)
6970                 /* lowest order of left goes to the highest
6971                 order of the destination */
6972                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6973                 else
6974                         movLeft2Result(left, LSB, result, MSB32);
6975                 aopPut(AOP(result),zero,LSB);
6976                 aopPut(AOP(result),zero,MSB16);
6977                 aopPut(AOP(result),zero,MSB32);
6978                 return;
6979         }
6980         
6981         /* more than two bytes */
6982         else if ( shCount >= 16 ) {
6983                 /* lower order two bytes goes to higher order two bytes */
6984                 shCount -= 16;
6985                 /* if some more remaining */
6986                 if (shCount)
6987                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6988                 else {
6989                         movLeft2Result(left, MSB16, result, MSB32);
6990                         movLeft2Result(left, LSB, result, MSB24);
6991                 }
6992                 aopPut(AOP(result),zero,MSB16);
6993                 aopPut(AOP(result),zero,LSB);
6994                 return;
6995         }    
6996         
6997         /* if more than 1 byte */
6998         else if ( shCount >= 8 ) {
6999                 /* lower order three bytes goes to higher order  three bytes */
7000                 shCount -= 8;
7001                 if(size == 2){
7002                         if(shCount)
7003                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7004                         else
7005                                 movLeft2Result(left, LSB, result, MSB16);
7006                 }
7007                 else{   /* size = 4 */
7008                         if(shCount == 0){
7009                                 movLeft2Result(left, MSB24, result, MSB32);
7010                                 movLeft2Result(left, MSB16, result, MSB24);
7011                                 movLeft2Result(left, LSB, result, MSB16);
7012                                 aopPut(AOP(result),zero,LSB);
7013                         }
7014                         else if(shCount == 1)
7015                                 shiftLLong(left, result, MSB16);
7016                         else{
7017                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7018                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7019                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7020                                 aopPut(AOP(result),zero,LSB);
7021                         }
7022                 }
7023         }
7024         
7025         /* 1 <= shCount <= 7 */
7026         else if(shCount <= 2){
7027                 shiftLLong(left, result, LSB);
7028                 if(shCount == 2)
7029                         shiftLLong(result, result, LSB);
7030         }
7031         /* 3 <= shCount <= 7, optimize */
7032         else{
7033                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7034                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7035                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7036         }
7037 }
7038
7039 /*-----------------------------------------------------------------*/
7040 /* genLeftShiftLiteral - left shifting by known count              */
7041 /*-----------------------------------------------------------------*/
7042 static void genLeftShiftLiteral (operand *left,
7043                                                                  operand *right,
7044                                                                  operand *result,
7045                                                                  iCode *ic)
7046 {    
7047         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7048         int size;
7049         
7050         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7051         freeAsmop(right,NULL,ic,TRUE);
7052         
7053         aopOp(left,ic,FALSE);
7054         aopOp(result,ic,FALSE);
7055         
7056         size = getSize(operandType(result));
7057         
7058 #if VIEW_SIZE
7059         pic14_emitcode("; shift left ","result %d, left %d",size,
7060                 AOP_SIZE(left));
7061 #endif
7062         
7063         /* I suppose that the left size >= result size */
7064         if(shCount == 0){
7065                 while(size--){
7066                         movLeft2Result(left, size, result, size);
7067                 }
7068         }
7069         
7070         else if(shCount >= (size * 8))
7071                 while(size--)
7072                         aopPut(AOP(result),zero,size);
7073                 else{
7074                         switch (size) {
7075                         case 1:
7076                                 genlshOne (result,left,shCount);
7077                                 break;
7078                                 
7079                         case 2:
7080                         case 3:
7081                                 genlshTwo (result,left,shCount);
7082                                 break;
7083                                 
7084                         case 4:
7085                                 genlshFour (result,left,shCount);
7086                                 break;
7087                         }
7088                 }
7089                 freeAsmop(left,NULL,ic,TRUE);
7090                 freeAsmop(result,NULL,ic,TRUE);
7091 }
7092
7093 /*-----------------------------------------------------------------*
7094 * genMultiAsm - repeat assembly instruction for size of register.
7095 * if endian == 1, then the high byte (i.e base address + size of 
7096 * register) is used first else the low byte is used first;
7097 *-----------------------------------------------------------------*/
7098 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7099 {
7100         
7101         int offset = 0;
7102         
7103         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7104         
7105         if(!reg)
7106                 return;
7107         
7108         if(!endian) {
7109                 endian = 1;
7110         } else {
7111                 endian = -1;
7112                 offset = size-1;
7113         }
7114         
7115         while(size--) {
7116                 emitpcode(poc,    popGet(AOP(reg),offset));
7117                 offset += endian;
7118         }
7119         
7120 }
7121 /*-----------------------------------------------------------------*/
7122 /* genLeftShift - generates code for left shifting                 */
7123 /*-----------------------------------------------------------------*/
7124 static void genLeftShift (iCode *ic)
7125 {
7126         operand *left,*right, *result;
7127         int size, offset;
7128         unsigned long lit = 0L;
7129         char *l;
7130         symbol *tlbl , *tlbl1;
7131         pCodeOp *pctemp;
7132         
7133         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7134         
7135         right = IC_RIGHT(ic);
7136         left  = IC_LEFT(ic);
7137         result = IC_RESULT(ic);
7138         
7139         aopOp(right,ic,FALSE);
7140         
7141         /* if the shift count is known then do it 
7142         as efficiently as possible */
7143         if (AOP_TYPE(right) == AOP_LIT) {
7144                 genLeftShiftLiteral (left,right,result,ic);
7145                 return ;
7146         }
7147         
7148         /* shift count is unknown then we have to form 
7149         a loop get the loop count in B : Note: we take
7150         only the lower order byte since shifting
7151         more that 32 bits make no sense anyway, ( the
7152         largest size of an object can be only 32 bits ) */  
7153         
7154         
7155         aopOp(left,ic,FALSE);
7156         aopOp(result,ic,FALSE);
7157         
7158         /* now move the left to the result if they are not the
7159         same */
7160         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7161                 AOP_SIZE(result) > 1) {
7162                 
7163                 size = AOP_SIZE(result);
7164                 offset=0;
7165                 while (size--) {
7166                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7167                         if (*l == '@' && (IS_AOP_PREG(result))) {
7168                                 
7169                                 pic14_emitcode("mov","a,%s",l);
7170                                 aopPut(AOP(result),"a",offset);
7171                         } else {
7172                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7173                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7174                                 //aopPut(AOP(result),l,offset);
7175                         }
7176                         offset++;
7177                 }
7178         }
7179         
7180         if(AOP_TYPE(left) == AOP_LIT)
7181                 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7182
7183         size = AOP_SIZE(result);
7184         
7185         /* if it is only one byte then */
7186         if (size == 1) {
7187                 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7188                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7189                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7190                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7191                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7192                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7193                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7194                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7195                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7196                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7197                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7198                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7199                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7200                 } else {
7201                         
7202                         tlbl = newiTempLabel(NULL);
7203                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7204                                 if (AOP_TYPE(left) == AOP_LIT)
7205                                         emitpcode(POC_MOVLW,  popGetLit(lit));
7206                                 else
7207                                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7208                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7209                         }
7210                         
7211                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7212                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7213                         emitpLabel(tlbl->key);
7214                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7215                         emitpcode(POC_ADDLW,  popGetLit(1));
7216                         emitSKPC;
7217                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7218                 }
7219                 goto release ;
7220         }
7221         
7222         if (pic14_sameRegs(AOP(left),AOP(result))) {
7223                 
7224                 tlbl = newiTempLabel(NULL);
7225                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7226                 genMultiAsm(POC_RRF, result, size,1);
7227                 emitpLabel(tlbl->key);
7228                 genMultiAsm(POC_RLF, result, size,0);
7229                 emitpcode(POC_ADDLW,  popGetLit(1));
7230                 emitSKPC;
7231                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7232                 goto release;
7233         }
7234         
7235         //tlbl = newiTempLabel(NULL);
7236         //offset = 0 ;   
7237         //tlbl1 = newiTempLabel(NULL);
7238         
7239         //reAdjustPreg(AOP(result));    
7240         
7241         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7242         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7243         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7244         //MOVA(l);
7245         //pic14_emitcode("add","a,acc");         
7246         //aopPut(AOP(result),"a",offset++);
7247         //while (--size) {
7248         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7249         //  MOVA(l);
7250         //  pic14_emitcode("rlc","a");         
7251         //  aopPut(AOP(result),"a",offset++);
7252         //}
7253         //reAdjustPreg(AOP(result));
7254         
7255         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7256         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7257         
7258         
7259         tlbl = newiTempLabel(NULL);
7260         tlbl1= newiTempLabel(NULL);
7261         
7262         size = AOP_SIZE(result);
7263         offset = 1;
7264         
7265         pctemp = popGetTempReg();  /* grab a temporary working register. */
7266         
7267         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7268         
7269         /* offset should be 0, 1 or 3 */
7270         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7271         emitSKPNZ;
7272         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7273         
7274         emitpcode(POC_MOVWF, pctemp);
7275         
7276         
7277         emitpLabel(tlbl->key);
7278         
7279         emitCLRC;
7280         emitpcode(POC_RLF,  popGet(AOP(result),0));
7281         while(--size)
7282                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7283         
7284         emitpcode(POC_DECFSZ,  pctemp);
7285         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7286         emitpLabel(tlbl1->key);
7287         
7288         popReleaseTempReg(pctemp);
7289         
7290         
7291 release:
7292         freeAsmop (right,NULL,ic,TRUE);
7293         freeAsmop(left,NULL,ic,TRUE);
7294         freeAsmop(result,NULL,ic,TRUE);
7295 }
7296
7297 /*-----------------------------------------------------------------*/
7298 /* genrshOne - right shift a one byte quantity by known count      */
7299 /*-----------------------------------------------------------------*/
7300 static void genrshOne (operand *result, operand *left,
7301                                            int shCount, int sign)
7302 {
7303         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7304         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7305 }
7306
7307 /*-----------------------------------------------------------------*/
7308 /* genrshTwo - right shift two bytes by known amount != 0          */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshTwo (operand *result,operand *left,
7311                                            int shCount, int sign)
7312 {
7313         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7314         /* if shCount >= 8 */
7315         if (shCount >= 8) {
7316                 shCount -= 8 ;
7317                 if (shCount)
7318                         shiftR1Left2Result(left, MSB16, result, LSB,
7319                         shCount, sign);
7320                 else
7321                         movLeft2Result(left, MSB16, result, LSB);
7322                 
7323                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7324                 
7325                 if(sign) {
7326                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7327                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7328                 }
7329         }
7330         
7331         /*  1 <= shCount <= 7 */
7332         else
7333                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7334 }
7335
7336 /*-----------------------------------------------------------------*/
7337 /* shiftRLong - shift right one long from left to result           */
7338 /* offl = LSB or MSB16                                             */
7339 /*-----------------------------------------------------------------*/
7340 static void shiftRLong (operand *left, int offl,
7341                                                 operand *result, int sign)
7342 {
7343         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7344         if(!sign)
7345                 pic14_emitcode("clr","c");
7346         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7347         if(sign)
7348                 pic14_emitcode("mov","c,acc.7");
7349         pic14_emitcode("rrc","a");
7350         aopPut(AOP(result),"a",MSB32-offl);
7351         if(offl == MSB16)
7352                 /* add sign of "a" */
7353                 addSign(result, MSB32, sign);
7354         
7355         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7356         pic14_emitcode("rrc","a");
7357         aopPut(AOP(result),"a",MSB24-offl);
7358         
7359         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7360         pic14_emitcode("rrc","a");
7361         aopPut(AOP(result),"a",MSB16-offl);
7362         
7363         if(offl == LSB){
7364                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7365                 pic14_emitcode("rrc","a");
7366                 aopPut(AOP(result),"a",LSB);
7367         }
7368 }
7369
7370 /*-----------------------------------------------------------------*/
7371 /* genrshFour - shift four byte by a known amount != 0             */
7372 /*-----------------------------------------------------------------*/
7373 static void genrshFour (operand *result, operand *left,
7374                                                 int shCount, int sign)
7375 {
7376         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7377         /* if shifting more that 3 bytes */
7378         if(shCount >= 24 ) {
7379                 shCount -= 24;
7380                 if(shCount)
7381                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7382                 else
7383                         movLeft2Result(left, MSB32, result, LSB);
7384                 
7385                 addSign(result, MSB16, sign);
7386         }
7387         else if(shCount >= 16){
7388                 shCount -= 16;
7389                 if(shCount)
7390                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7391                 else{
7392                         movLeft2Result(left, MSB24, result, LSB);
7393                         movLeft2Result(left, MSB32, result, MSB16);
7394                 }
7395                 addSign(result, MSB24, sign);
7396         }
7397         else if(shCount >= 8){
7398                 shCount -= 8;
7399                 if(shCount == 1)
7400                         shiftRLong(left, MSB16, result, sign);
7401                 else if(shCount == 0){
7402                         movLeft2Result(left, MSB16, result, LSB);
7403                         movLeft2Result(left, MSB24, result, MSB16);
7404                         movLeft2Result(left, MSB32, result, MSB24);
7405                         addSign(result, MSB32, sign);
7406                 }
7407                 else{
7408                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7409                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7410                         /* the last shift is signed */
7411                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7412                         addSign(result, MSB32, sign);
7413                 }
7414         }
7415         else{   /* 1 <= shCount <= 7 */
7416                 if(shCount <= 2){
7417                         shiftRLong(left, LSB, result, sign);
7418                         if(shCount == 2)
7419                                 shiftRLong(result, LSB, result, sign);
7420                 }
7421                 else{
7422                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7423                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7424                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7425                 }
7426         }
7427 }
7428
7429 /*-----------------------------------------------------------------*/
7430 /* genRightShiftLiteral - right shifting by known count            */
7431 /*-----------------------------------------------------------------*/
7432 static void genRightShiftLiteral (operand *left,
7433                                                                   operand *right,
7434                                                                   operand *result,
7435                                                                   iCode *ic,
7436                                                                   int sign)
7437 {    
7438         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7439         int lsize,res_size;
7440         
7441         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7442         freeAsmop(right,NULL,ic,TRUE);
7443         
7444         aopOp(left,ic,FALSE);
7445         aopOp(result,ic,FALSE);
7446         
7447 #if VIEW_SIZE
7448         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7449                 AOP_SIZE(left));
7450 #endif
7451         
7452         lsize = pic14_getDataSize(left);
7453         res_size = pic14_getDataSize(result);
7454         /* test the LEFT size !!! */
7455         
7456         /* I suppose that the left size >= result size */
7457         if(shCount == 0){
7458                 while(res_size--)
7459                         movLeft2Result(left, lsize, result, res_size);
7460         }
7461         
7462         else if(shCount >= (lsize * 8)){
7463                 
7464                 if(res_size == 1) {
7465                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7466                         if(sign) {
7467                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7468                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7469                         }
7470                 } else {
7471                         
7472                         if(sign) {
7473                                 emitpcode(POC_MOVLW, popGetLit(0));
7474                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7475                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7476                                 while(res_size--)
7477                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7478                                 
7479                         } else {
7480                                 
7481                                 while(res_size--)
7482                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7483                         }
7484                 }
7485         } else {
7486                 
7487                 switch (res_size) {
7488                 case 1:
7489                         genrshOne (result,left,shCount,sign);
7490                         break;
7491                         
7492                 case 2:
7493                         genrshTwo (result,left,shCount,sign);
7494                         break;
7495                         
7496                 case 4:
7497                         genrshFour (result,left,shCount,sign);
7498                         break;
7499                 default :
7500                         break;
7501                 }
7502                 
7503         }
7504         
7505         freeAsmop(left,NULL,ic,TRUE);
7506         freeAsmop(result,NULL,ic,TRUE);
7507 }
7508
7509 /*-----------------------------------------------------------------*/
7510 /* genSignedRightShift - right shift of signed number              */
7511 /*-----------------------------------------------------------------*/
7512 static void genSignedRightShift (iCode *ic)
7513 {
7514         operand *right, *left, *result;
7515         int size, offset;
7516         //  char *l;
7517         symbol *tlbl, *tlbl1 ;
7518         pCodeOp *pctemp;
7519         
7520         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7521         
7522         /* we do it the hard way put the shift count in b
7523         and loop thru preserving the sign */
7524         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7525         
7526         right = IC_RIGHT(ic);
7527         left  = IC_LEFT(ic);
7528         result = IC_RESULT(ic);
7529         
7530         aopOp(right,ic,FALSE);  
7531         aopOp(left,ic,FALSE);
7532         aopOp(result,ic,FALSE);
7533         
7534         
7535         if ( AOP_TYPE(right) == AOP_LIT) {
7536                 genRightShiftLiteral (left,right,result,ic,1);
7537                 return ;
7538         }
7539         /* shift count is unknown then we have to form 
7540         a loop get the loop count in B : Note: we take
7541         only the lower order byte since shifting
7542         more that 32 bits make no sense anyway, ( the
7543         largest size of an object can be only 32 bits ) */  
7544         
7545         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7546         //pic14_emitcode("inc","b");
7547         //freeAsmop (right,NULL,ic,TRUE);
7548         //aopOp(left,ic,FALSE);
7549         //aopOp(result,ic,FALSE);
7550         
7551         /* now move the left to the result if they are not the
7552         same */
7553         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7554                 AOP_SIZE(result) > 1) {
7555                 
7556                 size = AOP_SIZE(result);
7557                 offset=0;
7558                 while (size--) { 
7559                         /*
7560                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7561                         if (*l == '@' && IS_AOP_PREG(result)) {
7562                                 pic14_emitcode("mov","a,%s",l);
7563                                 aopPut(AOP(result),"a",offset);
7564                         } else
7565                         aopPut(AOP(result),l,offset);
7566                         */
7567                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7568                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7569                         
7570                         offset++;
7571                 }
7572         }
7573         
7574         /* mov the highest order bit to OVR */    
7575         tlbl = newiTempLabel(NULL);
7576         tlbl1= newiTempLabel(NULL);
7577         
7578         size = AOP_SIZE(result);
7579         offset = size - 1;
7580         
7581         pctemp = popGetTempReg();  /* grab a temporary working register. */
7582         
7583         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7584         
7585         /* offset should be 0, 1 or 3 */
7586         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7587         emitSKPNZ;
7588         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7589         
7590         emitpcode(POC_MOVWF, pctemp);
7591         
7592         
7593         emitpLabel(tlbl->key);
7594         
7595         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7596         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7597         
7598         while(--size) {
7599                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7600         }
7601         
7602         emitpcode(POC_DECFSZ,  pctemp);
7603         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7604         emitpLabel(tlbl1->key);
7605         
7606         popReleaseTempReg(pctemp);
7607 #if 0
7608         size = AOP_SIZE(result);
7609         offset = size - 1;
7610         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7611         pic14_emitcode("rlc","a");
7612         pic14_emitcode("mov","ov,c");
7613         /* if it is only one byte then */
7614         if (size == 1) {
7615                 l = aopGet(AOP(left),0,FALSE,FALSE);
7616                 MOVA(l);
7617                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7618                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7619                 pic14_emitcode("mov","c,ov");
7620                 pic14_emitcode("rrc","a");
7621                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7622                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7623                 aopPut(AOP(result),"a",0);
7624                 goto release ;
7625         }
7626         
7627         reAdjustPreg(AOP(result));
7628         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7629         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7630         pic14_emitcode("mov","c,ov");
7631         while (size--) {
7632                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7633                 MOVA(l);
7634                 pic14_emitcode("rrc","a");         
7635                 aopPut(AOP(result),"a",offset--);
7636         }
7637         reAdjustPreg(AOP(result));
7638         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7639         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7640         
7641 release:
7642 #endif
7643         
7644         freeAsmop(left,NULL,ic,TRUE);
7645         freeAsmop(result,NULL,ic,TRUE);
7646         freeAsmop(right,NULL,ic,TRUE);
7647 }
7648
7649 /*-----------------------------------------------------------------*/
7650 /* genRightShift - generate code for right shifting                */
7651 /*-----------------------------------------------------------------*/
7652 static void genRightShift (iCode *ic)
7653 {
7654         operand *right, *left, *result;
7655         sym_link *retype ;
7656         int size, offset;
7657         char *l;
7658         symbol *tlbl, *tlbl1 ;
7659         
7660         /* if signed then we do it the hard way preserve the
7661         sign bit moving it inwards */
7662         retype = getSpec(operandType(IC_RESULT(ic)));
7663         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7664         
7665         if (!SPEC_USIGN(retype)) {
7666                 genSignedRightShift (ic);
7667                 return ;
7668         }
7669         
7670         /* signed & unsigned types are treated the same : i.e. the
7671         signed is NOT propagated inwards : quoting from the
7672         ANSI - standard : "for E1 >> E2, is equivalent to division
7673         by 2**E2 if unsigned or if it has a non-negative value,
7674         otherwise the result is implementation defined ", MY definition
7675         is that the sign does not get propagated */
7676         
7677         right = IC_RIGHT(ic);
7678         left  = IC_LEFT(ic);
7679         result = IC_RESULT(ic);
7680         
7681         aopOp(right,ic,FALSE);
7682         
7683         /* if the shift count is known then do it 
7684         as efficiently as possible */
7685         if (AOP_TYPE(right) == AOP_LIT) {
7686                 genRightShiftLiteral (left,right,result,ic, 0);
7687                 return ;
7688         }
7689         
7690         /* shift count is unknown then we have to form 
7691         a loop get the loop count in B : Note: we take
7692         only the lower order byte since shifting
7693         more that 32 bits make no sense anyway, ( the
7694         largest size of an object can be only 32 bits ) */  
7695         
7696         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7697         pic14_emitcode("inc","b");
7698         aopOp(left,ic,FALSE);
7699         aopOp(result,ic,FALSE);
7700         
7701         /* now move the left to the result if they are not the
7702         same */
7703         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7704                 AOP_SIZE(result) > 1) {
7705                 
7706                 size = AOP_SIZE(result);
7707                 offset=0;
7708                 while (size--) {
7709                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7710                         if (*l == '@' && IS_AOP_PREG(result)) {
7711                                 
7712                                 pic14_emitcode("mov","a,%s",l);
7713                                 aopPut(AOP(result),"a",offset);
7714                         } else
7715                                 aopPut(AOP(result),l,offset);
7716                         offset++;
7717                 }
7718         }
7719         
7720         tlbl = newiTempLabel(NULL);
7721         tlbl1= newiTempLabel(NULL);
7722         size = AOP_SIZE(result);
7723         offset = size - 1;
7724         
7725         /* if it is only one byte then */
7726         if (size == 1) {
7727                 
7728                 tlbl = newiTempLabel(NULL);
7729                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7730                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7731                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7732                 }
7733                 
7734                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7735                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7736                 emitpLabel(tlbl->key);
7737                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7738                 emitpcode(POC_ADDLW,  popGetLit(1));
7739                 emitSKPC;
7740                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7741                 
7742                 goto release ;
7743         }
7744         
7745         reAdjustPreg(AOP(result));
7746         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7747         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7748         CLRC;
7749         while (size--) {
7750                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7751                 MOVA(l);
7752                 pic14_emitcode("rrc","a");         
7753                 aopPut(AOP(result),"a",offset--);
7754         }
7755         reAdjustPreg(AOP(result));
7756         
7757         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7758         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7759         
7760 release:
7761         freeAsmop(left,NULL,ic,TRUE);
7762         freeAsmop (right,NULL,ic,TRUE);
7763         freeAsmop(result,NULL,ic,TRUE);
7764 }
7765
7766 /*-----------------------------------------------------------------*/
7767 /* genUnpackBits - generates code for unpacking bits               */
7768 /*-----------------------------------------------------------------*/
7769 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7770 {    
7771         int shCnt;
7772         int offset = 0;       /* result byte offset */
7773         int rsize;            /* result size */
7774         int rlen = 0;         /* remaining bitfield length */
7775         sym_link *etype;      /* bitfield type information */
7776         int blen;             /* bitfield length */
7777         int bstr;             /* bitfield starting bit within byte */
7778
7779         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7780         etype = getSpec(operandType(result));
7781         rsize = getSize (operandType (result));
7782         blen = SPEC_BLEN (etype);
7783         bstr = SPEC_BSTR (etype);
7784         
7785         /* single bit field case */
7786         if (blen == 1) {
7787                 if (ifx) { /* that is for an if statement */
7788                         pCodeOp *pcop;
7789                         resolvedIfx rIfx;
7790                         resolveIfx(&rIfx,ifx);
7791                         if (ptype == -1) /* direct */
7792                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7793                         else
7794                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7795                         emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7796                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7797                         ifx->generated=1;
7798                 } else {
7799                         pCodeOp *pcop;
7800                         if (ptype == -1) /* direct */
7801                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7802                         else
7803                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7804                         emitpcode(POC_BTFSC,pcop);
7805                         emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7806
7807                         if (ptype == -1) /* direct */
7808                                 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7809                         else
7810                                 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7811                         emitpcode(POC_BTFSS,pcop);
7812                         emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7813                 }
7814                 return;
7815         }
7816
7817         /* read the first byte  */
7818         switch (ptype) {
7819                 
7820         case POINTER:
7821         case IPOINTER:
7822 //              pic14_emitcode("mov","a,@%s",rname);
7823                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
7824                 break;
7825                 
7826         case PPOINTER:
7827                 pic14_emitcode("movx","a,@%s",rname);
7828                 break;
7829                 
7830         case FPOINTER:
7831                 pic14_emitcode("movx","a,@dptr");
7832                 break;
7833                 
7834         case CPOINTER:
7835                 pic14_emitcode("clr","a");
7836                 pic14_emitcode("movc","a","@a+dptr");
7837                 break;
7838                 
7839         case GPOINTER:
7840                 pic14_emitcode("lcall","__gptrget");
7841                 break;
7842         }
7843
7844         /* if we have bitdisplacement then it fits   */
7845         /* into this byte completely or if length is */
7846         /* less than a byte                          */
7847         if ((shCnt = SPEC_BSTR(etype)) || blen <= 8)  {
7848                 
7849                 /* shift right acc */
7850                 AccRsh(left,0,shCnt);
7851                 
7852                 pic14_emitcode("anl","a,#0x%02x",
7853                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7854                 aopPut(AOP(result),"a",offset);
7855                 return ;
7856         }
7857         
7858         /* bit field did not fit in a byte  */
7859         rlen = SPEC_BLEN(etype) - 8;
7860         aopPut(AOP(result),"a",offset++);
7861         
7862         while (1)  {
7863                 
7864                 switch (ptype) {
7865                 case POINTER:
7866                 case IPOINTER:
7867                         pic14_emitcode("inc","%s",rname);
7868                         pic14_emitcode("mov","a,@%s",rname);
7869                         break;
7870                         
7871                 case PPOINTER:
7872                         pic14_emitcode("inc","%s",rname);
7873                         pic14_emitcode("movx","a,@%s",rname);
7874                         break;
7875                         
7876                 case FPOINTER:
7877                         pic14_emitcode("inc","dptr");
7878                         pic14_emitcode("movx","a,@dptr");
7879                         break;
7880                         
7881                 case CPOINTER:
7882                         pic14_emitcode("clr","a");
7883                         pic14_emitcode("inc","dptr");
7884                         pic14_emitcode("movc","a","@a+dptr");
7885                         break;
7886                         
7887                 case GPOINTER:
7888                         pic14_emitcode("inc","dptr");
7889                         pic14_emitcode("lcall","__gptrget");
7890                         break;
7891                 }
7892                 
7893                 rlen -= 8;            
7894                 /* if we are done */
7895                 if ( rlen <= 0 )
7896                         break ;
7897                 
7898                 aopPut(AOP(result),"a",offset++);
7899                 
7900         }
7901         
7902         if (rlen) {
7903                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7904                 aopPut(AOP(result),"a",offset);        
7905         }
7906         
7907         return ;
7908 }
7909
7910 #if 0
7911 /*-----------------------------------------------------------------*/
7912 /* genDataPointerGet - generates code when ptr offset is known     */
7913 /*-----------------------------------------------------------------*/
7914 static void genDataPointerGet (operand *left, 
7915                                                            operand *result, 
7916                                                            iCode *ic)
7917 {
7918         int size , offset = 0;
7919         
7920         
7921         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7922         
7923         
7924         /* optimization - most of the time, left and result are the same
7925         * address, but different types. for the pic code, we could omit
7926         * the following
7927         */
7928         
7929         aopOp(result,ic,TRUE);
7930         
7931         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7932         
7933         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7934         
7935         size = AOP_SIZE(result);
7936         
7937         while (size--) {
7938                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7939                 offset++;
7940         }
7941         
7942         freeAsmop(left,NULL,ic,TRUE);
7943         freeAsmop(result,NULL,ic,TRUE);
7944 }
7945 #endif
7946 /*-----------------------------------------------------------------*/
7947 /* genNearPointerGet - pic14_emitcode for near pointer fetch       */
7948 /*-----------------------------------------------------------------*/
7949 static void genNearPointerGet (operand *left, 
7950                                                            operand *result, 
7951                                                            iCode *ic)
7952 {
7953         asmop *aop = NULL;
7954         sym_link *ltype = operandType(left);
7955         sym_link *rtype = operandType(result);
7956         sym_link *retype= getSpec(rtype);      /* bitfield type information */
7957         int direct = 0;
7958
7959         
7960         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7961         
7962         
7963         aopOp(left,ic,FALSE);
7964         
7965         /* if left is rematerialisable and
7966         result is not bit variable type and
7967         the left is pointer to data space i.e
7968         lower 128 bytes of space */
7969         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7970                 !IS_BITVAR(retype)         &&
7971                 DCL_TYPE(ltype) == POINTER) {
7972                 //genDataPointerGet (left,result,ic);
7973                 return ;
7974         }
7975         
7976         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7977         aopOp (result,ic,FALSE);
7978         
7979         /* Check if can access directly instead of via a pointer */
7980         if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
7981                 direct = 1;
7982         }
7983
7984         /* If the pointer value is not in a the FSR then need to put it in */
7985         if (!AOP_INPREG(AOP(left)) && !direct) {
7986                 /* otherwise get a free pointer register */
7987                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7988                 if (PCOP(AOP(result))->type == PO_LITERAL) 
7989                         emitpcode(POC_MOVLW, popGet(AOP(left),0));
7990                 else
7991                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7992                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
7993         }
7994         
7995         
7996 //      sym_link *etype;
7997         /* if bitfield then unpack the bits */
7998         if (IS_BITFIELD(retype)) 
7999                 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8000         else {
8001                 /* we have can just get the values */
8002                 int size = AOP_SIZE(result);
8003                 int offset = 0 ;  
8004                 
8005                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8006                 
8007                 while(size--) {
8008                         if (direct)
8009                                 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8010                         else
8011                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8012                         if (AOP_TYPE(result) == AOP_LIT) {
8013                                 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8014                         } else {
8015                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8016                         }
8017                         if (size && !direct)
8018                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8019                         offset++;
8020                 }
8021         }
8022         
8023         /* now some housekeeping stuff */
8024         if (aop) {
8025                 /* we had to allocate for this iCode */
8026                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8027                 freeAsmop(NULL,aop,ic,TRUE);
8028         } else { 
8029                 /* we did not allocate which means left
8030                 already in a pointer register, then
8031                 if size > 0 && this could be used again
8032                 we have to point it back to where it 
8033                 belongs */
8034                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8035                 if (AOP_SIZE(result) > 1 &&
8036                         !OP_SYMBOL(left)->remat &&
8037                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8038                         ic->depth )) {
8039                         int size = AOP_SIZE(result) - 1;
8040                         while (size--)
8041                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8042                 }
8043         }
8044         
8045         /* done */
8046         freeAsmop(left,NULL,ic,TRUE);
8047         freeAsmop(result,NULL,ic,TRUE);
8048
8049 }
8050
8051 /*-----------------------------------------------------------------*/
8052 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8053 /*-----------------------------------------------------------------*/
8054 static void genPagedPointerGet (operand *left, 
8055                                                                 operand *result, 
8056                                                                 iCode *ic)
8057 {
8058         asmop *aop = NULL;
8059         regs *preg = NULL ;
8060         char *rname ;
8061         sym_link *rtype, *retype;    
8062         
8063         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8064         
8065         rtype = operandType(result);
8066         retype= getSpec(rtype);
8067         
8068         aopOp(left,ic,FALSE);
8069         
8070         /* if the value is already in a pointer register
8071         then don't need anything more */
8072         if (!AOP_INPREG(AOP(left))) {
8073                 /* otherwise get a free pointer register */
8074                 aop = newAsmop(0);
8075                 preg = getFreePtr(ic,&aop,FALSE);
8076                 pic14_emitcode("mov","%s,%s",
8077                         preg->name,
8078                         aopGet(AOP(left),0,FALSE,TRUE));
8079                 rname = preg->name ;
8080         } else
8081                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8082         
8083         freeAsmop(left,NULL,ic,TRUE);
8084         aopOp (result,ic,FALSE);
8085         
8086         /* if bitfield then unpack the bits */
8087         if (IS_BITFIELD(retype)) 
8088                 genUnpackBits (result,left,rname,PPOINTER,0);
8089         else {
8090                 /* we have can just get the values */
8091                 int size = AOP_SIZE(result);
8092                 int offset = 0 ;  
8093                 
8094                 while (size--) {
8095                         
8096                         pic14_emitcode("movx","a,@%s",rname);
8097                         aopPut(AOP(result),"a",offset);
8098                         
8099                         offset++ ;
8100                         
8101                         if (size)
8102                                 pic14_emitcode("inc","%s",rname);
8103                 }
8104         }
8105         
8106         /* now some housekeeping stuff */
8107         if (aop) {
8108                 /* we had to allocate for this iCode */
8109                 freeAsmop(NULL,aop,ic,TRUE);
8110         } else { 
8111         /* we did not allocate which means left
8112         already in a pointer register, then
8113         if size > 0 && this could be used again
8114         we have to point it back to where it 
8115                 belongs */
8116                 if (AOP_SIZE(result) > 1 &&
8117                         !OP_SYMBOL(left)->remat &&
8118                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8119                         ic->depth )) {
8120                         int size = AOP_SIZE(result) - 1;
8121                         while (size--)
8122                                 pic14_emitcode("dec","%s",rname);
8123                 }
8124         }
8125         
8126         /* done */
8127         freeAsmop(result,NULL,ic,TRUE);
8128         
8129         
8130 }
8131
8132 /*-----------------------------------------------------------------*/
8133 /* genFarPointerGet - gget value from far space                    */
8134 /*-----------------------------------------------------------------*/
8135 static void genFarPointerGet (operand *left,
8136                                                           operand *result, iCode *ic)
8137 {
8138         int size, offset ;
8139         sym_link *retype = getSpec(operandType(result));
8140         
8141         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8142         
8143         aopOp(left,ic,FALSE);
8144         
8145         /* if the operand is already in dptr 
8146         then we do nothing else we move the value to dptr */
8147         if (AOP_TYPE(left) != AOP_STR) {
8148                 /* if this is remateriazable */
8149                 if (AOP_TYPE(left) == AOP_IMMD)
8150                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8151                 else { /* we need to get it byte by byte */
8152                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8153                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8154                         if (options.model == MODEL_FLAT24)
8155                         {
8156                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8157                         }
8158                 }
8159         }
8160         /* so dptr know contains the address */
8161         freeAsmop(left,NULL,ic,TRUE);
8162         aopOp(result,ic,FALSE);
8163         
8164         /* if bit then unpack */
8165         if (IS_BITFIELD(retype)) 
8166                 genUnpackBits(result,left,"dptr",FPOINTER,0);
8167         else {
8168                 size = AOP_SIZE(result);
8169                 offset = 0 ;
8170                 
8171                 while (size--) {
8172                         pic14_emitcode("movx","a,@dptr");
8173                         aopPut(AOP(result),"a",offset++);
8174                         if (size)
8175                                 pic14_emitcode("inc","dptr");
8176                 }
8177         }
8178         
8179         freeAsmop(result,NULL,ic,TRUE);
8180 }
8181 #if 0
8182 /*-----------------------------------------------------------------*/
8183 /* genCodePointerGet - get value from code space                  */
8184 /*-----------------------------------------------------------------*/
8185 static void genCodePointerGet (operand *left,
8186                                                            operand *result, iCode *ic)
8187 {
8188         int size, offset ;
8189         sym_link *retype = getSpec(operandType(result));
8190         
8191         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8192         
8193         aopOp(left,ic,FALSE);
8194         
8195         /* if the operand is already in dptr 
8196         then we do nothing else we move the value to dptr */
8197         if (AOP_TYPE(left) != AOP_STR) {
8198                 /* if this is remateriazable */
8199                 if (AOP_TYPE(left) == AOP_IMMD)
8200                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201                 else { /* we need to get it byte by byte */
8202                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204                         if (options.model == MODEL_FLAT24)
8205                         {
8206                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8207                         }
8208                 }
8209         }
8210         /* so dptr know contains the address */
8211         freeAsmop(left,NULL,ic,TRUE);
8212         aopOp(result,ic,FALSE);
8213         
8214         /* if bit then unpack */
8215         if (IS_BITFIELD(retype)) 
8216                 genUnpackBits(result,left,"dptr",CPOINTER,0);
8217         else {
8218                 size = AOP_SIZE(result);
8219                 offset = 0 ;
8220                 
8221                 while (size--) {
8222                         pic14_emitcode("clr","a");
8223                         pic14_emitcode("movc","a,@a+dptr");
8224                         aopPut(AOP(result),"a",offset++);
8225                         if (size)
8226                                 pic14_emitcode("inc","dptr");
8227                 }
8228         }
8229         
8230         freeAsmop(result,NULL,ic,TRUE);
8231 }
8232 #endif
8233 /*-----------------------------------------------------------------*/
8234 /* genGenPointerGet - gget value from generic pointer space        */
8235 /*-----------------------------------------------------------------*/
8236 static void genGenPointerGet (operand *left,
8237                                                           operand *result, iCode *ic)
8238 {
8239         int size, offset ;
8240         sym_link *retype = getSpec(operandType(result));
8241         
8242         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8243         aopOp(left,ic,FALSE);
8244         aopOp(result,ic,FALSE);
8245         
8246         
8247         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8248         
8249         /* if the operand is already in dptr 
8250         then we do nothing else we move the value to dptr */
8251         //  if (AOP_TYPE(left) != AOP_STR) {
8252         /* if this is remateriazable */
8253         if (AOP_TYPE(left) == AOP_IMMD) {
8254                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8255                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8256         }
8257         else { /* we need to get it byte by byte */
8258                 
8259                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8260                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8261                 
8262                 size = AOP_SIZE(result);
8263                 offset = 0 ;
8264                 
8265                 while(size--) {
8266                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8267                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8268                         if(size)
8269                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8270                 }
8271                 goto release;
8272         }
8273         //}
8274         /* so dptr know contains the address */
8275         
8276         /* if bit then unpack */
8277         //if (IS_BITFIELD(retype)) 
8278         //  genUnpackBits(result,"dptr",GPOINTER);
8279         
8280 release:
8281         freeAsmop(left,NULL,ic,TRUE);
8282         freeAsmop(result,NULL,ic,TRUE);
8283         
8284 }
8285
8286 /*-----------------------------------------------------------------*/
8287 /* genConstPointerGet - get value from const generic pointer space */
8288 /*-----------------------------------------------------------------*/
8289 static void genConstPointerGet (operand *left,
8290                                                                 operand *result, iCode *ic)
8291 {
8292         //sym_link *retype = getSpec(operandType(result));
8293         symbol *albl = newiTempLabel(NULL);
8294         symbol *blbl = newiTempLabel(NULL);
8295         PIC_OPCODE poc;
8296         pCodeOp *pcop;
8297         
8298         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8299         aopOp(left,ic,FALSE);
8300         aopOp(result,ic,FALSE);
8301         
8302         
8303         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8304         
8305         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8306         
8307         emitpcode(POC_CALL,popGetLabel(albl->key));
8308         pcop = popGetLabel(blbl->key);
8309         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8310         emitpcode(POC_GOTO,pcop);
8311         emitpLabel(albl->key);
8312         
8313         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8314         
8315         emitpcode(poc,popGet(AOP(left),1));
8316         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8317         emitpcode(poc,popGet(AOP(left),0));
8318         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8319         
8320         emitpLabel(blbl->key);
8321         
8322         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8323         
8324         
8325         freeAsmop(left,NULL,ic,TRUE);
8326         freeAsmop(result,NULL,ic,TRUE);
8327         
8328 }
8329 /*-----------------------------------------------------------------*/
8330 /* genPointerGet - generate code for pointer get                   */
8331 /*-----------------------------------------------------------------*/
8332 static void genPointerGet (iCode *ic)
8333 {
8334         operand *left, *result ;
8335         sym_link *type, *etype;
8336         int p_type;
8337         
8338         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8339         
8340         left = IC_LEFT(ic);
8341         result = IC_RESULT(ic) ;
8342         
8343         /* depending on the type of pointer we need to
8344         move it to the correct pointer register */
8345         type = operandType(left);
8346         etype = getSpec(type);
8347         
8348         if (IS_PTR_CONST(type))
8349                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8350         
8351         /* if left is of type of pointer then it is simple */
8352         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8353                 p_type = DCL_TYPE(type);
8354         else {
8355                 /* we have to go by the storage class */
8356                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8357                 
8358                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8359                 
8360                 if (SPEC_OCLS(etype)->codesp ) {
8361                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8362                         //p_type = CPOINTER ; 
8363                 }
8364                 else
8365                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8366                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8367                         /*p_type = FPOINTER ;*/ 
8368                         else
8369                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8370                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8371                                 /*        p_type = PPOINTER; */
8372                                 else
8373                                         if (SPEC_OCLS(etype) == idata )
8374                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8375                                         /*      p_type = IPOINTER; */
8376                                         else
8377                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8378                                         /*      p_type = POINTER ; */
8379         }
8380         
8381         /* now that we have the pointer type we assign
8382         the pointer values */
8383         switch (p_type) {
8384                 
8385         case POINTER: 
8386         case IPOINTER:
8387                 genNearPointerGet (left,result,ic);
8388                 break;
8389                 
8390         case PPOINTER:
8391                 genPagedPointerGet(left,result,ic);
8392                 break;
8393                 
8394         case FPOINTER:
8395                 genFarPointerGet (left,result,ic);
8396                 break;
8397                 
8398         case CPOINTER:
8399                 genConstPointerGet (left,result,ic);
8400                 //pic14_emitcodePointerGet (left,result,ic);
8401                 break;
8402                 
8403         case GPOINTER:
8404                 if (IS_PTR_CONST(type))
8405                         genConstPointerGet (left,result,ic);
8406                 else
8407                         genGenPointerGet (left,result,ic);
8408                 break;
8409         }
8410         
8411 }
8412
8413 /*-----------------------------------------------------------------*/
8414 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into  */
8415 /* A through a pointer register (R0, R1, or DPTR). The original    */
8416 /* value of A can be preserved in B.                               */
8417 /* PIC has to use INDF register.                                   */
8418 /*-----------------------------------------------------------------*/
8419 static void
8420 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8421 {
8422         switch (p_type)
8423     {
8424     case IPOINTER:
8425     case POINTER:
8426                 if (preserveAinB)
8427                         pic14_emitcode ("mov", "b,a");
8428 //              pic14_emitcode ("mov", "a,@%s", rname);
8429                 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8430                 break;
8431                 
8432     case PPOINTER:
8433                 if (preserveAinB)
8434                         pic14_emitcode ("mov", "b,a");
8435                 pic14_emitcode ("movx", "a,@%s", rname);
8436                 break;
8437                 
8438     case FPOINTER:
8439                 if (preserveAinB)
8440                         pic14_emitcode ("mov", "b,a");
8441                 pic14_emitcode ("movx", "a,@dptr");
8442                 break;
8443                 
8444     case CPOINTER:
8445                 if (preserveAinB)
8446                         pic14_emitcode ("mov", "b,a");
8447                 pic14_emitcode ("clr", "a");
8448                 pic14_emitcode ("movc", "a,@a+dptr");
8449                 break;
8450                 
8451     case GPOINTER:
8452                 if (preserveAinB)
8453         {
8454                         pic14_emitcode ("push", "b");
8455                         pic14_emitcode ("push", "acc");
8456         }
8457                 pic14_emitcode ("lcall", "__gptrget");
8458                 if (preserveAinB)
8459                         pic14_emitcode ("pop", "b");
8460                 break;
8461     }
8462 }
8463
8464 /*-----------------------------------------------------------------*/
8465 /* emitPtrByteSet - emits code to set a byte from src through a    */
8466 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR).       */
8467 /*-----------------------------------------------------------------*/
8468 static void
8469 emitPtrByteSet (char *rname, int p_type, char *src)
8470 {
8471         switch (p_type)
8472     {
8473     case IPOINTER:
8474     case POINTER:
8475                 if (*src=='@')
8476         {
8477                         MOVA (src);
8478                         pic14_emitcode ("mov", "@%s,a", rname);
8479         }
8480                 else
8481 //                      pic14_emitcode ("mov", "@%s,%s", rname, src);
8482                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8483                 break;
8484                 
8485     case PPOINTER:
8486                 MOVA (src);
8487                 pic14_emitcode ("movx", "@%s,a", rname);
8488                 break;
8489                 
8490     case FPOINTER:
8491                 MOVA (src);
8492                 pic14_emitcode ("movx", "@dptr,a");
8493                 break;
8494                 
8495     case GPOINTER:
8496                 MOVA (src);
8497                 pic14_emitcode ("lcall", "__gptrput");
8498                 break;
8499     }
8500 }
8501
8502 /*-----------------------------------------------------------------*/
8503 /* genPackBits - generates code for packed bit storage             */
8504 /*-----------------------------------------------------------------*/
8505 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8506 {
8507         int offset = 0;       /* source byte offset */
8508         int rlen = 0;         /* remaining bitfield length */
8509         int blen;             /* bitfield length */
8510         int bstr;             /* bitfield starting bit within byte */
8511         int litval;           /* source literal value (if AOP_LIT) */
8512         unsigned char mask;   /* bitmask within current byte */
8513         
8514         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8515         
8516         blen = SPEC_BLEN (etype);
8517         bstr = SPEC_BSTR (etype);
8518         
8519         /* If the bitfield length is less than a byte */
8520         if (blen < 8)
8521     {
8522                 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8523                         (unsigned char) (0xFF >> (8 - bstr)));
8524                 
8525                 if (AOP_TYPE (right) == AOP_LIT)
8526         {
8527                         /* Case with a bitfield length <8 and literal source
8528                         */
8529                         int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8530                         if (blen == 1) {
8531                                 if (p_type == -1) {
8532                                         pCodeOp *pcop;
8533                                         if (AOP(result)->type == AOP_PCODE)
8534                                                 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8535                                         else
8536                                                 pcop = popGet(AOP(result),0);
8537                                         emitpcode(lit?POC_BSF:POC_BCF,pcop);
8538                                 } else {
8539                                         emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8540                                 }
8541                                 return;
8542                         } else {
8543                                 litval = lit << bstr;
8544                                 litval &= (~mask) & 0xff;
8545                                 if (p_type == -1)
8546                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8547                                 else
8548                                         emitPtrByteGet (rname, p_type, FALSE);
8549                                 if ((mask|litval)!=0xff)
8550                                         emitpcode(POC_ANDLW,popGetLit(mask));
8551                                 if (litval)
8552                                         emitpcode(POC_IORLW,popGetLit(litval));
8553                         }
8554         }
8555                 else
8556         {
8557                         if (blen==1) {
8558                                 if (p_type == -1) {
8559                                         /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
8560                                         emitpcode(POC_RLF,popGet(AOP(right),0));
8561                                         emitSKPC;
8562                                         emitpcode(POC_BCF,popGet(AOP(result),0));
8563                                         emitSKPNC;
8564                                         emitpcode(POC_BSF,popGet(AOP(result),0));
8565                                 } else if (p_type!=GPOINTER) {
8566                                         /* Case with a bitfield length == 1 and no generic pointer
8567                                         */
8568                                         if (AOP_TYPE (right) == AOP_CRY)
8569                                                 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8570                                         else
8571                                         {
8572                                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8573                                                 pic14_emitcode ("rrc","a");
8574                                         }
8575                                         emitPtrByteGet (rname, p_type, FALSE);
8576                                         pic14_emitcode ("mov","acc.%d,c",bstr);
8577                                 }
8578             }
8579                         else
8580             {
8581                                 //bool pushedB;
8582                                 /* Case with a bitfield length < 8 and arbitrary source
8583                                 */
8584                                 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8585                                 /* shift and mask source value */
8586                                 AccLsh (right,0,bstr);
8587                                 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8588                                 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8589                                 
8590                                 //pushedB = pushB ();
8591                                 if (p_type == -1)
8592                                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8593                                 else
8594                                         emitPtrByteGet (rname, p_type, TRUE);
8595                                 
8596                                 pic14_emitcode ("anl", "a,#0x%02x", mask);
8597                                 pic14_emitcode ("orl", "a,b");
8598                                 emitpcode(POC_ANDLW,popGetLit(mask));
8599                                 emitpcode(POC_IORFW,popGet(AOP(right),0));
8600                                 if (p_type == GPOINTER)
8601                                         pic14_emitcode ("pop", "b");
8602                                 
8603                                 //popB (pushedB);
8604                         }
8605         }
8606                 
8607                 if (p_type == -1)
8608                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8609                 else
8610                         emitPtrByteSet (rname, p_type, "a");
8611                 return;
8612     }
8613         
8614         /* Bit length is greater than 7 bits. In this case, copy  */
8615         /* all except the partial byte at the end                 */
8616         for (rlen=blen;rlen>=8;rlen-=8)
8617     {
8618                 emitPtrByteSet (rname, p_type,
8619                         aopGet (AOP (right), offset++, FALSE, TRUE) );
8620                 if (rlen>8)
8621                         pic14_emitcode ("inc", "%s", rname);
8622     }
8623         
8624         /* If there was a partial byte at the end */
8625         if (rlen)
8626     {
8627                 mask = (((unsigned char) -1 << rlen) & 0xff);
8628                 
8629                 if (AOP_TYPE (right) == AOP_LIT)
8630         {
8631                 /* Case with partial byte and literal source
8632                         */
8633                         litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8634                         litval >>= (blen-rlen);
8635                         litval &= (~mask) & 0xff;
8636                         emitPtrByteGet (rname, p_type, FALSE);
8637                         if ((mask|litval)!=0xff)
8638                                 pic14_emitcode ("anl","a,#0x%02x", mask);
8639                         if (litval)
8640                                 pic14_emitcode ("orl","a,#0x%02x", litval);
8641         }
8642                 else
8643         {
8644                         //bool pushedB;
8645                         /* Case with partial byte and arbitrary source
8646                         */
8647                         MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8648                         pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8649                         
8650                         //pushedB = pushB ();
8651                         /* transfer A to B and get next byte */
8652                         emitPtrByteGet (rname, p_type, TRUE);
8653                         
8654                         pic14_emitcode ("anl", "a,#0x%02x", mask);
8655                         pic14_emitcode ("orl", "a,b");
8656                         if (p_type == GPOINTER)
8657                                 pic14_emitcode ("pop", "b");
8658                         
8659                         //popB (pushedB);
8660         }
8661                 emitPtrByteSet (rname, p_type, "a");
8662     }
8663         
8664 }
8665
8666 /*-----------------------------------------------------------------*/
8667 /* SetIrp - Set IRP bit                                            */
8668 /*-----------------------------------------------------------------*/
8669 void SetIrp(operand *result) {
8670         if (AOP_TYPE(result) == AOP_LIT) {
8671                 unsigned lit = (unsigned)operandLitValue(result);
8672                 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8673         } else {
8674                 if (PCOP(AOP(result))->type == PO_LITERAL) {
8675                         int addrs = PCOL(AOP(result))->lit;
8676                         emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8677                 } else {
8678                         emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8679                         if(AOP_SIZE(result) > 1) {
8680                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8681                                 emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8682                         }
8683                 }
8684         }
8685 }
8686
8687 /*-----------------------------------------------------------------*/
8688 /* genDataPointerSet - remat pointer to data space                 */
8689 /*-----------------------------------------------------------------*/
8690 static void genDataPointerSet(operand *right,
8691                                                           operand *result,
8692                                                           iCode *ic)
8693 {
8694         int size, offset = 0 ;
8695         char *l, buffer[256];
8696         
8697         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8698         aopOp(right,ic,FALSE);
8699         
8700         l = aopGet(AOP(result),0,FALSE,TRUE);
8701         size = AOP_SIZE(right);
8702         /*
8703         if ( AOP_TYPE(result) == AOP_PCODE) {
8704         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8705         AOP(result)->aopu.pcop->name,
8706         PCOI(AOP(result)->aopu.pcop)->offset);
8707         }
8708         */
8709         
8710         // tsd, was l+1 - the underline `_' prefix was being stripped
8711         while (size--) {
8712                 if (offset) {
8713                         sprintf(buffer,"(%s + %d)",l,offset);
8714                         fprintf(stderr,"oops  %s\n",buffer);
8715                 } else
8716                         sprintf(buffer,"%s",l);
8717                 
8718                 if (AOP_TYPE(right) == AOP_LIT) {
8719                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8720                         lit = lit >> (8*offset);
8721                         if(lit&0xff) {
8722                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8723                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8724                         } else {
8725                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8726                         }
8727                 } else {
8728                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8729                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8730                 }
8731                 
8732                 offset++;
8733         }
8734         
8735         freeAsmop(right,NULL,ic,TRUE);
8736         freeAsmop(result,NULL,ic,TRUE);
8737 }
8738
8739 /*-----------------------------------------------------------------*/
8740 /* genNearPointerSet - pic14_emitcode for near pointer put         */
8741 /*-----------------------------------------------------------------*/
8742 static void genNearPointerSet (operand *right,
8743                                                            operand *result, 
8744                                                            iCode *ic)
8745 {
8746         asmop *aop = NULL;
8747         sym_link *ptype = operandType(result);
8748         sym_link *retype = getSpec(operandType(right));
8749         sym_link *letype = getSpec(ptype);
8750         int direct = 0;
8751         
8752         
8753         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8754         aopOp(result,ic,FALSE);
8755         
8756         
8757         /* if the result is rematerializable &
8758         in data space & not a bit variable */
8759         //if (AOP_TYPE(result) == AOP_IMMD &&
8760         if (AOP_TYPE(result) == AOP_PCODE &&
8761                 DCL_TYPE(ptype) == POINTER   &&
8762                 !IS_BITVAR (retype) &&
8763                 !IS_BITVAR (letype)) {
8764                 genDataPointerSet (right,result,ic);
8765                 freeAsmop(result,NULL,ic,TRUE);
8766                 return;
8767         }
8768
8769         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8770         aopOp(right,ic,FALSE);
8771         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8772         
8773         /* Check if can access directly instead of via a pointer */
8774         if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8775                 direct = 1;
8776         }
8777
8778         /* If the pointer value is not in a the FSR then need to put it in */
8779         if (!AOP_INPREG(AOP(result)) && !direct) {
8780                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8781                 if (PCOP(AOP(result))->type == PO_LITERAL) 
8782                         emitpcode(POC_MOVLW, popGet(AOP(result),0));
8783                 else
8784                         emitpcode(POC_MOVFW, popGet(AOP(result),0));
8785                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8786         }
8787
8788         /* Must set/reset IRP bit for use with FSR. */
8789         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8790         if (!direct)
8791                 SetIrp(result);
8792
8793         /* if bitfield then unpack the bits */
8794         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8795                 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8796         } else {
8797                 /* we have can just get the values */
8798                 int size = AOP_SIZE(right);
8799                 int offset = 0 ;    
8800                 
8801                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8802                 while (size--) {
8803                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8804                         if (*l == '@' ) {
8805                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8806                         } else {
8807                                 if (AOP_TYPE(right) == AOP_LIT) {
8808                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
8809                                 } else {
8810                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
8811                                 }
8812                                 if (direct)
8813                                         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8814                                 else
8815                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8816                         }
8817                         if (size && !direct)
8818                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8819                         offset++;
8820                 }
8821         }
8822         
8823         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8824         /* now some housekeeping stuff */
8825         if (aop) {
8826                 /* we had to allocate for this iCode */
8827                 freeAsmop(NULL,aop,ic,TRUE);
8828         } else { 
8829                 /* we did not allocate which means left
8830                 already in a pointer register, then
8831                 if size > 0 && this could be used again
8832                 we have to point it back to where it 
8833                 belongs */
8834                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8835                 if (AOP_SIZE(right) > 1 &&
8836                         !OP_SYMBOL(result)->remat &&
8837                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8838                         ic->depth )) {
8839                         int size = AOP_SIZE(right) - 1;
8840                         while (size--)
8841                                 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8842                 }
8843         }
8844         
8845         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8846         /* done */
8847
8848         freeAsmop(right,NULL,ic,TRUE);
8849         freeAsmop(result,NULL,ic,TRUE);
8850 }
8851
8852 /*-----------------------------------------------------------------*/
8853 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8854 /*-----------------------------------------------------------------*/
8855 static void genPagedPointerSet (operand *right,
8856                                                                 operand *result, 
8857                                                                 iCode *ic)
8858 {
8859         asmop *aop = NULL;
8860         regs *preg = NULL ;
8861         char *rname , *l;
8862         sym_link *retype;
8863         
8864         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8865         
8866         retype= getSpec(operandType(right));
8867         
8868         aopOp(result,ic,FALSE);
8869         
8870         /* if the value is already in a pointer register
8871         then don't need anything more */
8872         if (!AOP_INPREG(AOP(result))) {
8873                 /* otherwise get a free pointer register */
8874                 aop = newAsmop(0);
8875                 preg = getFreePtr(ic,&aop,FALSE);
8876                 pic14_emitcode("mov","%s,%s",
8877                         preg->name,
8878                         aopGet(AOP(result),0,FALSE,TRUE));
8879                 rname = preg->name ;
8880         } else
8881                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8882         
8883         freeAsmop(result,NULL,ic,TRUE);
8884         aopOp (right,ic,FALSE);
8885         
8886         /* if bitfield then unpack the bits */
8887         if (IS_BITFIELD(retype)) 
8888                 genPackBits (retype,result,right,rname,PPOINTER);
8889         else {
8890                 /* we have can just get the values */
8891                 int size = AOP_SIZE(right);
8892                 int offset = 0 ;  
8893                 
8894                 while (size--) {
8895                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8896                         
8897                         MOVA(l);
8898                         pic14_emitcode("movx","@%s,a",rname);
8899                         
8900                         if (size)
8901                                 pic14_emitcode("inc","%s",rname);
8902                         
8903                         offset++;
8904                 }
8905         }
8906         
8907         /* now some housekeeping stuff */
8908         if (aop) {
8909                 /* we had to allocate for this iCode */
8910                 freeAsmop(NULL,aop,ic,TRUE);
8911         } else { 
8912         /* we did not allocate which means left
8913         already in a pointer register, then
8914         if size > 0 && this could be used again
8915         we have to point it back to where it 
8916                 belongs */
8917                 if (AOP_SIZE(right) > 1 &&
8918                         !OP_SYMBOL(result)->remat &&
8919                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8920                         ic->depth )) {
8921                         int size = AOP_SIZE(right) - 1;
8922                         while (size--)
8923                                 pic14_emitcode("dec","%s",rname);
8924                 }
8925         }
8926         
8927         /* done */
8928         freeAsmop(right,NULL,ic,TRUE);
8929         
8930         
8931 }
8932
8933 /*-----------------------------------------------------------------*/
8934 /* genFarPointerSet - set value from far space                     */
8935 /*-----------------------------------------------------------------*/
8936 static void genFarPointerSet (operand *right,
8937                                                           operand *result, iCode *ic)
8938 {
8939         int size, offset ;
8940         sym_link *retype = getSpec(operandType(right));
8941         
8942         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8943         aopOp(result,ic,FALSE);
8944         
8945         /* if the operand is already in dptr 
8946         then we do nothing else we move the value to dptr */
8947         if (AOP_TYPE(result) != AOP_STR) {
8948                 /* if this is remateriazable */
8949                 if (AOP_TYPE(result) == AOP_IMMD)
8950                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8951                 else { /* we need to get it byte by byte */
8952                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8953                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8954                         if (options.model == MODEL_FLAT24)
8955                         {
8956                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8957                         }
8958                 }
8959         }
8960         /* so dptr know contains the address */
8961         freeAsmop(result,NULL,ic,TRUE);
8962         aopOp(right,ic,FALSE);
8963         
8964         /* if bit then unpack */
8965         if (IS_BITFIELD(retype)) 
8966                 genPackBits(retype,result,right,"dptr",FPOINTER);
8967         else {
8968                 size = AOP_SIZE(right);
8969                 offset = 0 ;
8970                 
8971                 while (size--) {
8972                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8973                         MOVA(l);
8974                         pic14_emitcode("movx","@dptr,a");
8975                         if (size)
8976                                 pic14_emitcode("inc","dptr");
8977                 }
8978         }
8979         
8980         freeAsmop(right,NULL,ic,TRUE);
8981 }
8982
8983 /*-----------------------------------------------------------------*/
8984 /* genGenPointerSet - set value from generic pointer space         */
8985 /*-----------------------------------------------------------------*/
8986 static void genGenPointerSet (operand *right,
8987                                                           operand *result, iCode *ic)
8988 {
8989         sym_link *ptype = operandType(result);
8990         sym_link *retype = getSpec(operandType(right));
8991         sym_link *letype = getSpec (ptype);
8992         
8993         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8994         
8995         aopOp(result,ic,FALSE);
8996         aopOp(right,ic,FALSE);
8997         
8998         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8999         
9000         /* if the operand is already in dptr 
9001         then we do nothing else we move the value to dptr */
9002         if (AOP_TYPE(result) != AOP_STR) {
9003                 /* if this is remateriazable */
9004                 if (AOP_TYPE(result) == AOP_IMMD) {
9005                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9006                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9007                 }
9008                 else {
9009                         emitpcode(POC_MOVFW,popGet(AOP(result),0));
9010                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9011
9012                         /* Must set/reset IRP bit for use with FSR. */
9013                         /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9014                         SetIrp(result);
9015                 }
9016         }
9017
9018         /* if bitfield then unpack the bits */
9019         if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9020                 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9021         } else {
9022                 /* we have can just get the values */
9023                 int size = AOP_SIZE(right);
9024                 int offset = 0 ;    
9025                 
9026                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9027                 while (size--) {
9028                         char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9029                         if (*l == '@' ) {
9030                                 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9031                         } else {
9032                                 if (AOP_TYPE(right) == AOP_LIT) {
9033                                         emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9034                                 } else {
9035                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9036                                 }
9037                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9038                         }
9039                         if (size)
9040                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9041                         offset++;
9042                 }
9043         }
9044         
9045         freeAsmop(right,NULL,ic,TRUE);
9046         freeAsmop(result,NULL,ic,TRUE);
9047 }
9048
9049 /*-----------------------------------------------------------------*/
9050 /* genPointerSet - stores the value into a pointer location        */
9051 /*-----------------------------------------------------------------*/
9052 static void genPointerSet (iCode *ic)
9053 {    
9054         operand *right, *result ;
9055         sym_link *type, *etype;
9056         int p_type;
9057         
9058         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9059         
9060         right = IC_RIGHT(ic);
9061         result = IC_RESULT(ic) ;
9062         
9063         /* depending on the type of pointer we need to
9064         move it to the correct pointer register */
9065         type = operandType(result);
9066         etype = getSpec(type);
9067         /* if left is of type of pointer then it is simple */
9068         if (IS_PTR(type) && !IS_FUNC(type->next)) {
9069                 p_type = DCL_TYPE(type);
9070         }
9071         else {
9072                 /* we have to go by the storage class */
9073                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9074                 
9075                 /*  if (SPEC_OCLS(etype)->codesp ) { */
9076                 /*      p_type = CPOINTER ;  */
9077                 /*  } */
9078                 /*  else */
9079                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9080                 /*    p_type = FPOINTER ; */
9081                 /*      else */
9082                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9083                 /*        p_type = PPOINTER ; */
9084                 /*    else */
9085                 /*        if (SPEC_OCLS(etype) == idata ) */
9086                 /*      p_type = IPOINTER ; */
9087                 /*        else */
9088                 /*      p_type = POINTER ; */
9089         }
9090         
9091         /* now that we have the pointer type we assign
9092         the pointer values */
9093         switch (p_type) {
9094                 
9095         case POINTER:
9096         case IPOINTER:
9097                 genNearPointerSet (right,result,ic);
9098                 break;
9099                 
9100         case PPOINTER:
9101                 genPagedPointerSet (right,result,ic);
9102                 break;
9103                 
9104         case FPOINTER:
9105                 genFarPointerSet (right,result,ic);
9106                 break;
9107                 
9108         case GPOINTER:
9109                 genGenPointerSet (right,result,ic);
9110                 break;
9111                 
9112         default:
9113                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9114                         "genPointerSet: illegal pointer type");
9115         }
9116 }
9117
9118 /*-----------------------------------------------------------------*/
9119 /* genIfx - generate code for Ifx statement                        */
9120 /*-----------------------------------------------------------------*/
9121 static void genIfx (iCode *ic, iCode *popIc)
9122 {
9123         operand *cond = IC_COND(ic);
9124         int isbit =0;
9125         
9126         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9127         
9128         aopOp(cond,ic,FALSE);
9129         
9130         /* get the value into acc */
9131         if (AOP_TYPE(cond) != AOP_CRY)
9132                 pic14_toBoolean(cond);
9133         else
9134                 isbit = 1;
9135         /* the result is now in the accumulator */
9136         freeAsmop(cond,NULL,ic,TRUE);
9137         
9138         /* if there was something to be popped then do it */
9139         if (popIc)
9140                 genIpop(popIc);
9141         
9142         /* if the condition is  a bit variable */
9143         if (isbit && IS_ITEMP(cond) && 
9144                 SPIL_LOC(cond)) {
9145                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9146                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9147         }
9148         else {
9149                 if (isbit && !IS_ITEMP(cond))
9150                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9151                 else
9152                         genIfxJump(ic,"a");
9153         }
9154         ic->generated = 1;
9155         
9156 }
9157
9158 /*-----------------------------------------------------------------*/
9159 /* genAddrOf - generates code for address of                       */
9160 /*-----------------------------------------------------------------*/
9161 static void genAddrOf (iCode *ic)
9162 {
9163         operand *right, *result, *left;
9164         int size, offset ;
9165         
9166         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9167         
9168         
9169         //aopOp(IC_RESULT(ic),ic,FALSE);
9170         
9171         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9172         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9173         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9174         
9175         DEBUGpic14_AopType(__LINE__,left,right,result);
9176         
9177         size = AOP_SIZE(IC_RESULT(ic));
9178         offset = 0;
9179         
9180         while (size--) {
9181                 /* fixing bug #863624, reported from (errolv) */
9182                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9183                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9184                 
9185 #if 0
9186                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9187                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9188 #endif
9189                 offset++;
9190         }
9191         
9192         freeAsmop(left,NULL,ic,FALSE);
9193         freeAsmop(result,NULL,ic,TRUE);
9194         
9195 }
9196
9197 #if 0
9198 /*-----------------------------------------------------------------*/
9199 /* genFarFarAssign - assignment when both are in far space         */
9200 /*-----------------------------------------------------------------*/
9201 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9202 {
9203         int size = AOP_SIZE(right);
9204         int offset = 0;
9205         char *l ;
9206         /* first push the right side on to the stack */
9207         while (size--) {
9208                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9209                 MOVA(l);
9210                 pic14_emitcode ("push","acc");
9211         }
9212         
9213         freeAsmop(right,NULL,ic,FALSE);
9214         /* now assign DPTR to result */
9215         aopOp(result,ic,FALSE);
9216         size = AOP_SIZE(result);
9217         while (size--) {
9218                 pic14_emitcode ("pop","acc");
9219                 aopPut(AOP(result),"a",--offset);
9220         }
9221         freeAsmop(result,NULL,ic,FALSE);
9222         
9223 }
9224 #endif
9225
9226 /*-----------------------------------------------------------------*/
9227 /* genAssign - generate code for assignment                        */
9228 /*-----------------------------------------------------------------*/
9229 static void genAssign (iCode *ic)
9230 {
9231         operand *result, *right;
9232         int size, offset,know_W;
9233         unsigned long lit = 0L;
9234         
9235         result = IC_RESULT(ic);
9236         right  = IC_RIGHT(ic) ;
9237         
9238         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9239         
9240         /* if they are the same */
9241         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9242                 return ;
9243         
9244         aopOp(right,ic,FALSE);
9245         aopOp(result,ic,TRUE);
9246         
9247         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9248         
9249         /* if they are the same registers */
9250         if (pic14_sameRegs(AOP(right),AOP(result)))
9251                 goto release;
9252         
9253         /* if the result is a bit */
9254         if (AOP_TYPE(result) == AOP_CRY) {
9255                 
9256         /* if the right size is a literal then
9257                 we know what the value is */
9258                 if (AOP_TYPE(right) == AOP_LIT) {
9259                         
9260                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9261                                 popGet(AOP(result),0));
9262                         
9263                         if (((int) operandLitValue(right))) 
9264                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9265                                 AOP(result)->aopu.aop_dir,
9266                                 AOP(result)->aopu.aop_dir);
9267                         else
9268                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9269                                 AOP(result)->aopu.aop_dir,
9270                                 AOP(result)->aopu.aop_dir);
9271                         goto release;
9272                 }
9273                 
9274                 /* the right is also a bit variable */
9275                 if (AOP_TYPE(right) == AOP_CRY) {
9276                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9277                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9278                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9279                         
9280                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9281                                 AOP(result)->aopu.aop_dir,
9282                                 AOP(result)->aopu.aop_dir);
9283                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9284                                 AOP(right)->aopu.aop_dir,
9285                                 AOP(right)->aopu.aop_dir);
9286                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9287                                 AOP(result)->aopu.aop_dir,
9288                                 AOP(result)->aopu.aop_dir);
9289                         goto release ;
9290                 }
9291                 
9292                 /* we need to or */
9293                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9294                 pic14_toBoolean(right);
9295                 emitSKPZ;
9296                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9297                 //aopPut(AOP(result),"a",0);
9298                 goto release ;
9299         }
9300         
9301         /* bit variables done */
9302         /* general case */
9303         size = AOP_SIZE(result);
9304         offset = 0 ;
9305         if(AOP_TYPE(right) == AOP_LIT)
9306                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9307         
9308         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9309                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9310                 if(aopIdx(AOP(result),0) == 4) {
9311                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9312                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9313                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9314                         goto release;
9315                 } else
9316                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9317         }
9318         
9319         know_W=-1;
9320         while (size--) {
9321                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9322                 if(AOP_TYPE(right) == AOP_LIT) {
9323                         if(lit&0xff) {
9324                                 if(know_W != (int)(lit&0xff))
9325                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9326                                 know_W = lit&0xff;
9327                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9328                         } else
9329                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9330                         
9331                         lit >>= 8;
9332                         
9333                 } else if (AOP_TYPE(right) == AOP_CRY) {
9334                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9335                         if(offset == 0) {
9336                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9337                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9338                         }
9339                 } else {
9340                         mov2w (AOP(right), offset);
9341                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9342                 }
9343                 
9344                 offset++;
9345         }
9346         
9347         
9348 release:
9349         freeAsmop (right,NULL,ic,FALSE);
9350         freeAsmop (result,NULL,ic,TRUE);
9351 }   
9352
9353 /*-----------------------------------------------------------------*/
9354 /* genJumpTab - genrates code for jump table                       */
9355 /*-----------------------------------------------------------------*/
9356 static void genJumpTab (iCode *ic)
9357 {
9358         symbol *jtab;
9359         char *l;
9360         
9361         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9362         
9363         aopOp(IC_JTCOND(ic),ic,FALSE);
9364         /* get the condition into accumulator */
9365         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9366         MOVA(l);
9367         /* multiply by three */
9368         pic14_emitcode("add","a,acc");
9369         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9370         
9371         jtab = newiTempLabel(NULL);
9372         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9373         pic14_emitcode("jmp","@a+dptr");
9374         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9375         
9376         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9377         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9378         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9379         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9380         emitSKPNC;
9381         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9382         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9383         emitpLabel(jtab->key);
9384         
9385         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9386         
9387         /* now generate the jump labels */
9388         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9389         jtab = setNextItem(IC_JTLABELS(ic))) {
9390                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9391                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9392                 
9393         }
9394         
9395 }
9396
9397 /*-----------------------------------------------------------------*/
9398 /* genMixedOperation - gen code for operators between mixed types  */
9399 /*-----------------------------------------------------------------*/
9400 /*
9401 TSD - Written for the PIC port - but this unfortunately is buggy.
9402 This routine is good in that it is able to efficiently promote 
9403 types to different (larger) sizes. Unfortunately, the temporary
9404 variables that are optimized out by this routine are sometimes
9405 used in other places. So until I know how to really parse the 
9406 iCode tree, I'm going to not be using this routine :(.
9407 */
9408 static int genMixedOperation (iCode *ic)
9409 {
9410 #if 0
9411         operand *result = IC_RESULT(ic);
9412         sym_link *ctype = operandType(IC_LEFT(ic));
9413         operand *right = IC_RIGHT(ic);
9414         int ret = 0;
9415         int big,small;
9416         int offset;
9417         
9418         iCode *nextic;
9419         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9420         
9421         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9422         
9423         nextic = ic->next;
9424         if(!nextic)
9425                 return 0;
9426         
9427         nextright = IC_RIGHT(nextic);
9428         nextleft  = IC_LEFT(nextic);
9429         nextresult = IC_RESULT(nextic);
9430         
9431         aopOp(right,ic,FALSE);
9432         aopOp(result,ic,FALSE);
9433         aopOp(nextright,  nextic, FALSE);
9434         aopOp(nextleft,   nextic, FALSE);
9435         aopOp(nextresult, nextic, FALSE);
9436         
9437         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9438                 
9439                 operand *t = right;
9440                 right = nextright;
9441                 nextright = t; 
9442                 
9443                 pic14_emitcode(";remove right +","");
9444                 
9445         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9446         /*
9447         operand *t = right;
9448         right = nextleft;
9449         nextleft = t; 
9450                 */
9451                 pic14_emitcode(";remove left +","");
9452         } else
9453                 return 0;
9454         
9455         big = AOP_SIZE(nextleft);
9456         small = AOP_SIZE(nextright);
9457         
9458         switch(nextic->op) {
9459                 
9460         case '+':
9461                 pic14_emitcode(";optimize a +","");
9462                 /* if unsigned or not an integral type */
9463                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9464                         pic14_emitcode(";add a bit to something","");
9465                 } else {
9466                         
9467                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9468                         
9469                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9470                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9471                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9472                         } else
9473                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9474                         
9475                         offset = 0;
9476                         while(--big) {
9477                                 
9478                                 offset++;
9479                                 
9480                                 if(--small) {
9481                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9482                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9483                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9484                                         }
9485                                         
9486                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9487                                         emitSKPNC;
9488                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9489                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9490                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9491                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9492                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9493                                         
9494                                 } else {
9495                                         pic14_emitcode("rlf","known_zero,w");
9496                                         
9497                                         /*
9498                                         if right is signed
9499                                         btfsc  right,7
9500                                         addlw ff
9501                                         */
9502                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9503                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9504                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9505                                         } else {
9506                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9507                                         }
9508                                 }
9509                         }
9510                         ret = 1;
9511                 }
9512         }
9513         ret = 1;
9514         
9515 release:
9516         freeAsmop(right,NULL,ic,TRUE);
9517         freeAsmop(result,NULL,ic,TRUE);
9518         freeAsmop(nextright,NULL,ic,TRUE);
9519         freeAsmop(nextleft,NULL,ic,TRUE);
9520         if(ret)
9521                 nextic->generated = 1;
9522         
9523         return ret;
9524 #else
9525         return 0;
9526 #endif
9527 }
9528 /*-----------------------------------------------------------------*/
9529 /* genCast - gen code for casting                                  */
9530 /*-----------------------------------------------------------------*/
9531 static void genCast (iCode *ic)
9532 {
9533         operand *result = IC_RESULT(ic);
9534         sym_link *ctype = operandType(IC_LEFT(ic));
9535         sym_link *rtype = operandType(IC_RIGHT(ic));
9536         operand *right = IC_RIGHT(ic);
9537         int size, offset ;
9538         
9539         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9540         /* if they are equivalent then do nothing */
9541         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9542                 return ;
9543         
9544         aopOp(right,ic,FALSE) ;
9545         aopOp(result,ic,FALSE);
9546         
9547         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9548         
9549         /* if the result is a bit */
9550         if (AOP_TYPE(result) == AOP_CRY) {
9551         /* if the right size is a literal then
9552                 we know what the value is */
9553                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9554                 if (AOP_TYPE(right) == AOP_LIT) {
9555                         
9556                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9557                                 popGet(AOP(result),0));
9558                         
9559                         if (((int) operandLitValue(right))) 
9560                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9561                                 AOP(result)->aopu.aop_dir,
9562                                 AOP(result)->aopu.aop_dir);
9563                         else
9564                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9565                                 AOP(result)->aopu.aop_dir,
9566                                 AOP(result)->aopu.aop_dir);
9567                         
9568                         goto release;
9569                 }
9570                 
9571                 /* the right is also a bit variable */
9572                 if (AOP_TYPE(right) == AOP_CRY) {
9573                         
9574                         emitCLRC;
9575                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9576                         
9577                         pic14_emitcode("clrc","");
9578                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9579                                 AOP(right)->aopu.aop_dir,
9580                                 AOP(right)->aopu.aop_dir);
9581                         aopPut(AOP(result),"c",0);
9582                         goto release ;
9583                 }
9584                 
9585                 /* we need to or */
9586                 if (AOP_TYPE(right) == AOP_REG) {
9587                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9588                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9589                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9590                 }
9591                 pic14_toBoolean(right);
9592                 aopPut(AOP(result),"a",0);
9593                 goto release ;
9594         }
9595         
9596         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9597                 int offset = 1;
9598                 size = AOP_SIZE(result);
9599                 
9600                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9601                 
9602                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9603                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9604                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9605                 
9606                 while (size--)
9607                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9608                 
9609                 goto release;
9610         }
9611         
9612         /* if they are the same size : or less */
9613         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9614                 
9615                 /* if they are in the same place */
9616                 if (pic14_sameRegs(AOP(right),AOP(result)))
9617                         goto release;
9618                 
9619                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9620                 if (IS_PTR_CONST(rtype))
9621                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9622                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9623                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9624                 
9625                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9626                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9627                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9628                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9629                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9630                         if(AOP_SIZE(result) <2)
9631                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9632                         
9633                 } else {
9634                         
9635                         /* if they in different places then copy */
9636                         size = AOP_SIZE(result);
9637                         offset = 0 ;
9638                         while (size--) {
9639                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9640                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9641                                 
9642                                 //aopPut(AOP(result),
9643                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9644                                 // offset);
9645                                 
9646                                 offset++;
9647                         }
9648                 }
9649                 goto release;
9650         }
9651         
9652         
9653         /* if the result is of type pointer */
9654         if (IS_PTR(ctype)) {
9655                 
9656                 int p_type;
9657                 sym_link *type = operandType(right);
9658                 sym_link *etype = getSpec(type);
9659                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9660                 
9661                 /* pointer to generic pointer */
9662                 if (IS_GENPTR(ctype)) {
9663                         char *l = zero;
9664                         
9665                         if (IS_PTR(type)) 
9666                                 p_type = DCL_TYPE(type);
9667                         else {
9668                                 /* we have to go by the storage class */
9669                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9670                                 
9671                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9672                                 /*        p_type = CPOINTER ;  */
9673                                 /*    else */
9674                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9675                                 /*      p_type = FPOINTER ; */
9676                                 /*        else */
9677                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9678                                 /*          p_type = PPOINTER; */
9679                                 /*      else */
9680                                 /*          if (SPEC_OCLS(etype) == idata ) */
9681                                 /*        p_type = IPOINTER ; */
9682                                 /*          else */
9683                                 /*        p_type = POINTER ; */
9684                         }
9685                         
9686                         /* the first two bytes are known */
9687                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9688                         size = GPTRSIZE - 1; 
9689                         offset = 0 ;
9690                         while (size--) {
9691                                 if(offset < AOP_SIZE(right)) {
9692                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9693                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9694                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9695                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9696                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9697                                         } else { 
9698                                                 aopPut(AOP(result),
9699                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9700                                                         offset);
9701                                         }
9702                                 } else 
9703                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9704                                 offset++;
9705                         }
9706                         /* the last byte depending on type */
9707                         switch (p_type) {
9708                         case IPOINTER:
9709                         case POINTER:
9710                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9711                                 break;
9712                         case FPOINTER:
9713                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9714                                 l = one;
9715                                 break;
9716                         case CPOINTER:
9717                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9718                                 l = "#0x02";
9719                                 break;        
9720                         case PPOINTER:
9721                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9722                                 l = "#0x03";
9723                                 break;
9724                                 
9725                         default:
9726                                 /* this should never happen */
9727                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9728                                         "got unknown pointer type");
9729                                 exit(1);
9730                         }
9731                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9732                         goto release ;
9733                 }
9734                 
9735                 /* just copy the pointers */
9736                 size = AOP_SIZE(result);
9737                 offset = 0 ;
9738                 while (size--) {
9739                         aopPut(AOP(result),
9740                                 aopGet(AOP(right),offset,FALSE,FALSE),
9741                                 offset);
9742                         offset++;
9743                 }
9744                 goto release ;
9745         }
9746         
9747         
9748         
9749         /* so we now know that the size of destination is greater
9750         than the size of the source.
9751         Now, if the next iCode is an operator then we might be
9752         able to optimize the operation without performing a cast.
9753         */
9754         if(genMixedOperation(ic))
9755                 goto release;
9756         
9757         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9758         
9759         /* we move to result for the size of source */
9760         size = AOP_SIZE(right);
9761         offset = 0 ;
9762         while (size--) {
9763                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9764                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9765                 offset++;
9766         }
9767         
9768         /* now depending on the sign of the destination */
9769         size = AOP_SIZE(result) - AOP_SIZE(right);
9770         /* if unsigned or not an integral type */
9771         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9772                 while (size--)
9773                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9774         } else {
9775                 /* we need to extend the sign :{ */
9776                 
9777                 if(size == 1) {
9778                         /* Save one instruction of casting char to int */
9779                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9780                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9781                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9782                 } else {
9783                         emitpcodeNULLop(POC_CLRW);
9784                         
9785                         if(offset)
9786                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9787                         else
9788                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9789                         
9790                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9791                         
9792                         while (size--)
9793                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9794                 }
9795         }
9796         
9797 release:
9798         freeAsmop(right,NULL,ic,TRUE);
9799         freeAsmop(result,NULL,ic,TRUE);
9800         
9801 }
9802
9803 /*-----------------------------------------------------------------*/
9804 /* genDjnz - generate decrement & jump if not zero instrucion      */
9805 /*-----------------------------------------------------------------*/
9806 static int genDjnz (iCode *ic, iCode *ifx)
9807 {
9808         symbol *lbl, *lbl1;
9809         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9810         
9811         if (!ifx)
9812                 return 0;
9813         
9814                 /* if the if condition has a false label
9815         then we cannot save */
9816         if (IC_FALSE(ifx))
9817                 return 0;
9818         
9819                 /* if the minus is not of the form 
9820         a = a - 1 */
9821         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9822                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9823                 return 0;
9824         
9825         if (operandLitValue(IC_RIGHT(ic)) != 1)
9826                 return 0;
9827         
9828                 /* if the size of this greater than one then no
9829         saving */
9830         if (getSize(operandType(IC_RESULT(ic))) > 1)
9831                 return 0;
9832         
9833         /* otherwise we can save BIG */
9834         lbl = newiTempLabel(NULL);
9835         lbl1= newiTempLabel(NULL);
9836         
9837         aopOp(IC_RESULT(ic),ic,FALSE);
9838         
9839         if (IS_AOP_PREG(IC_RESULT(ic))) {
9840                 pic14_emitcode("dec","%s",
9841                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9842                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9844         } else {  
9845                 
9846                 
9847                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9848                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9849                 
9850                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9851                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9852                 
9853         }
9854         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9855         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9856         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9857         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9858         
9859         
9860         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9861         ifx->generated = 1;
9862         return 1;
9863 }
9864
9865 /*-----------------------------------------------------------------*/
9866 /* genReceive - generate code for a receive iCode                  */
9867 /*-----------------------------------------------------------------*/
9868 static void genReceive (iCode *ic)
9869 {
9870         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9871         
9872         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9873                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9874                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9875                 
9876                 int size = getSize(operandType(IC_RESULT(ic)));
9877                 int offset =  fReturnSizePic - size;
9878                 while (size--) {
9879                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9880                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9881                         offset++;
9882                 }
9883                 aopOp(IC_RESULT(ic),ic,FALSE);
9884                 size = AOP_SIZE(IC_RESULT(ic));
9885                 offset = 0;
9886                 while (size--) {
9887                         pic14_emitcode ("pop","acc");
9888                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9889                 }
9890                 
9891         } else {
9892                 _G.accInUse++;
9893                 aopOp(IC_RESULT(ic),ic,FALSE);
9894                 _G.accInUse--;
9895                 assignResultValue(IC_RESULT(ic));
9896         }
9897         
9898         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9899 }
9900
9901 /*-----------------------------------------------------------------*/
9902 /* genDummyRead - generate code for dummy read of volatiles        */
9903 /*-----------------------------------------------------------------*/
9904 static void
9905 genDummyRead (iCode * ic)
9906 {
9907         pic14_emitcode ("; genDummyRead","");
9908         pic14_emitcode ("; not implemented","");
9909         
9910         ic = ic;
9911 }
9912
9913 /*-----------------------------------------------------------------*/
9914 /* genpic14Code - generate code for pic14 based controllers        */
9915 /*-----------------------------------------------------------------*/
9916 /*
9917 * At this point, ralloc.c has gone through the iCode and attempted
9918 * to optimize in a way suitable for a PIC. Now we've got to generate
9919 * PIC instructions that correspond to the iCode.
9920 *
9921 * Once the instructions are generated, we'll pass through both the
9922 * peep hole optimizer and the pCode optimizer.
9923 *-----------------------------------------------------------------*/
9924
9925 void genpic14Code (iCode *lic)
9926 {
9927         iCode *ic;
9928         int cln = 0;
9929         
9930         lineHead = lineCurr = NULL;
9931         
9932         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9933         addpBlock(pb);
9934         
9935         /* if debug information required */
9936         if (options.debug && currFunc) { 
9937                 if (currFunc) {
9938                         debugFile->writeFunction (currFunc, lic);
9939                 }
9940         }
9941         
9942         
9943         for (ic = lic ; ic ; ic = ic->next ) {
9944                 
9945                 DEBUGpic14_emitcode(";ic","");
9946                 if ( cln != ic->lineno ) {
9947                         if ( options.debug ) {
9948                                 debugFile->writeCLine (ic);
9949                         }
9950                         /*
9951                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9952                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9953                         printCLine(ic->filename, ic->lineno));
9954                         */
9955                         if (!options.noCcodeInAsm) {
9956                                 addpCode2pBlock(pb,
9957                                         newpCodeCSource(ic->lineno, 
9958                                         ic->filename, 
9959                                         printCLine(ic->filename, ic->lineno)));
9960                         }
9961                         
9962                         cln = ic->lineno ;
9963                 }
9964                 
9965                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9966                 
9967                 /* if the result is marked as
9968                 spilt and rematerializable or code for
9969                 this has already been generated then
9970                 do nothing */
9971                 if (resultRemat(ic) || ic->generated ) 
9972                         continue ;
9973                 
9974                 /* depending on the operation */
9975                 switch (ic->op) {
9976                 case '!' :
9977                         genNot(ic);
9978                         break;
9979                         
9980                 case '~' :
9981                         genCpl(ic);
9982                         break;
9983                         
9984                 case UNARYMINUS:
9985                         genUminus (ic);
9986                         break;
9987                         
9988                 case IPUSH:
9989                         genIpush (ic);
9990                         break;
9991                         
9992                 case IPOP:
9993                         /* IPOP happens only when trying to restore a 
9994                         spilt live range, if there is an ifx statement
9995                         following this pop then the if statement might
9996                         be using some of the registers being popped which
9997                         would destory the contents of the register so
9998                         we need to check for this condition and handle it */
9999                         if (ic->next            && 
10000                                 ic->next->op == IFX &&
10001                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10002                                 genIfx (ic->next,ic);
10003                         else
10004                                 genIpop (ic);
10005                         break; 
10006                         
10007                 case CALL:
10008                         genCall (ic);
10009                         break;
10010                         
10011                 case PCALL:
10012                         genPcall (ic);
10013                         break;
10014                         
10015                 case FUNCTION:
10016                         genFunction (ic);
10017                         break;
10018                         
10019                 case ENDFUNCTION:
10020                         genEndFunction (ic);
10021                         break;
10022                         
10023                 case RETURN:
10024                         genRet (ic);
10025                         break;
10026                         
10027                 case LABEL:
10028                         genLabel (ic);
10029                         break;
10030                         
10031                 case GOTO:
10032                         genGoto (ic);
10033                         break;
10034                         
10035                 case '+' :
10036                         genPlus (ic) ;
10037                         break;
10038                         
10039                 case '-' :
10040                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10041                                 genMinus (ic);
10042                         break;
10043                         
10044                 case '*' :
10045                         genMult (ic);
10046                         break;
10047                         
10048                 case '/' :
10049                         genDiv (ic) ;
10050                         break;
10051                         
10052                 case '%' :
10053                         genMod (ic);
10054                         break;
10055                         
10056                 case '>' :
10057                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
10058                         break;
10059                         
10060                 case '<' :
10061                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10062                         break;
10063                         
10064                 case LE_OP:
10065                 case GE_OP:
10066                 case NE_OP:
10067                         
10068                         /* note these two are xlated by algebraic equivalence
10069                         during parsing SDCC.y */
10070                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10071                                 "got '>=' or '<=' shouldn't have come here");
10072                         break;  
10073                         
10074                 case EQ_OP:
10075                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10076                         break;      
10077                         
10078                 case AND_OP:
10079                         genAndOp (ic);
10080                         break;
10081                         
10082                 case OR_OP:
10083                         genOrOp (ic);
10084                         break;
10085                         
10086                 case '^' :
10087                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10088                         break;
10089                         
10090                 case '|' :
10091                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10092                         break;
10093                         
10094                 case BITWISEAND:
10095                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10096                         break;
10097                         
10098                 case INLINEASM:
10099                         genInline (ic);
10100                         break;
10101                         
10102                 case RRC:
10103                         genRRC (ic);
10104                         break;
10105                         
10106                 case RLC:
10107                         genRLC (ic);
10108                         break;
10109                         
10110                 case GETHBIT:
10111                         genGetHbit (ic);
10112                         break;
10113                         
10114                 case LEFT_OP:
10115                         genLeftShift (ic);
10116                         break;
10117                         
10118                 case RIGHT_OP:
10119                         genRightShift (ic);
10120                         break;
10121                         
10122                 case GET_VALUE_AT_ADDRESS:
10123                         genPointerGet(ic);
10124                         break;
10125                         
10126                 case '=' :
10127                         if (POINTER_SET(ic))
10128                                 genPointerSet(ic);
10129                         else
10130                                 genAssign(ic);
10131                         break;
10132                         
10133                 case IFX:
10134                         genIfx (ic,NULL);
10135                         break;
10136                         
10137                 case ADDRESS_OF:
10138                         genAddrOf (ic);
10139                         break;
10140                         
10141                 case JUMPTABLE:
10142                         genJumpTab (ic);
10143                         break;
10144                         
10145                 case CAST:
10146                         genCast (ic);
10147                         break;
10148                         
10149                 case RECEIVE:
10150                         genReceive(ic);
10151                         break;
10152                         
10153                 case SEND:
10154                         addSet(&_G.sendSet,ic);
10155                         break;
10156                         
10157                 case DUMMY_READ_VOLATILE:
10158                         genDummyRead (ic);
10159                         break;
10160                         
10161                 default :
10162                         ic = ic;
10163                 }
10164         }
10165
10166         
10167         /* now we are ready to call the
10168         peep hole optimizer */
10169         if (!options.nopeep) {
10170                 peepHole (&lineHead);
10171         }
10172         /* now do the actual printing */
10173         printLine (lineHead,codeOutFile);
10174         
10175 #ifdef PCODE_DEBUG
10176         DFPRINTF((stderr,"printing pBlock\n\n"));
10177         printpBlock(stdout,pb);
10178 #endif
10179         
10180         return;
10181 }