x = y >> 6; was failing if x and y were 16-bit ints
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
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 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
41 #else
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
51 #endif
52 #endif
53 #endif
54 #endif
55
56 #include "common.h"
57 #include "SDCCpeeph.h"
58 #include "ralloc.h"
59 #include "pcode.h"
60 #include "gen.h"
61
62
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
66 pCode *AssembleLine(char *line);
67 extern void printpBlock(FILE *of, pBlock *pb);
68
69 static int labelOffset=0;
70 extern int debug_verbose;
71 static int optimized_for_speed = 0;
72
73 /* max_key keeps track of the largest label number used in 
74    a function. This is then used to adjust the label offset
75    for the next function.
76 */
77 static int max_key=0;
78 static int GpsuedoStkPtr=0;
79
80 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
81 unsigned int pic14aopLiteral (value *val, int offset);
82 const char *AopType(short type);
83 static iCode *ifxForOp ( operand *op, iCode *ic );
84
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
86
87 /* this is the down and dirty file with all kinds of 
88    kludgy & hacky stuff. This is what it is all about
89    CODE GENERATION for a specific MCU . some of the
90    routines may be reusable, will have to see */
91
92 static char *zero = "#0x00";
93 static char *one  = "#0x01";
94 static char *spname = "sp";
95
96 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
97 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
98 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
99 static char **fReturn = fReturnpic14;
100
101 static char *accUse[] = {"a","b"};
102
103 //static short rbank = -1;
104
105 static struct {
106     short r0Pushed;
107     short r1Pushed;
108     short accInUse;
109     short inLine;
110     short debugLine;
111     short nRegsSaved;
112     set *sendSet;
113 } _G;
114
115 /* Resolved ifx structure. This structure stores information
116    about an iCode ifx that makes it easier to generate code.
117 */
118 typedef struct resolvedIfx {
119   symbol *lbl;     /* pointer to a label */
120   int condition;   /* true or false ifx */
121   int generated;   /* set true when the code associated with the ifx
122                     * is generated */
123 } resolvedIfx;
124
125 extern int pic14_ptrRegReq ;
126 extern int pic14_nRegs;
127 extern FILE *codeOutFile;
128 static void saverbank (int, iCode *,bool);
129
130 static lineNode *lineHead = NULL;
131 static lineNode *lineCurr = NULL;
132
133 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
134 0xE0, 0xC0, 0x80, 0x00};
135 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
136 0x07, 0x03, 0x01, 0x00};
137
138 static  pBlock *pb;
139
140 /*-----------------------------------------------------------------*/
141 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
142 /*                 exponent of 2 is returned, otherwise -1 is      */
143 /*                 returned.                                       */
144 /* note that this is similar to the function `powof2' in SDCCsymt  */
145 /* if(n == 2^y)                                                    */
146 /*   return y;                                                     */
147 /* return -1;                                                      */
148 /*-----------------------------------------------------------------*/
149 static int my_powof2 (unsigned long num)
150 {
151   if(num) {
152     if( (num & (num-1)) == 0) {
153       int nshifts = -1;
154       while(num) {
155         num>>=1;
156         nshifts++;
157       }
158       return nshifts;
159     }
160   }
161
162   return -1;
163 }
164
165 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 {
167
168   DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
169                        line_no,
170                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
171                        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
172                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
173                        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
174                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
175                        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
176                        ((result) ? AOP_SIZE(result) : 0));
177
178 }
179
180 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 {
182
183   DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
184                        line_no,
185                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
186                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
187                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
188                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
189                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
190                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
191
192 }
193
194 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 {
196     va_list ap;
197     char lb[INITIAL_INLINEASM];  
198     char *lbp = lb;
199
200     if(!debug_verbose)
201       return;
202
203     va_start(ap,fmt);   
204
205     if (inst && *inst) {
206         if (fmt && *fmt)
207             sprintf(lb,"%s\t",inst);
208         else
209             sprintf(lb,"%s",inst);
210         vsprintf(lb+(strlen(lb)),fmt,ap);
211     }  else
212         vsprintf(lb,fmt,ap);
213
214     while (isspace(*lbp)) lbp++;
215
216     if (lbp && *lbp) 
217         lineCurr = (lineCurr ?
218                     connectLine(lineCurr,newLineNode(lb)) :
219                     (lineHead = newLineNode(lb)));
220     lineCurr->isInline = _G.inLine;
221     lineCurr->isDebug  = _G.debugLine;
222
223     addpCode2pBlock(pb,newpCodeCharP(lb));
224
225     va_end(ap);
226 }
227
228
229 void emitpLabel(int key)
230 {
231   addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 }
233
234 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
235 {
236
237   if(pcop)
238     addpCode2pBlock(pb,newpCode(poc,pcop));
239   else
240     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
241 }
242
243 void emitpcodeNULLop(PIC_OPCODE poc)
244 {
245
246   addpCode2pBlock(pb,newpCode(poc,NULL));
247
248 }
249
250 /*-----------------------------------------------------------------*/
251 /* pic14_emitcode - writes the code into a file : for now it is simple    */
252 /*-----------------------------------------------------------------*/
253 void pic14_emitcode (char *inst,char *fmt, ...)
254 {
255     va_list ap;
256     char lb[INITIAL_INLINEASM];  
257     char *lbp = lb;
258
259     va_start(ap,fmt);   
260
261     if (inst && *inst) {
262         if (fmt && *fmt)
263             sprintf(lb,"%s\t",inst);
264         else
265             sprintf(lb,"%s",inst);
266         vsprintf(lb+(strlen(lb)),fmt,ap);
267     }  else
268         vsprintf(lb,fmt,ap);
269
270     while (isspace(*lbp)) lbp++;
271
272     if (lbp && *lbp) 
273         lineCurr = (lineCurr ?
274                     connectLine(lineCurr,newLineNode(lb)) :
275                     (lineHead = newLineNode(lb)));
276     lineCurr->isInline = _G.inLine;
277     lineCurr->isDebug  = _G.debugLine;
278
279     if(debug_verbose)
280       addpCode2pBlock(pb,newpCodeCharP(lb));
281
282     va_end(ap);
283 }
284
285
286 /*-----------------------------------------------------------------*/
287 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
288 /*-----------------------------------------------------------------*/
289 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
290 {
291     bool r0iu = FALSE , r1iu = FALSE;
292     bool r0ou = FALSE , r1ou = FALSE;
293
294     /* the logic: if r0 & r1 used in the instruction
295     then we are in trouble otherwise */
296
297     /* first check if r0 & r1 are used by this
298     instruction, in which case we are in trouble */
299     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
301     {
302         goto endOfWorld;      
303     }
304
305     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
307
308     /* if no usage of r0 then return it */
309     if (!r0iu && !r0ou) {
310         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311         (*aopp)->type = AOP_R0;
312         
313         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314     }
315
316     /* if no usage of r1 then return it */
317     if (!r1iu && !r1ou) {
318         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319         (*aopp)->type = AOP_R1;
320
321         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322     }    
323
324     /* now we know they both have usage */
325     /* if r0 not used in this instruction */
326     if (!r0iu) {
327         /* push it if not already pushed */
328         if (!_G.r0Pushed) {
329           //pic14_emitcode ("push","%s",
330           //          pic14_regWithIdx(R0_IDX)->dname);
331             _G.r0Pushed++ ;
332         }
333         
334         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335         (*aopp)->type = AOP_R0;
336
337         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338     }
339
340     /* if r1 not used then */
341
342     if (!r1iu) {
343         /* push it if not already pushed */
344         if (!_G.r1Pushed) {
345           //pic14_emitcode ("push","%s",
346           //          pic14_regWithIdx(R1_IDX)->dname);
347             _G.r1Pushed++ ;
348         }
349         
350         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351         (*aopp)->type = AOP_R1;
352         return pic14_regWithIdx(R1_IDX);
353     }
354
355 endOfWorld :
356     /* I said end of world but not quite end of world yet */
357     /* if this is a result then we can push it on the stack*/
358     if (result) {
359         (*aopp)->type = AOP_STK;    
360         return NULL;
361     }
362
363     /* other wise this is true end of the world */
364     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365            "getFreePtr should never reach here");
366     exit(0);
367 }
368
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp                                  */
371 /*-----------------------------------------------------------------*/
372 asmop *newAsmop (short type)
373 {
374     asmop *aop;
375
376     aop = Safe_calloc(1,sizeof(asmop));
377     aop->type = type;
378     return aop;
379 }
380
381 static void genSetDPTR(int n)
382 {
383     if (!n)
384     {
385         pic14_emitcode(";", "Select standard DPTR");
386         pic14_emitcode("mov", "dps, #0x00");
387     }
388     else
389     {
390         pic14_emitcode(";", "Select alternate DPTR");
391         pic14_emitcode("mov", "dps, #0x01");
392     }
393 }
394
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for  */
397 /*              generating code                                    */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
400 {
401   if(!resIfx) 
402     return;
403
404   //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
405
406   resIfx->condition = 1;    /* assume that the ifx is true */
407   resIfx->generated = 0;    /* indicate that the ifx has not been used */
408
409   if(!ifx) {
410     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
411 /*
412     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
413                         __FUNCTION__,__LINE__,resIfx->lbl->key);
414 */
415   } else {
416     if(IC_TRUE(ifx)) {
417       resIfx->lbl = IC_TRUE(ifx);
418     } else {
419       resIfx->lbl = IC_FALSE(ifx);
420       resIfx->condition = 0;
421     }
422 /*
423     if(IC_TRUE(ifx)) 
424       DEBUGpic14_emitcode("; ***","ifx true is non-null");
425     if(IC_FALSE(ifx)) 
426       DEBUGpic14_emitcode("; ***","ifx false is non-null");
427 */
428   }
429
430   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
431
432 }
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type               */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
437 {
438
439     return PTR_TYPE(SPEC_OCLS(etype));
440
441 }
442
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol                                   */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
447 {
448     asmop *aop;
449     memmap *space= SPEC_OCLS(sym->etype);
450
451     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452     /* if already has one */
453     if (sym->aop)
454         return sym->aop;
455
456     /* assign depending on the storage class */
457     /* if it is on the stack or indirectly addressable */
458     /* space we need to assign either r0 or r1 to it   */    
459     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
460         sym->aop = aop = newAsmop(0);
461         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
462         aop->size = getSize(sym->type);
463
464         /* now assign the address of the variable to 
465         the pointer register */
466         if (aop->type != AOP_STK) {
467
468             if (sym->onStack) {
469                     if ( _G.accInUse )
470                         pic14_emitcode("push","acc");
471
472                     pic14_emitcode("mov","a,_bp");
473                     pic14_emitcode("add","a,#0x%02x",
474                              ((sym->stack < 0) ?
475                               ((char)(sym->stack - _G.nRegsSaved )) :
476                               ((char)sym->stack)) & 0xff);
477                     pic14_emitcode("mov","%s,a",
478                              aop->aopu.aop_ptr->name);
479
480                     if ( _G.accInUse )
481                         pic14_emitcode("pop","acc");
482             } else
483                 pic14_emitcode("mov","%s,#%s",
484                          aop->aopu.aop_ptr->name,
485                          sym->rname);
486             aop->paged = space->paged;
487         } else
488             aop->aopu.aop_stk = sym->stack;
489         return aop;
490     }
491     
492     if (sym->onStack && options.stack10bit)
493     {
494         /* It's on the 10 bit stack, which is located in
495          * far data space.
496          */
497          
498       //DEBUGpic14_emitcode(";","%d",__LINE__);
499
500         if ( _G.accInUse )
501                 pic14_emitcode("push","acc");
502
503         pic14_emitcode("mov","a,_bp");
504         pic14_emitcode("add","a,#0x%02x",
505                  ((sym->stack < 0) ?
506                    ((char)(sym->stack - _G.nRegsSaved )) :
507                    ((char)sym->stack)) & 0xff);
508         
509         genSetDPTR(1);
510         pic14_emitcode ("mov","dpx1,#0x40");
511         pic14_emitcode ("mov","dph1,#0x00");
512         pic14_emitcode ("mov","dpl1, a");
513         genSetDPTR(0);
514         
515         if ( _G.accInUse )
516             pic14_emitcode("pop","acc");
517             
518         sym->aop = aop = newAsmop(AOP_DPTR2);
519         aop->size = getSize(sym->type); 
520         return aop;
521     }
522
523     //DEBUGpic14_emitcode(";","%d",__LINE__);
524     /* if in bit space */
525     if (IN_BITSPACE(space)) {
526         sym->aop = aop = newAsmop (AOP_CRY);
527         aop->aopu.aop_dir = sym->rname ;
528         aop->size = getSize(sym->type);
529         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
530         return aop;
531     }
532     /* if it is in direct space */
533     if (IN_DIRSPACE(space)) {
534         sym->aop = aop = newAsmop (AOP_DIR);
535         aop->aopu.aop_dir = sym->rname ;
536         aop->size = getSize(sym->type);
537         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
538         return aop;
539     }
540
541     /* special case for a function */
542     if (IS_FUNC(sym->type)) {   
543         sym->aop = aop = newAsmop(AOP_IMMD);    
544         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
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         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
549         return aop;
550     }
551
552
553     /* only remaining is far space */
554     /* in which case DPTR gets the address */
555     sym->aop = aop = newAsmop(AOP_PCODE);
556
557     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
558     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559     PCOI(aop->aopu.pcop)->index = 0;
560
561     DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
562                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
563
564     allocDirReg (IC_LEFT(ic));
565
566     aop->size = FPTRSIZE; 
567 /*
568     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569     sym->aop = aop = newAsmop(AOP_DPTR);
570     pic14_emitcode ("mov","dptr,#%s", sym->rname);
571     aop->size = getSize(sym->type);
572
573     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
574 */
575
576     /* if it is in code space */
577     if (IN_CODESPACE(space))
578         aop->code = 1;
579
580     return aop;     
581 }
582
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object                           */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
587 {
588   symbol *sym = OP_SYMBOL(op);
589   iCode *ic = NULL;
590   asmop *aop = newAsmop(AOP_PCODE);
591   int val = 0;
592   int offset = 0;
593
594   ic = sym->rematiCode;
595
596   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597   if(IS_OP_POINTER(op)) {
598     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
599   }
600   for (;;) {
601     if (ic->op == '+') {
602       val += (int) operandLitValue(IC_RIGHT(ic));
603     } else if (ic->op == '-') {
604       val -= (int) operandLitValue(IC_RIGHT(ic));
605     } else
606       break;
607         
608     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
609   }
610
611   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
613   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614   PCOI(aop->aopu.pcop)->index = val;
615
616   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
617                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
618                       val, IS_PTR_CONST(operandType(op)));
619
620   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
621
622   allocDirReg (IC_LEFT(ic));
623
624   return aop;        
625 }
626
627 int aopIdx (asmop *aop, int offset)
628 {
629   if(!aop)
630     return -1;
631
632   if(aop->type !=  AOP_REG)
633     return -2;
634         
635   return aop->aopu.aop_reg[offset]->rIdx;
636
637 }
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common       */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
642 {
643     symbol *sym1, *sym2;
644     int i;
645
646     /* if they have registers in common */
647     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
648         return FALSE ;
649
650     sym1 = OP_SYMBOL(op1);
651     sym2 = OP_SYMBOL(op2);
652
653     if (sym1->nRegs == 0 || sym2->nRegs == 0)
654         return FALSE ;
655
656     for (i = 0 ; i < sym1->nRegs ; i++) {
657         int j;
658         if (!sym1->regs[i])
659             continue ;
660
661         for (j = 0 ; j < sym2->nRegs ;j++ ) {
662             if (!sym2->regs[j])
663                 continue ;
664
665             if (sym2->regs[j] == sym1->regs[i])
666                 return TRUE ;
667         }
668     }
669
670     return FALSE ;
671 }
672
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent                                        */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
677 {
678     symbol *sym1, *sym2;
679
680     /* if they not symbols */
681     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
682         return FALSE;
683
684     sym1 = OP_SYMBOL(op1);
685     sym2 = OP_SYMBOL(op2);
686
687     /* if both are itemps & one is spilt
688        and the other is not then false */
689     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690         sym1->isspilt != sym2->isspilt )
691         return FALSE ;
692
693     /* if they are the same */
694     if (sym1 == sym2)
695         return TRUE ;
696
697     if (strcmp(sym1->rname,sym2->rname) == 0)
698         return TRUE;
699
700
701     /* if left is a tmp & right is not */
702     if (IS_ITEMP(op1)  && 
703         !IS_ITEMP(op2) &&
704         sym1->isspilt  &&
705         (sym1->usl.spillLoc == sym2))
706         return TRUE;
707
708     if (IS_ITEMP(op2)  && 
709         !IS_ITEMP(op1) &&
710         sym2->isspilt  &&
711         sym1->level > 0 &&
712         (sym2->usl.spillLoc == sym1))
713         return TRUE ;
714
715     return FALSE ;
716 }
717
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers                   */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 {
723     int i;
724
725     if (aop1 == aop2)
726         return TRUE ;
727
728     if (aop1->type != AOP_REG ||
729         aop2->type != AOP_REG )
730         return FALSE ;
731
732     if (aop1->size != aop2->size )
733         return FALSE ;
734
735     for (i = 0 ; i < aop1->size ; i++ )
736         if (aop1->aopu.aop_reg[i] !=
737             aop2->aopu.aop_reg[i] )
738             return FALSE ;
739
740     return TRUE ;
741 }
742
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand  :                    */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
747 {
748     asmop *aop;
749     symbol *sym;
750     int i;
751
752     if (!op)
753         return ;
754
755     //    DEBUGpic14_emitcode(";","%d",__LINE__);
756     /* if this a literal */
757     if (IS_OP_LITERAL(op)) {
758         op->aop = aop = newAsmop(AOP_LIT);
759         aop->aopu.aop_lit = op->operand.valOperand;
760         aop->size = getSize(operandType(op));
761         return;
762     }
763
764     {
765       sym_link *type = operandType(op);
766       if(IS_PTR_CONST(type))
767         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
768     }
769
770     /* if already has a asmop then continue */
771     if (op->aop)
772         return ;
773
774     /* if the underlying symbol has a aop */
775     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776       DEBUGpic14_emitcode(";","%d",__LINE__);
777         op->aop = OP_SYMBOL(op)->aop;
778         return;
779     }
780
781     /* if this is a true symbol */
782     if (IS_TRUE_SYMOP(op)) {    
783       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
785       return ;
786     }
787
788     /* this is a temporary : this has
789     only four choices :
790     a) register
791     b) spillocation
792     c) rematerialize 
793     d) conditional   
794     e) can be a return use only */
795
796     sym = OP_SYMBOL(op);
797
798
799     /* if the type is a conditional */
800     if (sym->regType == REG_CND) {
801         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
802         aop->size = 0;
803         return;
804     }
805
806     /* if it is spilt then two situations
807     a) is rematerialize 
808     b) has a spill location */
809     if (sym->isspilt || sym->nRegs == 0) {
810
811       DEBUGpic14_emitcode(";","%d",__LINE__);
812         /* rematerialize it NOW */
813         if (sym->remat) {
814
815             sym->aop = op->aop = aop =
816                                       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           /*
834           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
835           aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
836           //allocDirReg (IC_LEFT(ic));
837           aop->size = getSize(sym->type);
838           */
839
840           unsigned i;
841
842           aop = op->aop = sym->aop = newAsmop(AOP_STR);
843           aop->size = getSize(sym->type);
844           for ( i = 0 ; i < fReturnSizePic ; i++ )
845             aop->aopu.aop_str[i] = fReturn[i];
846
847           DEBUGpic14_emitcode(";","%d",__LINE__);
848           return;
849         }
850
851         /* else spill location  */
852         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
853             /* force a new aop if sizes differ */
854             sym->usl.spillLoc->aop = NULL;
855         }
856         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
857                             __FUNCTION__,__LINE__,
858                             sym->usl.spillLoc->rname,
859                             sym->rname, sym->usl.spillLoc->offset);
860
861         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
862         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
863         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
864                                           getSize(sym->type), 
865                                           sym->usl.spillLoc->offset);
866         aop->size = getSize(sym->type);
867
868         return;
869     }
870
871     {
872       sym_link *type = operandType(op);
873       if(IS_PTR_CONST(type)) 
874         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
875     }
876
877     /* must be in a register */
878     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
879     sym->aop = op->aop = aop = newAsmop(AOP_REG);
880     aop->size = sym->nRegs;
881     for ( i = 0 ; i < sym->nRegs ;i++)
882         aop->aopu.aop_reg[i] = sym->regs[i];
883 }
884
885 /*-----------------------------------------------------------------*/
886 /* freeAsmop - free up the asmop given to an operand               */
887 /*----------------------------------------------------------------*/
888 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
889 {   
890     asmop *aop ;
891
892     if (!op)
893         aop = aaop;
894     else 
895         aop = op->aop;
896
897     if (!aop)
898         return ;
899
900     if (aop->freed)
901         goto dealloc; 
902
903     aop->freed = 1;
904
905     /* depending on the asmop type only three cases need work AOP_RO
906        , AOP_R1 && AOP_STK */
907 #if 0
908     switch (aop->type) {
909         case AOP_R0 :
910             if (_G.r0Pushed ) {
911                 if (pop) {
912                     pic14_emitcode ("pop","ar0");     
913                     _G.r0Pushed--;
914                 }
915             }
916             bitVectUnSetBit(ic->rUsed,R0_IDX);
917             break;
918
919         case AOP_R1 :
920             if (_G.r1Pushed ) {
921                 if (pop) {
922                     pic14_emitcode ("pop","ar1");
923                     _G.r1Pushed--;
924                 }
925             }
926             bitVectUnSetBit(ic->rUsed,R1_IDX);          
927             break;
928
929         case AOP_STK :
930         {
931             int sz = aop->size;    
932             int stk = aop->aopu.aop_stk + aop->size;
933             bitVectUnSetBit(ic->rUsed,R0_IDX);
934             bitVectUnSetBit(ic->rUsed,R1_IDX);          
935
936             getFreePtr(ic,&aop,FALSE);
937             
938             if (options.stack10bit)
939             {
940                 /* I'm not sure what to do here yet... */
941                 /* #STUB */
942                 fprintf(stderr, 
943                         "*** Warning: probably generating bad code for "
944                         "10 bit stack mode.\n");
945             }
946             
947             if (stk) {
948                 pic14_emitcode ("mov","a,_bp");
949                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
950                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
951             } else {
952                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
953             }
954
955             while (sz--) {
956                 pic14_emitcode("pop","acc");
957                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
958                 if (!sz) break;
959                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
960             }
961             op->aop = aop;
962             freeAsmop(op,NULL,ic,TRUE);
963             if (_G.r0Pushed) {
964                 pic14_emitcode("pop","ar0");
965                 _G.r0Pushed--;
966             }
967
968             if (_G.r1Pushed) {
969                 pic14_emitcode("pop","ar1");
970                 _G.r1Pushed--;
971             }       
972         }
973     }
974 #endif
975
976 dealloc:
977     /* all other cases just dealloc */
978     if (op ) {
979         op->aop = NULL;
980         if (IS_SYMOP(op)) {
981             OP_SYMBOL(op)->aop = NULL;    
982             /* if the symbol has a spill */
983             if (SPIL_LOC(op))
984                 SPIL_LOC(op)->aop = NULL;
985         }
986     }
987 }
988
989 /*-----------------------------------------------------------------*/
990 /* aopGet - for fetching value of the aop                          */
991 /*-----------------------------------------------------------------*/
992 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
993 {
994     char *s = buffer ;
995     char *rs;
996
997     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
998     /* offset is greater than
999     size then zero */
1000     if (offset > (aop->size - 1) &&
1001         aop->type != AOP_LIT)
1002         return zero;
1003
1004     /* depending on type */
1005     switch (aop->type) {
1006         
1007     case AOP_R0:
1008     case AOP_R1:
1009         DEBUGpic14_emitcode(";","%d",__LINE__);
1010         /* if we need to increment it */       
1011         while (offset > aop->coff) {        
1012             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1013             aop->coff++;
1014         }
1015         
1016         while (offset < aop->coff) {
1017             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1018             aop->coff--;
1019         }
1020         
1021         aop->coff = offset ;
1022         if (aop->paged) {
1023             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1024             return (dname ? "acc" : "a");
1025         }       
1026         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1027         rs = Safe_calloc(1,strlen(s)+1);
1028         strcpy(rs,s);   
1029         return rs;
1030         
1031     case AOP_DPTR:
1032     case AOP_DPTR2:
1033         DEBUGpic14_emitcode(";","%d",__LINE__);
1034     if (aop->type == AOP_DPTR2)
1035     {
1036         genSetDPTR(1);
1037     }
1038     
1039         while (offset > aop->coff) {
1040             pic14_emitcode ("inc","dptr");
1041             aop->coff++;
1042         }
1043         
1044         while (offset < aop->coff) {        
1045             pic14_emitcode("lcall","__decdptr");
1046             aop->coff--;
1047         }
1048         
1049         aop->coff = offset;
1050         if (aop->code) {
1051             pic14_emitcode("clr","a");
1052             pic14_emitcode("movc","a,@a+dptr");
1053         }
1054     else {
1055             pic14_emitcode("movx","a,@dptr");
1056     }
1057             
1058     if (aop->type == AOP_DPTR2)
1059     {
1060         genSetDPTR(0);
1061     }
1062             
1063     return (dname ? "acc" : "a");
1064         
1065         
1066     case AOP_IMMD:
1067         if (bit16) 
1068             sprintf (s,"%s",aop->aopu.aop_immd);
1069         else
1070             if (offset) 
1071                 sprintf(s,"(%s >> %d)",
1072                         aop->aopu.aop_immd,
1073                         offset*8);
1074             else
1075                 sprintf(s,"%s",
1076                         aop->aopu.aop_immd);
1077         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1078         rs = Safe_calloc(1,strlen(s)+1);
1079         strcpy(rs,s);   
1080         return rs;
1081         
1082     case AOP_DIR:
1083       if (offset) {
1084         sprintf(s,"(%s + %d)",
1085                 aop->aopu.aop_dir,
1086                 offset);
1087         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1088       } else
1089             sprintf(s,"%s",aop->aopu.aop_dir);
1090         rs = Safe_calloc(1,strlen(s)+1);
1091         strcpy(rs,s);   
1092         return rs;
1093         
1094     case AOP_REG:
1095       //if (dname) 
1096       //    return aop->aopu.aop_reg[offset]->dname;
1097       //else
1098             return aop->aopu.aop_reg[offset]->name;
1099         
1100     case AOP_CRY:
1101       //pic14_emitcode(";","%d",__LINE__);
1102       return aop->aopu.aop_dir;
1103         
1104     case AOP_ACC:
1105         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1106         return "AOP_accumulator_bug";
1107
1108     case AOP_LIT:
1109         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1110         rs = Safe_calloc(1,strlen(s)+1);
1111         strcpy(rs,s);   
1112         return rs;
1113         
1114     case AOP_STR:
1115         aop->coff = offset ;
1116         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1117             dname)
1118             return "acc";
1119         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1120         
1121         return aop->aopu.aop_str[offset];
1122         
1123     case AOP_PCODE:
1124       {
1125         pCodeOp *pcop = aop->aopu.pcop;
1126         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1127         if(pcop->name) {
1128           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1129           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1130           sprintf(s,"%s", pcop->name);
1131         } else
1132           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1133
1134       }
1135       rs = Safe_calloc(1,strlen(s)+1);
1136       strcpy(rs,s);   
1137       return rs;
1138
1139     }
1140
1141     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1142            "aopget got unsupported aop->type");
1143     exit(0);
1144 }
1145
1146
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp                  */
1149 /*-----------------------------------------------------------------*/
1150 pCodeOp *popGetTempReg(void)
1151 {
1152
1153   pCodeOp *pcop;
1154
1155   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1156   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1157     PCOR(pcop)->r->wasUsed=1;
1158     PCOR(pcop)->r->isFree=0;
1159   }
1160
1161   return pcop;
1162 }
1163
1164 /*-----------------------------------------------------------------*/
1165 /* popGetTempReg - create a new temporary pCodeOp                  */
1166 /*-----------------------------------------------------------------*/
1167 void popReleaseTempReg(pCodeOp *pcop)
1168 {
1169
1170   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1171     PCOR(pcop)->r->isFree = 1;
1172
1173 }
1174 /*-----------------------------------------------------------------*/
1175 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1176 /*-----------------------------------------------------------------*/
1177 pCodeOp *popGetLabel(unsigned int key)
1178 {
1179
1180   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1181
1182   if(key>max_key)
1183     max_key = key;
1184
1185   return newpCodeOpLabel(NULL,key+100+labelOffset);
1186 }
1187
1188 /*-----------------------------------------------------------------*/
1189 /* popCopyReg - copy a pcode operator                              */
1190 /*-----------------------------------------------------------------*/
1191 pCodeOp *popCopyReg(pCodeOpReg *pc)
1192 {
1193   pCodeOpReg *pcor;
1194
1195   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1196   pcor->pcop.type = pc->pcop.type;
1197   if(pc->pcop.name) {
1198     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1199       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1200   } else
1201     pcor->pcop.name = NULL;
1202
1203   pcor->r = pc->r;
1204   pcor->rIdx = pc->rIdx;
1205   pcor->r->wasUsed=1;
1206
1207   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1208
1209   return PCOP(pcor);
1210 }
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion              */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetLit(unsigned int lit)
1215 {
1216
1217   return newpCodeOpLit(lit);
1218 }
1219
1220
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion         */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1225 {
1226
1227   return newpCodeOpImmd(name, offset,index, 0);
1228 }
1229
1230
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion              */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str)
1235 {
1236   pCodeOp *pcop;
1237
1238
1239   if(!str) {
1240     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1241     exit (1);
1242   }
1243
1244   pcop = newpCodeOp(str,PO_STR);
1245
1246   return pcop;
1247 }
1248
1249 /*-----------------------------------------------------------------*/
1250 /* popRegFromString -                                              */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popRegFromString(char *str, int size, int offset)
1253 {
1254
1255   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256   pcop->type = PO_DIR;
1257
1258   DEBUGpic14_emitcode(";","%d",__LINE__);
1259
1260   if(!str)
1261     str = "BAD_STRING";
1262
1263   pcop->name = Safe_calloc(1,strlen(str)+1);
1264   strcpy(pcop->name,str);
1265
1266   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1267
1268   PCOR(pcop)->r = dirregWithName(pcop->name);
1269   if(PCOR(pcop)->r == NULL) {
1270     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1271     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1272     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1273   } else {
1274     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1275   }
1276   PCOR(pcop)->instance = offset;
1277
1278   return pcop;
1279 }
1280
1281 pCodeOp *popRegFromIdx(int rIdx)
1282 {
1283   pCodeOp *pcop;
1284
1285   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1286                        __FUNCTION__,__LINE__,rIdx);
1287
1288   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1289
1290   PCOR(pcop)->rIdx = rIdx;
1291   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1292   PCOR(pcop)->r->isFree = 0;
1293   PCOR(pcop)->r->wasUsed = 1;
1294
1295   pcop->type = PCOR(pcop)->r->pc_type;
1296
1297
1298   return pcop;
1299 }
1300 /*-----------------------------------------------------------------*/
1301 /* popGet - asm operator to pcode operator conversion              */
1302 /*-----------------------------------------------------------------*/
1303 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1304 {
1305   //char *s = buffer ;
1306     //char *rs;
1307
1308     pCodeOp *pcop;
1309
1310     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1311     /* offset is greater than
1312     size then zero */
1313
1314     if (offset > (aop->size - 1) &&
1315         aop->type != AOP_LIT)
1316       return NULL;  //zero;
1317
1318     /* depending on type */
1319     switch (aop->type) {
1320         
1321     case AOP_R0:
1322     case AOP_R1:
1323     case AOP_DPTR:
1324     case AOP_DPTR2:
1325     case AOP_ACC:
1326         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1327         return NULL;
1328         
1329     case AOP_IMMD:
1330       DEBUGpic14_emitcode(";","%d",__LINE__);
1331       return popGetImmd(aop->aopu.aop_immd,offset,0);
1332
1333     case AOP_DIR:
1334       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1335 #if 0
1336         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1337         pcop->type = PO_DIR;
1338
1339         /*
1340         if (offset)
1341             sprintf(s,"(%s + %d)",
1342                     aop->aopu.aop_dir,
1343                     offset);
1344         else
1345             sprintf(s,"%s",aop->aopu.aop_dir);
1346         pcop->name = Safe_calloc(1,strlen(s)+1);
1347         strcpy(pcop->name,s);   
1348         */
1349         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1350         strcpy(pcop->name,aop->aopu.aop_dir);   
1351         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1352         if(PCOR(pcop)->r == NULL) {
1353           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1354           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1355           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1356         } else {
1357           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1358         }
1359         PCOR(pcop)->instance = offset;
1360
1361         return pcop;
1362 #endif
1363         
1364     case AOP_REG:
1365       {
1366         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1367
1368         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1369         PCOR(pcop)->rIdx = rIdx;
1370         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1371         PCOR(pcop)->r->wasUsed=1;
1372         PCOR(pcop)->r->isFree=0;
1373
1374         PCOR(pcop)->instance = offset;
1375         pcop->type = PCOR(pcop)->r->pc_type;
1376         //rs = aop->aopu.aop_reg[offset]->name;
1377         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1378         return pcop;
1379       }
1380
1381     case AOP_CRY:
1382       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1383       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1384       //if(PCOR(pcop)->r == NULL)
1385       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1386       return pcop;
1387         
1388     case AOP_LIT:
1389       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1390
1391     case AOP_STR:
1392       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1393       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1394       /*
1395       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1396       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1397       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1398       pcop->type = PCOR(pcop)->r->pc_type;
1399       pcop->name = PCOR(pcop)->r->name;
1400
1401       return pcop;
1402       */
1403
1404     case AOP_PCODE:
1405       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1406                           __LINE__, 
1407                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1408       pcop = pCodeOpCopy(aop->aopu.pcop);
1409       PCOI(pcop)->offset = offset;
1410       return pcop;
1411     }
1412
1413     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1414            "popGet got unsupported aop->type");
1415     exit(0);
1416 }
1417 /*-----------------------------------------------------------------*/
1418 /* aopPut - puts a string for a aop                                */
1419 /*-----------------------------------------------------------------*/
1420 void aopPut (asmop *aop, char *s, int offset)
1421 {
1422     char *d = buffer ;
1423     symbol *lbl ;
1424
1425     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1426
1427     if (aop->size && offset > ( aop->size - 1)) {
1428         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1429                "aopPut got offset > aop->size");
1430         exit(0);
1431     }
1432
1433     /* will assign value to value */
1434     /* depending on where it is ofcourse */
1435     switch (aop->type) {
1436     case AOP_DIR:
1437       if (offset) {
1438         sprintf(d,"(%s + %d)",
1439                 aop->aopu.aop_dir,offset);
1440         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1441
1442       } else
1443             sprintf(d,"%s",aop->aopu.aop_dir);
1444         
1445         if (strcmp(d,s)) {
1446           DEBUGpic14_emitcode(";","%d",__LINE__);
1447           if(strcmp(s,"W"))
1448             pic14_emitcode("movf","%s,w",s);
1449           pic14_emitcode("movwf","%s",d);
1450
1451           if(strcmp(s,"W")) {
1452             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1453             if(offset >= aop->size) {
1454               emitpcode(POC_CLRF,popGet(aop,offset));
1455               break;
1456             } else
1457               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1458           }
1459
1460           emitpcode(POC_MOVWF,popGet(aop,offset));
1461
1462
1463         }
1464         break;
1465         
1466     case AOP_REG:
1467       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1468         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1469           /*
1470             if (*s == '@'           ||
1471                 strcmp(s,"r0") == 0 ||
1472                 strcmp(s,"r1") == 0 ||
1473                 strcmp(s,"r2") == 0 ||
1474                 strcmp(s,"r3") == 0 ||
1475                 strcmp(s,"r4") == 0 ||
1476                 strcmp(s,"r5") == 0 ||
1477                 strcmp(s,"r6") == 0 || 
1478                 strcmp(s,"r7") == 0 )
1479                 pic14_emitcode("mov","%s,%s  ; %d",
1480                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1481             else
1482           */
1483
1484           if(strcmp(s,"W")==0 )
1485             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1486
1487           pic14_emitcode("movwf","%s",
1488                    aop->aopu.aop_reg[offset]->name);
1489
1490           if(strcmp(s,zero)==0) {
1491             emitpcode(POC_CLRF,popGet(aop,offset));
1492
1493           } else if(strcmp(s,"W")==0) {
1494             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1495             pcop->type = PO_GPR_REGISTER;
1496
1497             PCOR(pcop)->rIdx = -1;
1498             PCOR(pcop)->r = NULL;
1499
1500             DEBUGpic14_emitcode(";","%d",__LINE__);
1501             pcop->name = Safe_strdup(s);
1502             emitpcode(POC_MOVFW,pcop);
1503             emitpcode(POC_MOVWF,popGet(aop,offset));
1504           } else if(strcmp(s,one)==0) {
1505             emitpcode(POC_CLRF,popGet(aop,offset));
1506             emitpcode(POC_INCF,popGet(aop,offset));
1507           } else {
1508             emitpcode(POC_MOVWF,popGet(aop,offset));
1509           }
1510         }
1511         break;
1512         
1513     case AOP_DPTR:
1514     case AOP_DPTR2:
1515     
1516     if (aop->type == AOP_DPTR2)
1517     {
1518         genSetDPTR(1);
1519     }
1520     
1521         if (aop->code) {
1522             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1523                    "aopPut writting to code space");
1524             exit(0);
1525         }
1526         
1527         while (offset > aop->coff) {
1528             aop->coff++;
1529             pic14_emitcode ("inc","dptr");
1530         }
1531         
1532         while (offset < aop->coff) {
1533             aop->coff-- ;
1534             pic14_emitcode("lcall","__decdptr");
1535         }
1536         
1537         aop->coff = offset;
1538         
1539         /* if not in accumulater */
1540         MOVA(s);        
1541         
1542         pic14_emitcode ("movx","@dptr,a");
1543         
1544     if (aop->type == AOP_DPTR2)
1545     {
1546         genSetDPTR(0);
1547     }
1548         break;
1549         
1550     case AOP_R0:
1551     case AOP_R1:
1552         while (offset > aop->coff) {
1553             aop->coff++;
1554             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1555         }
1556         while (offset < aop->coff) {
1557             aop->coff-- ;
1558             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559         }
1560         aop->coff = offset;
1561         
1562         if (aop->paged) {
1563             MOVA(s);           
1564             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565             
1566         } else
1567             if (*s == '@') {
1568                 MOVA(s);
1569                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1570             } else
1571                 if (strcmp(s,"r0") == 0 ||
1572                     strcmp(s,"r1") == 0 ||
1573                     strcmp(s,"r2") == 0 ||
1574                     strcmp(s,"r3") == 0 ||
1575                     strcmp(s,"r4") == 0 ||
1576                     strcmp(s,"r5") == 0 ||
1577                     strcmp(s,"r6") == 0 || 
1578                     strcmp(s,"r7") == 0 ) {
1579                     char buffer[10];
1580                     sprintf(buffer,"a%s",s);
1581                     pic14_emitcode("mov","@%s,%s",
1582                              aop->aopu.aop_ptr->name,buffer);
1583                 } else
1584                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585         
1586         break;
1587         
1588     case AOP_STK:
1589         if (strcmp(s,"a") == 0)
1590             pic14_emitcode("push","acc");
1591         else
1592             pic14_emitcode("push","%s",s);
1593         
1594         break;
1595         
1596     case AOP_CRY:
1597         /* if bit variable */
1598         if (!aop->aopu.aop_dir) {
1599             pic14_emitcode("clr","a");
1600             pic14_emitcode("rlc","a");
1601         } else {
1602             if (s == zero) 
1603                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1604             else
1605                 if (s == one)
1606                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1607                 else
1608                     if (!strcmp(s,"c"))
1609                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1610                     else {
1611                         lbl = newiTempLabel(NULL);
1612                         
1613                         if (strcmp(s,"a")) {
1614                             MOVA(s);
1615                         }
1616                         pic14_emitcode("clr","c");
1617                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1618                         pic14_emitcode("cpl","c");
1619                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1620                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621                     }
1622         }
1623         break;
1624         
1625     case AOP_STR:
1626         aop->coff = offset;
1627         if (strcmp(aop->aopu.aop_str[offset],s))
1628             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629         break;
1630         
1631     case AOP_ACC:
1632         aop->coff = offset;
1633         if (!offset && (strcmp(s,"acc") == 0))
1634             break;
1635         
1636         if (strcmp(aop->aopu.aop_str[offset],s))
1637             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1638         break;
1639
1640     default :
1641         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1642                "aopPut got unsupported aop->type");
1643         exit(0);    
1644     }    
1645
1646 }
1647
1648 /*-----------------------------------------------------------------*/
1649 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1650 /*-----------------------------------------------------------------*/
1651 void mov2w (asmop *aop, int offset)
1652 {
1653
1654   if(!aop)
1655     return;
1656
1657   DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1658
1659   if ( aop->type == AOP_PCODE ||
1660        aop->type == AOP_LIT )
1661     emitpcode(POC_MOVLW,popGet(aop,offset));
1662   else
1663     emitpcode(POC_MOVFW,popGet(aop,offset));
1664
1665 }
1666
1667 /*-----------------------------------------------------------------*/
1668 /* reAdjustPreg - points a register back to where it should        */
1669 /*-----------------------------------------------------------------*/
1670 static void reAdjustPreg (asmop *aop)
1671 {
1672     int size ;
1673
1674     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1675     aop->coff = 0;
1676     if ((size = aop->size) <= 1)
1677         return ;
1678     size-- ;
1679     switch (aop->type) {
1680         case AOP_R0 :
1681         case AOP_R1 :
1682             while (size--)
1683                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1684             break;          
1685         case AOP_DPTR :
1686         case AOP_DPTR2:
1687             if (aop->type == AOP_DPTR2)
1688             {
1689                 genSetDPTR(1);
1690             } 
1691             while (size--)
1692             {
1693                 pic14_emitcode("lcall","__decdptr");
1694             }
1695                 
1696             if (aop->type == AOP_DPTR2)
1697             {
1698                 genSetDPTR(0);
1699             }                
1700             break;  
1701
1702     }   
1703
1704 }
1705
1706 /*-----------------------------------------------------------------*/
1707 /* genNotFloat - generates not for float operations              */
1708 /*-----------------------------------------------------------------*/
1709 static void genNotFloat (operand *op, operand *res)
1710 {
1711     int size, offset;
1712     char *l;
1713     symbol *tlbl ;
1714
1715     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1716     /* we will put 127 in the first byte of 
1717     the result */
1718     aopPut(AOP(res),"#127",0);
1719     size = AOP_SIZE(op) - 1;
1720     offset = 1;
1721
1722     l = aopGet(op->aop,offset++,FALSE,FALSE);
1723     MOVA(l);    
1724
1725     while(size--) {
1726         pic14_emitcode("orl","a,%s",
1727                  aopGet(op->aop,
1728                         offset++,FALSE,FALSE));
1729     }
1730     tlbl = newiTempLabel(NULL);
1731
1732     tlbl = newiTempLabel(NULL);
1733     aopPut(res->aop,one,1);
1734     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1735     aopPut(res->aop,zero,1);
1736     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1737
1738     size = res->aop->size - 2;
1739     offset = 2;    
1740     /* put zeros in the rest */
1741     while (size--) 
1742         aopPut(res->aop,zero,offset++);
1743 }
1744
1745 #if 0
1746 /*-----------------------------------------------------------------*/
1747 /* opIsGptr: returns non-zero if the passed operand is             */   
1748 /* a generic pointer type.                                         */
1749 /*-----------------------------------------------------------------*/ 
1750 static int opIsGptr(operand *op)
1751 {
1752     sym_link *type = operandType(op);
1753     
1754     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1755     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1756     {
1757         return 1;
1758     }
1759     return 0;        
1760 }
1761 #endif
1762
1763 /*-----------------------------------------------------------------*/
1764 /* pic14_getDataSize - get the operand data size                         */
1765 /*-----------------------------------------------------------------*/
1766 int pic14_getDataSize(operand *op)
1767 {
1768     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1769
1770
1771     return AOP_SIZE(op);
1772
1773     // tsd- in the pic port, the genptr size is 1, so this code here
1774     // fails. ( in the 8051 port, the size was 4).
1775 #if 0
1776     int size;
1777     size = AOP_SIZE(op);
1778     if (size == GPTRSIZE)
1779     {
1780         sym_link *type = operandType(op);
1781         if (IS_GENPTR(type))
1782         {
1783             /* generic pointer; arithmetic operations
1784              * should ignore the high byte (pointer type).
1785              */
1786             size--;
1787     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1788         }
1789     }
1790     return size;
1791 #endif
1792 }
1793
1794 /*-----------------------------------------------------------------*/
1795 /* pic14_outAcc - output Acc                                             */
1796 /*-----------------------------------------------------------------*/
1797 void pic14_outAcc(operand *result)
1798 {
1799   int size,offset;
1800   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1801   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1802
1803
1804   size = pic14_getDataSize(result);
1805   if(size){
1806     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1807     size--;
1808     offset = 1;
1809     /* unsigned or positive */
1810     while(size--)
1811       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1812   }
1813
1814 }
1815
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_outBitC - output a bit C                                        */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_outBitC(operand *result)
1820 {
1821
1822     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1823     /* if the result is bit */
1824     if (AOP_TYPE(result) == AOP_CRY) 
1825         aopPut(AOP(result),"c",0);
1826     else {
1827         pic14_emitcode("clr","a  ; %d", __LINE__);
1828         pic14_emitcode("rlc","a");
1829         pic14_outAcc(result);
1830     }
1831 }
1832
1833 /*-----------------------------------------------------------------*/
1834 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1835 /*-----------------------------------------------------------------*/
1836 void pic14_toBoolean(operand *oper)
1837 {
1838     int size = AOP_SIZE(oper) - 1;
1839     int offset = 1;
1840
1841     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1842
1843     if ( AOP_TYPE(oper) != AOP_ACC) {
1844       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1845     }
1846     while (size--) {
1847       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1848     }
1849 }
1850
1851
1852 /*-----------------------------------------------------------------*/
1853 /* genNot - generate code for ! operation                          */
1854 /*-----------------------------------------------------------------*/
1855 static void genNot (iCode *ic)
1856 {
1857   symbol *tlbl;
1858   sym_link *optype = operandType(IC_LEFT(ic));
1859   int size;
1860
1861   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1862   /* assign asmOps to operand & result */
1863   aopOp (IC_LEFT(ic),ic,FALSE);
1864   aopOp (IC_RESULT(ic),ic,TRUE);
1865
1866   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1867   /* if in bit space then a special case */
1868   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1869     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1870       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1871       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1872     } else {
1873       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1874       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1875       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1876     }
1877     goto release;
1878   }
1879
1880   /* if type float then do float */
1881   if (IS_FLOAT(optype)) {
1882     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1883     goto release;
1884   }
1885
1886   size = AOP_SIZE(IC_RESULT(ic));
1887   if(size == 1) {
1888     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1889     emitpcode(POC_ANDLW,popGetLit(1));
1890     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1891     goto release;
1892   }
1893   pic14_toBoolean(IC_LEFT(ic));
1894
1895   tlbl = newiTempLabel(NULL);
1896   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1897   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1898   pic14_outBitC(IC_RESULT(ic));
1899
1900  release:    
1901   /* release the aops */
1902   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1903   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1904 }
1905
1906
1907 /*-----------------------------------------------------------------*/
1908 /* genCpl - generate code for complement                           */
1909 /*-----------------------------------------------------------------*/
1910 static void genCpl (iCode *ic)
1911 {
1912     int offset = 0;
1913     int size ;
1914
1915
1916     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1917     /* assign asmOps to operand & result */
1918     aopOp (IC_LEFT(ic),ic,FALSE);
1919     aopOp (IC_RESULT(ic),ic,TRUE);
1920
1921     /* if both are in bit space then 
1922     a special case */
1923     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1924         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1925
1926         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1927         pic14_emitcode("cpl","c"); 
1928         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1929         goto release; 
1930     } 
1931
1932     size = AOP_SIZE(IC_RESULT(ic));
1933     while (size--) {
1934         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1935         MOVA(l);       
1936         pic14_emitcode("cpl","a");
1937         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1938     }
1939
1940
1941 release:
1942     /* release the aops */
1943     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1944     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1945 }
1946
1947 /*-----------------------------------------------------------------*/
1948 /* genUminusFloat - unary minus for floating points                */
1949 /*-----------------------------------------------------------------*/
1950 static void genUminusFloat(operand *op,operand *result)
1951 {
1952     int size ,offset =0 ;
1953     char *l;
1954
1955     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1956     /* for this we just need to flip the 
1957     first it then copy the rest in place */
1958     size = AOP_SIZE(op) - 1;
1959     l = aopGet(AOP(op),3,FALSE,FALSE);
1960
1961     MOVA(l);    
1962
1963     pic14_emitcode("cpl","acc.7");
1964     aopPut(AOP(result),"a",3);    
1965
1966     while(size--) {
1967         aopPut(AOP(result),
1968                aopGet(AOP(op),offset,FALSE,FALSE),
1969                offset);
1970         offset++;
1971     }          
1972 }
1973
1974 /*-----------------------------------------------------------------*/
1975 /* genUminus - unary minus code generation                         */
1976 /*-----------------------------------------------------------------*/
1977 static void genUminus (iCode *ic)
1978 {
1979   int size, i;
1980   sym_link *optype, *rtype;
1981
1982
1983   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1984   /* assign asmops */
1985   aopOp(IC_LEFT(ic),ic,FALSE);
1986   aopOp(IC_RESULT(ic),ic,TRUE);
1987
1988   /* if both in bit space then special
1989      case */
1990   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1991       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1992
1993     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1994     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1995     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1996
1997     goto release; 
1998   } 
1999
2000   optype = operandType(IC_LEFT(ic));
2001   rtype = operandType(IC_RESULT(ic));
2002
2003   /* if float then do float stuff */
2004   if (IS_FLOAT(optype)) {
2005     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2006     goto release;
2007   }
2008
2009   /* otherwise subtract from zero by taking the 2's complement */
2010   size = AOP_SIZE(IC_LEFT(ic));
2011
2012   for(i=0; i<size; i++) {
2013     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2014       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2015     else {
2016       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2017       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2018     }
2019   }
2020
2021   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2022   for(i=1; i<size; i++) {
2023     emitSKPNZ;
2024     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2025   }
2026
2027  release:
2028   /* release the aops */
2029   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2030   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2031 }
2032
2033 /*-----------------------------------------------------------------*/
2034 /* saveRegisters - will look for a call and save the registers     */
2035 /*-----------------------------------------------------------------*/
2036 static void saveRegisters(iCode *lic) 
2037 {
2038     int i;
2039     iCode *ic;
2040     bitVect *rsave;
2041     sym_link *dtype;
2042
2043     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2044     /* look for call */
2045     for (ic = lic ; ic ; ic = ic->next) 
2046         if (ic->op == CALL || ic->op == PCALL)
2047             break;
2048
2049     if (!ic) {
2050         fprintf(stderr,"found parameter push with no function call\n");
2051         return ;
2052     }
2053
2054     /* if the registers have been saved already then
2055     do nothing */
2056     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2057         return ;
2058
2059     /* find the registers in use at this time 
2060     and push them away to safety */
2061     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2062                           ic->rUsed);
2063
2064     ic->regsSaved = 1;
2065     if (options.useXstack) {
2066         if (bitVectBitValue(rsave,R0_IDX))
2067             pic14_emitcode("mov","b,r0");
2068         pic14_emitcode("mov","r0,%s",spname);
2069         for (i = 0 ; i < pic14_nRegs ; i++) {
2070             if (bitVectBitValue(rsave,i)) {
2071                 if (i == R0_IDX)
2072                     pic14_emitcode("mov","a,b");
2073                 else
2074                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2075                 pic14_emitcode("movx","@r0,a");
2076                 pic14_emitcode("inc","r0");
2077             }
2078         }
2079         pic14_emitcode("mov","%s,r0",spname);
2080         if (bitVectBitValue(rsave,R0_IDX))
2081             pic14_emitcode("mov","r0,b");           
2082     }// else
2083     //for (i = 0 ; i < pic14_nRegs ; i++) {
2084     //    if (bitVectBitValue(rsave,i))
2085     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2086     //}
2087
2088     dtype = operandType(IC_LEFT(ic));
2089     if (currFunc && dtype && 
2090         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2091         IFFUNC_ISISR(currFunc->type) &&
2092         !ic->bankSaved) 
2093
2094         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2095
2096 }
2097 /*-----------------------------------------------------------------*/
2098 /* unsaveRegisters - pop the pushed registers                      */
2099 /*-----------------------------------------------------------------*/
2100 static void unsaveRegisters (iCode *ic)
2101 {
2102     int i;
2103     bitVect *rsave;
2104
2105     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2106     /* find the registers in use at this time 
2107     and push them away to safety */
2108     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2109                           ic->rUsed);
2110     
2111     if (options.useXstack) {
2112         pic14_emitcode("mov","r0,%s",spname);   
2113         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2114             if (bitVectBitValue(rsave,i)) {
2115                 pic14_emitcode("dec","r0");
2116                 pic14_emitcode("movx","a,@r0");
2117                 if (i == R0_IDX)
2118                     pic14_emitcode("mov","b,a");
2119                 else
2120                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2121             }       
2122
2123         }
2124         pic14_emitcode("mov","%s,r0",spname);
2125         if (bitVectBitValue(rsave,R0_IDX))
2126             pic14_emitcode("mov","r0,b");
2127     } //else
2128     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2129     //    if (bitVectBitValue(rsave,i))
2130     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2131     //}
2132
2133 }  
2134
2135
2136 /*-----------------------------------------------------------------*/
2137 /* pushSide -                                                      */
2138 /*-----------------------------------------------------------------*/
2139 static void pushSide(operand * oper, int size)
2140 {
2141 #if 0
2142         int offset = 0;
2143     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2144         while (size--) {
2145                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2146                 if (AOP_TYPE(oper) != AOP_REG &&
2147                     AOP_TYPE(oper) != AOP_DIR &&
2148                     strcmp(l,"a") ) {
2149                         pic14_emitcode("mov","a,%s",l);
2150                         pic14_emitcode("push","acc");
2151                 } else
2152                         pic14_emitcode("push","%s",l);
2153         }
2154 #endif
2155 }
2156
2157 /*-----------------------------------------------------------------*/
2158 /* assignResultValue -                                             */
2159 /*-----------------------------------------------------------------*/
2160 static void assignResultValue(operand * oper)
2161 {
2162   int size = AOP_SIZE(oper);
2163
2164   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2165
2166   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2167
2168   if(!GpsuedoStkPtr) {
2169     /* The last byte in the assignment is in W */
2170     size--;
2171     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2172     GpsuedoStkPtr++;
2173   }
2174
2175   while (size--) {
2176     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2177     GpsuedoStkPtr++;
2178     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2179   }
2180 }
2181
2182
2183 /*-----------------------------------------------------------------*/
2184 /* genIpush - genrate code for pushing this gets a little complex  */
2185 /*-----------------------------------------------------------------*/
2186 static void genIpush (iCode *ic)
2187 {
2188
2189   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2190 #if 0
2191     int size, offset = 0 ;
2192     char *l;
2193
2194
2195     /* if this is not a parm push : ie. it is spill push 
2196     and spill push is always done on the local stack */
2197     if (!ic->parmPush) {
2198
2199         /* and the item is spilt then do nothing */
2200         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2201             return ;
2202
2203         aopOp(IC_LEFT(ic),ic,FALSE);
2204         size = AOP_SIZE(IC_LEFT(ic));
2205         /* push it on the stack */
2206         while(size--) {
2207             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2208             if (*l == '#') {
2209                 MOVA(l);
2210                 l = "acc";
2211             }
2212             pic14_emitcode("push","%s",l);
2213         }
2214         return ;        
2215     }
2216
2217     /* this is a paramter push: in this case we call
2218     the routine to find the call and save those
2219     registers that need to be saved */   
2220     saveRegisters(ic);
2221
2222     /* then do the push */
2223     aopOp(IC_LEFT(ic),ic,FALSE);
2224
2225
2226         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2227     size = AOP_SIZE(IC_LEFT(ic));
2228
2229     while (size--) {
2230         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2231         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2232             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2233             strcmp(l,"a") ) {
2234             pic14_emitcode("mov","a,%s",l);
2235             pic14_emitcode("push","acc");
2236         } else
2237             pic14_emitcode("push","%s",l);
2238     }       
2239
2240     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2241 #endif
2242 }
2243
2244 /*-----------------------------------------------------------------*/
2245 /* genIpop - recover the registers: can happen only for spilling   */
2246 /*-----------------------------------------------------------------*/
2247 static void genIpop (iCode *ic)
2248 {
2249   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2250 #if 0
2251     int size,offset ;
2252
2253
2254     /* if the temp was not pushed then */
2255     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2256         return ;
2257
2258     aopOp(IC_LEFT(ic),ic,FALSE);
2259     size = AOP_SIZE(IC_LEFT(ic));
2260     offset = (size-1);
2261     while (size--) 
2262         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2263                                    FALSE,TRUE));
2264
2265     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2266 #endif
2267 }
2268
2269 /*-----------------------------------------------------------------*/
2270 /* unsaverbank - restores the resgister bank from stack            */
2271 /*-----------------------------------------------------------------*/
2272 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2273 {
2274   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2275 #if 0
2276     int i;
2277     asmop *aop ;
2278     regs *r = NULL;
2279
2280     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2281     if (popPsw) {
2282         if (options.useXstack) {
2283             aop = newAsmop(0);
2284             r = getFreePtr(ic,&aop,FALSE);
2285             
2286             
2287             pic14_emitcode("mov","%s,_spx",r->name);
2288             pic14_emitcode("movx","a,@%s",r->name);
2289             pic14_emitcode("mov","psw,a");
2290             pic14_emitcode("dec","%s",r->name);
2291             
2292         }else
2293             pic14_emitcode ("pop","psw");
2294     }
2295
2296     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2297         if (options.useXstack) {       
2298             pic14_emitcode("movx","a,@%s",r->name);
2299             //pic14_emitcode("mov","(%s+%d),a",
2300             //       regspic14[i].base,8*bank+regspic14[i].offset);
2301             pic14_emitcode("dec","%s",r->name);
2302
2303         } else 
2304           pic14_emitcode("pop",""); //"(%s+%d)",
2305         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2306     }
2307
2308     if (options.useXstack) {
2309
2310         pic14_emitcode("mov","_spx,%s",r->name);
2311         freeAsmop(NULL,aop,ic,TRUE);
2312
2313     }
2314 #endif 
2315 }
2316
2317 /*-----------------------------------------------------------------*/
2318 /* saverbank - saves an entire register bank on the stack          */
2319 /*-----------------------------------------------------------------*/
2320 static void saverbank (int bank, iCode *ic, bool pushPsw)
2321 {
2322   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2323 #if 0
2324     int i;
2325     asmop *aop ;
2326     regs *r = NULL;
2327
2328     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2329     if (options.useXstack) {
2330
2331         aop = newAsmop(0);
2332         r = getFreePtr(ic,&aop,FALSE);  
2333         pic14_emitcode("mov","%s,_spx",r->name);
2334
2335     }
2336
2337     for (i = 0 ; i < pic14_nRegs ;i++) {
2338         if (options.useXstack) {
2339             pic14_emitcode("inc","%s",r->name);
2340             //pic14_emitcode("mov","a,(%s+%d)",
2341             //         regspic14[i].base,8*bank+regspic14[i].offset);
2342             pic14_emitcode("movx","@%s,a",r->name);           
2343         } else 
2344           pic14_emitcode("push","");// "(%s+%d)",
2345                      //regspic14[i].base,8*bank+regspic14[i].offset);
2346     }
2347     
2348     if (pushPsw) {
2349         if (options.useXstack) {
2350             pic14_emitcode("mov","a,psw");
2351             pic14_emitcode("movx","@%s,a",r->name);     
2352             pic14_emitcode("inc","%s",r->name);
2353             pic14_emitcode("mov","_spx,%s",r->name);       
2354             freeAsmop (NULL,aop,ic,TRUE);
2355             
2356         } else
2357             pic14_emitcode("push","psw");
2358         
2359         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2360     }
2361     ic->bankSaved = 1;
2362 #endif
2363 }
2364
2365 /*-----------------------------------------------------------------*/
2366 /* genCall - generates a call statement                            */
2367 /*-----------------------------------------------------------------*/
2368 static void genCall (iCode *ic)
2369 {
2370   sym_link *dtype;   
2371
2372   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2373
2374   /* if caller saves & we have not saved then */
2375   if (!ic->regsSaved)
2376     saveRegisters(ic);
2377
2378   /* if we are calling a function that is not using
2379      the same register bank then we need to save the
2380      destination registers on the stack */
2381   dtype = operandType(IC_LEFT(ic));
2382   if (currFunc && dtype && 
2383       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2384       IFFUNC_ISISR(currFunc->type) &&
2385       !ic->bankSaved) 
2386
2387     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2388
2389   /* if send set is not empty the assign */
2390   if (_G.sendSet) {
2391     iCode *sic;
2392     /* For the Pic port, there is no data stack.
2393      * So parameters passed to functions are stored
2394      * in registers. (The pCode optimizer will get
2395      * rid of most of these :).
2396      */
2397     int psuedoStkPtr=-1; 
2398     int firstTimeThruLoop = 1;
2399
2400     _G.sendSet = reverseSet(_G.sendSet);
2401
2402     /* First figure how many parameters are getting passed */
2403     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2404          sic = setNextItem(_G.sendSet)) {
2405
2406       aopOp(IC_LEFT(sic),sic,FALSE);
2407       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2408       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2409     }
2410
2411     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2412          sic = setNextItem(_G.sendSet)) {
2413       int size, offset = 0;
2414
2415       aopOp(IC_LEFT(sic),sic,FALSE);
2416       size = AOP_SIZE(IC_LEFT(sic));
2417
2418       while (size--) {
2419         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2420                              AopType(AOP_TYPE(IC_LEFT(sic))));
2421
2422         if(!firstTimeThruLoop) {
2423           /* If this is not the first time we've been through the loop
2424            * then we need to save the parameter in a temporary
2425            * register. The last byte of the last parameter is
2426            * passed in W. */
2427           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2428
2429         }
2430         firstTimeThruLoop=0;
2431
2432         //if (strcmp(l,fReturn[offset])) {
2433         mov2w (AOP(IC_LEFT(sic)),  offset);
2434 /*
2435         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2436              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2437           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2438         else
2439           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2440 */
2441         //}
2442         offset++;
2443       }
2444       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2445     }
2446     _G.sendSet = NULL;
2447   }
2448   /* make the call */
2449   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2450                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2451                                       OP_SYMBOL(IC_LEFT(ic))->name));
2452
2453   GpsuedoStkPtr=0;
2454   /* if we need assign a result value */
2455   if ((IS_ITEMP(IC_RESULT(ic)) && 
2456        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2457         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2458       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2459
2460     _G.accInUse++;
2461     aopOp(IC_RESULT(ic),ic,FALSE);
2462     _G.accInUse--;
2463
2464     assignResultValue(IC_RESULT(ic));
2465
2466     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2467                          AopType(AOP_TYPE(IC_RESULT(ic))));
2468                 
2469     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2470   }
2471
2472   /* adjust the stack for parameters if 
2473      required */
2474   if (ic->parmBytes) {
2475     int i;
2476     if (ic->parmBytes > 3) {
2477       pic14_emitcode("mov","a,%s",spname);
2478       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2479       pic14_emitcode("mov","%s,a",spname);
2480     } else 
2481       for ( i = 0 ; i <  ic->parmBytes ;i++)
2482         pic14_emitcode("dec","%s",spname);
2483
2484   }
2485
2486   /* if register bank was saved then pop them */
2487   if (ic->bankSaved)
2488     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2489
2490   /* if we hade saved some registers then unsave them */
2491   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2492     unsaveRegisters (ic);
2493
2494
2495 }
2496
2497 /*-----------------------------------------------------------------*/
2498 /* genPcall - generates a call by pointer statement                */
2499 /*-----------------------------------------------------------------*/
2500 static void genPcall (iCode *ic)
2501 {
2502     sym_link *dtype;
2503     symbol *rlbl = newiTempLabel(NULL);
2504
2505
2506     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2507     /* if caller saves & we have not saved then */
2508     if (!ic->regsSaved)
2509         saveRegisters(ic);
2510
2511     /* if we are calling a function that is not using
2512     the same register bank then we need to save the
2513     destination registers on the stack */
2514     dtype = operandType(IC_LEFT(ic));
2515     if (currFunc && dtype && 
2516         IFFUNC_ISISR(currFunc->type) &&
2517         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2518         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2519
2520
2521     /* push the return address on to the stack */
2522     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2523     pic14_emitcode("push","acc");    
2524     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2525     pic14_emitcode("push","acc");
2526     
2527     if (options.model == MODEL_FLAT24)
2528     {
2529         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2530         pic14_emitcode("push","acc");    
2531     }
2532
2533     /* now push the calling address */
2534     aopOp(IC_LEFT(ic),ic,FALSE);
2535
2536     pushSide(IC_LEFT(ic), FPTRSIZE);
2537
2538     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2539
2540     /* if send set is not empty the assign */
2541     if (_G.sendSet) {
2542         iCode *sic ;
2543
2544         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2545              sic = setNextItem(_G.sendSet)) {
2546             int size, offset = 0;
2547             aopOp(IC_LEFT(sic),sic,FALSE);
2548             size = AOP_SIZE(IC_LEFT(sic));
2549             while (size--) {
2550                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2551                                 FALSE,FALSE);
2552                 if (strcmp(l,fReturn[offset]))
2553                     pic14_emitcode("mov","%s,%s",
2554                              fReturn[offset],
2555                              l);
2556                 offset++;
2557             }
2558             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2559         }
2560         _G.sendSet = NULL;
2561     }
2562
2563     pic14_emitcode("ret","");
2564     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2565
2566
2567     /* if we need assign a result value */
2568     if ((IS_ITEMP(IC_RESULT(ic)) &&
2569          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2570           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2571         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2572
2573         _G.accInUse++;
2574         aopOp(IC_RESULT(ic),ic,FALSE);
2575         _G.accInUse--;
2576         
2577         assignResultValue(IC_RESULT(ic));
2578
2579         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2580     }
2581
2582     /* adjust the stack for parameters if 
2583     required */
2584     if (ic->parmBytes) {
2585         int i;
2586         if (ic->parmBytes > 3) {
2587             pic14_emitcode("mov","a,%s",spname);
2588             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2589             pic14_emitcode("mov","%s,a",spname);
2590         } else 
2591             for ( i = 0 ; i <  ic->parmBytes ;i++)
2592                 pic14_emitcode("dec","%s",spname);
2593
2594     }
2595
2596     /* if register bank was saved then unsave them */
2597     if (currFunc && dtype && 
2598         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2599         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2600
2601     /* if we hade saved some registers then
2602     unsave them */
2603     if (ic->regsSaved)
2604         unsaveRegisters (ic);
2605
2606 }
2607
2608 /*-----------------------------------------------------------------*/
2609 /* resultRemat - result  is rematerializable                       */
2610 /*-----------------------------------------------------------------*/
2611 static int resultRemat (iCode *ic)
2612 {
2613   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2614   if (SKIP_IC(ic) || ic->op == IFX)
2615     return 0;
2616
2617   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2618     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2619     if (sym->remat && !POINTER_SET(ic)) 
2620       return 1;
2621   }
2622
2623   return 0;
2624 }
2625
2626 #if defined(__BORLANDC__) || defined(_MSC_VER)
2627 #define STRCASECMP stricmp
2628 #else
2629 #define STRCASECMP strcasecmp
2630 #endif
2631
2632 #if 0
2633 /*-----------------------------------------------------------------*/
2634 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2635 /*-----------------------------------------------------------------*/
2636 static bool inExcludeList(char *s)
2637 {
2638   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2639     int i =0;
2640     
2641     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2642     if (options.excludeRegs[i] &&
2643     STRCASECMP(options.excludeRegs[i],"none") == 0)
2644         return FALSE ;
2645
2646     for ( i = 0 ; options.excludeRegs[i]; i++) {
2647         if (options.excludeRegs[i] &&
2648         STRCASECMP(s,options.excludeRegs[i]) == 0)
2649             return TRUE;
2650     }
2651     return FALSE ;
2652 }
2653 #endif
2654
2655 /*-----------------------------------------------------------------*/
2656 /* genFunction - generated code for function entry                 */
2657 /*-----------------------------------------------------------------*/
2658 static void genFunction (iCode *ic)
2659 {
2660     symbol *sym;
2661     sym_link *ftype;
2662
2663     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2664
2665     labelOffset += (max_key+4);
2666     max_key=0;
2667     GpsuedoStkPtr=0;
2668     _G.nRegsSaved = 0;
2669     /* create the function header */
2670     pic14_emitcode(";","-----------------------------------------");
2671     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2672     pic14_emitcode(";","-----------------------------------------");
2673
2674     pic14_emitcode("","%s:",sym->rname);
2675     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2676
2677     ftype = operandType(IC_LEFT(ic));
2678
2679     /* if critical function then turn interrupts off */
2680     if (IFFUNC_ISCRITICAL(ftype))
2681         pic14_emitcode("clr","ea");
2682
2683     /* here we need to generate the equates for the
2684        register bank if required */
2685 #if 0
2686     if (FUNC_REGBANK(ftype) != rbank) {
2687         int i ;
2688
2689         rbank = FUNC_REGBANK(ftype);
2690         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2691             if (strcmp(regspic14[i].base,"0") == 0)
2692                 pic14_emitcode("","%s = 0x%02x",
2693                          regspic14[i].dname,
2694                          8*rbank+regspic14[i].offset);
2695             else
2696                 pic14_emitcode ("","%s = %s + 0x%02x",
2697                           regspic14[i].dname,
2698                           regspic14[i].base,
2699                           8*rbank+regspic14[i].offset);
2700         }
2701     }
2702 #endif
2703
2704     /* if this is an interrupt service routine then
2705     save acc, b, dpl, dph  */
2706     if (IFFUNC_ISISR(sym->type)) {
2707       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2708       emitpcodeNULLop(POC_NOP);
2709       emitpcodeNULLop(POC_NOP);
2710       emitpcodeNULLop(POC_NOP);
2711       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2712       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2713       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2714       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2715
2716       pBlockConvert2ISR(pb);
2717 #if 0  
2718         if (!inExcludeList("acc"))          
2719             pic14_emitcode ("push","acc");      
2720         if (!inExcludeList("b"))
2721             pic14_emitcode ("push","b");
2722         if (!inExcludeList("dpl"))
2723             pic14_emitcode ("push","dpl");
2724         if (!inExcludeList("dph"))
2725             pic14_emitcode ("push","dph");
2726         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2727         {
2728             pic14_emitcode ("push", "dpx");
2729             /* Make sure we're using standard DPTR */
2730             pic14_emitcode ("push", "dps");
2731             pic14_emitcode ("mov", "dps, #0x00");
2732             if (options.stack10bit)
2733             {   
2734                 /* This ISR could conceivably use DPTR2. Better save it. */
2735                 pic14_emitcode ("push", "dpl1");
2736                 pic14_emitcode ("push", "dph1");
2737                 pic14_emitcode ("push", "dpx1");
2738             }
2739         }
2740         /* if this isr has no bank i.e. is going to
2741            run with bank 0 , then we need to save more
2742            registers :-) */
2743         if (!FUNC_REGBANK(sym->type)) {
2744
2745             /* if this function does not call any other
2746                function then we can be economical and
2747                save only those registers that are used */
2748             if (! IFFUNC_HASFCALL(sym->type)) {
2749                 int i;
2750
2751                 /* if any registers used */
2752                 if (sym->regsUsed) {
2753                     /* save the registers used */
2754                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2755                         if (bitVectBitValue(sym->regsUsed,i) ||
2756                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2757                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2758                     }
2759                 }
2760                 
2761             } else {
2762                 /* this function has  a function call cannot
2763                    determines register usage so we will have the
2764                    entire bank */
2765                 saverbank(0,ic,FALSE);
2766             }       
2767         }
2768 #endif
2769     } else {
2770         /* if callee-save to be used for this function
2771            then save the registers being used in this function */
2772         if (IFFUNC_CALLEESAVES(sym->type)) {
2773             int i;
2774             
2775             /* if any registers used */
2776             if (sym->regsUsed) {
2777                 /* save the registers used */
2778                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2779                     if (bitVectBitValue(sym->regsUsed,i) ||
2780                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2781                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2782                         _G.nRegsSaved++;
2783                     }
2784                 }
2785             }
2786         }
2787     }
2788
2789     /* set the register bank to the desired value */
2790     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2791         pic14_emitcode("push","psw");
2792         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2793     }
2794
2795     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2796
2797         if (options.useXstack) {
2798             pic14_emitcode("mov","r0,%s",spname);
2799             pic14_emitcode("mov","a,_bp");
2800             pic14_emitcode("movx","@r0,a");
2801             pic14_emitcode("inc","%s",spname);
2802         }
2803         else
2804         {
2805             /* set up the stack */
2806             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2807         }
2808         pic14_emitcode ("mov","_bp,%s",spname);
2809     }
2810
2811     /* adjust the stack for the function */
2812     if (sym->stack) {
2813
2814         int i = sym->stack;
2815         if (i > 256 ) 
2816             werror(W_STACK_OVERFLOW,sym->name);
2817
2818         if (i > 3 && sym->recvSize < 4) {              
2819
2820             pic14_emitcode ("mov","a,sp");
2821             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2822             pic14_emitcode ("mov","sp,a");
2823            
2824         }
2825         else
2826             while(i--)
2827                 pic14_emitcode("inc","sp");
2828     }
2829
2830      if (sym->xstack) {
2831
2832         pic14_emitcode ("mov","a,_spx");
2833         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2834         pic14_emitcode ("mov","_spx,a");
2835     }    
2836
2837 }
2838
2839 /*-----------------------------------------------------------------*/
2840 /* genEndFunction - generates epilogue for functions               */
2841 /*-----------------------------------------------------------------*/
2842 static void genEndFunction (iCode *ic)
2843 {
2844     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2845
2846     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2847
2848     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2849     {
2850         pic14_emitcode ("mov","%s,_bp",spname);
2851     }
2852
2853     /* if use external stack but some variables were
2854     added to the local stack then decrement the
2855     local stack */
2856     if (options.useXstack && sym->stack) {      
2857         pic14_emitcode("mov","a,sp");
2858         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2859         pic14_emitcode("mov","sp,a");
2860     }
2861
2862
2863     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2864         if (options.useXstack) {
2865             pic14_emitcode("mov","r0,%s",spname);
2866             pic14_emitcode("movx","a,@r0");
2867             pic14_emitcode("mov","_bp,a");
2868             pic14_emitcode("dec","%s",spname);
2869         }
2870         else
2871         {
2872             pic14_emitcode ("pop","_bp");
2873         }
2874     }
2875
2876     /* restore the register bank  */    
2877     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2878         pic14_emitcode ("pop","psw");
2879
2880     if (IFFUNC_ISISR(sym->type)) {
2881
2882         /* now we need to restore the registers */
2883         /* if this isr has no bank i.e. is going to
2884            run with bank 0 , then we need to save more
2885            registers :-) */
2886         if (!FUNC_REGBANK(sym->type)) {
2887             
2888             /* if this function does not call any other
2889                function then we can be economical and
2890                save only those registers that are used */
2891             if (! IFFUNC_HASFCALL(sym->type)) {
2892                 int i;
2893                 
2894                 /* if any registers used */
2895                 if (sym->regsUsed) {
2896                     /* save the registers used */
2897                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2898                         if (bitVectBitValue(sym->regsUsed,i) ||
2899                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2900                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2901                     }
2902                 }
2903                 
2904             } else {
2905                 /* this function has  a function call cannot
2906                    determines register usage so we will have the
2907                    entire bank */
2908                 unsaverbank(0,ic,FALSE);
2909             }       
2910         }
2911 #if 0
2912         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2913         {
2914             if (options.stack10bit)
2915             {
2916                 pic14_emitcode ("pop", "dpx1");
2917                 pic14_emitcode ("pop", "dph1");
2918                 pic14_emitcode ("pop", "dpl1");
2919             }   
2920             pic14_emitcode ("pop", "dps");
2921             pic14_emitcode ("pop", "dpx");
2922         }
2923         if (!inExcludeList("dph"))
2924             pic14_emitcode ("pop","dph");
2925         if (!inExcludeList("dpl"))
2926             pic14_emitcode ("pop","dpl");
2927         if (!inExcludeList("b"))
2928             pic14_emitcode ("pop","b");
2929         if (!inExcludeList("acc"))
2930             pic14_emitcode ("pop","acc");
2931
2932         if (IFFUNC_ISCRITICAL(sym->type))
2933             pic14_emitcode("setb","ea");
2934 #endif
2935
2936         /* if debug then send end of function */
2937 /*      if (options.debug && currFunc) { */
2938         if (currFunc) {
2939             _G.debugLine = 1;
2940             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2941                      FileBaseName(ic->filename),currFunc->lastLine,
2942                      ic->level,ic->block); 
2943             if (IS_STATIC(currFunc->etype))         
2944                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2945             else
2946                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2947             _G.debugLine = 0;
2948         }
2949         
2950         pic14_emitcode ("reti","");
2951
2952         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2953         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2954         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2955         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2956         emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2957         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2958
2959         emitpcodeNULLop(POC_RETFIE);
2960
2961     }
2962     else {
2963         if (IFFUNC_ISCRITICAL(sym->type))
2964             pic14_emitcode("setb","ea");
2965         
2966         if (IFFUNC_CALLEESAVES(sym->type)) {
2967             int i;
2968             
2969             /* if any registers used */
2970             if (sym->regsUsed) {
2971                 /* save the registers used */
2972                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2973                     if (bitVectBitValue(sym->regsUsed,i) ||
2974                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2975                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2976                 }
2977             }
2978             
2979         }
2980
2981         /* if debug then send end of function */
2982         if (currFunc) {
2983             _G.debugLine = 1;
2984             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2985                      FileBaseName(ic->filename),currFunc->lastLine,
2986                      ic->level,ic->block); 
2987             if (IS_STATIC(currFunc->etype))         
2988                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2989             else
2990                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2991             _G.debugLine = 0;
2992         }
2993
2994         pic14_emitcode ("return","");
2995         emitpcodeNULLop(POC_RETURN);
2996
2997         /* Mark the end of a function */
2998         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2999     }
3000
3001 }
3002
3003 /*-----------------------------------------------------------------*/
3004 /* genRet - generate code for return statement                     */
3005 /*-----------------------------------------------------------------*/
3006 static void genRet (iCode *ic)
3007 {
3008   int size,offset = 0 , pushed = 0;
3009     
3010   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3011   /* if we have no return value then
3012      just generate the "ret" */
3013   if (!IC_LEFT(ic)) 
3014     goto jumpret;       
3015     
3016   /* we have something to return then
3017      move the return value into place */
3018   aopOp(IC_LEFT(ic),ic,FALSE);
3019   size = AOP_SIZE(IC_LEFT(ic));
3020     
3021   while (size--) {
3022     char *l ;
3023     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3024       /* #NOCHANGE */
3025       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3026                  FALSE,TRUE);
3027       pic14_emitcode("push","%s",l);
3028       pushed++;
3029     } else {
3030       l = aopGet(AOP(IC_LEFT(ic)),offset,
3031                  FALSE,FALSE);
3032       if (strcmp(fReturn[offset],l)) {
3033         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3034             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3035           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3036         }else {
3037           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3038         }
3039         if(size) {
3040           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3041         }
3042         offset++;
3043       }
3044     }
3045   }    
3046
3047   if (pushed) {
3048     while(pushed) {
3049       pushed--;
3050       if (strcmp(fReturn[pushed],"a"))
3051         pic14_emitcode("pop",fReturn[pushed]);
3052       else
3053         pic14_emitcode("pop","acc");
3054     }
3055   }
3056   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3057     
3058  jumpret:
3059   /* generate a jump to the return label
3060      if the next is not the return statement */
3061   if (!(ic->next && ic->next->op == LABEL &&
3062         IC_LABEL(ic->next) == returnLabel)) {
3063         
3064     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3065     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3066   }
3067     
3068 }
3069
3070 /*-----------------------------------------------------------------*/
3071 /* genLabel - generates a label                                    */
3072 /*-----------------------------------------------------------------*/
3073 static void genLabel (iCode *ic)
3074 {
3075     /* special case never generate */
3076     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3077     if (IC_LABEL(ic) == entryLabel)
3078         return ;
3079
3080     emitpLabel(IC_LABEL(ic)->key);
3081     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3082 }
3083
3084 /*-----------------------------------------------------------------*/
3085 /* genGoto - generates a goto                                      */
3086 /*-----------------------------------------------------------------*/
3087 //tsd
3088 static void genGoto (iCode *ic)
3089 {
3090   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3091   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3092 }
3093
3094
3095 /*-----------------------------------------------------------------*/
3096 /* genMultbits :- multiplication of bits                           */
3097 /*-----------------------------------------------------------------*/
3098 static void genMultbits (operand *left, 
3099                          operand *right, 
3100                          operand *result)
3101 {
3102   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3103
3104   if(!pic14_sameRegs(AOP(result),AOP(right)))
3105     emitpcode(POC_BSF,  popGet(AOP(result),0));
3106
3107   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3108   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3109   emitpcode(POC_BCF,  popGet(AOP(result),0));
3110
3111 }
3112
3113
3114 /*-----------------------------------------------------------------*/
3115 /* genMultOneByte : 8 bit multiplication & division                */
3116 /*-----------------------------------------------------------------*/
3117 static void genMultOneByte (operand *left,
3118                             operand *right,
3119                             operand *result)
3120 {
3121   sym_link *opetype = operandType(result);
3122
3123   // symbol *lbl ;
3124   int size,offset;
3125
3126   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3127   DEBUGpic14_AopType(__LINE__,left,right,result);
3128   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3129
3130   /* (if two literals, the value is computed before) */
3131   /* if one literal, literal on the right */
3132   if (AOP_TYPE(left) == AOP_LIT){
3133     operand *t = right;
3134     right = left;
3135     left = t;
3136   }
3137
3138   size = AOP_SIZE(result);
3139   if(size == 1) {
3140
3141     if (AOP_TYPE(right) == AOP_LIT){
3142       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3143                      aopGet(AOP(right),0,FALSE,FALSE), 
3144                      aopGet(AOP(left),0,FALSE,FALSE), 
3145                      aopGet(AOP(result),0,FALSE,FALSE));
3146       pic14_emitcode("call","genMultLit");
3147     } else {
3148       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3149                      aopGet(AOP(right),0,FALSE,FALSE), 
3150                      aopGet(AOP(left),0,FALSE,FALSE), 
3151                      aopGet(AOP(result),0,FALSE,FALSE));
3152       pic14_emitcode("call","genMult8X8_8");
3153
3154     }
3155     genMult8X8_8 (left, right,result);
3156
3157
3158     /* signed or unsigned */
3159     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3160     //l = aopGet(AOP(left),0,FALSE,FALSE);
3161     //MOVA(l);       
3162     //pic14_emitcode("mul","ab");
3163     /* if result size = 1, mul signed = mul unsigned */
3164     //aopPut(AOP(result),"a",0);
3165
3166   } else {  // (size > 1)
3167
3168     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3169                    aopGet(AOP(right),0,FALSE,FALSE), 
3170                    aopGet(AOP(left),0,FALSE,FALSE), 
3171                    aopGet(AOP(result),0,FALSE,FALSE));
3172
3173     if (SPEC_USIGN(opetype)){
3174       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3175       genUMult8X8_16 (left, right, result, NULL);
3176
3177       if (size > 2) {
3178         /* for filling the MSBs */
3179         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3180         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3181       }
3182     }
3183     else{
3184       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3185
3186       pic14_emitcode("mov","a,b");
3187
3188       /* adjust the MSB if left or right neg */
3189
3190       /* if one literal */
3191       if (AOP_TYPE(right) == AOP_LIT){
3192         pic14_emitcode("multiply ","right is a lit");
3193         /* AND literal negative */
3194         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3195           /* adjust MSB (c==0 after mul) */
3196           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3197         }
3198       }
3199       else{
3200         genSMult8X8_16 (left, right, result, NULL);
3201       }
3202
3203       if(size > 2){
3204         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3205         /* get the sign */
3206         pic14_emitcode("rlc","a");
3207         pic14_emitcode("subb","a,acc");
3208       }
3209     }
3210
3211     size -= 2;   
3212     offset = 2;
3213     if (size > 0)
3214       while (size--)
3215         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3216     //aopPut(AOP(result),"a",offset++);
3217   }
3218 }
3219
3220 /*-----------------------------------------------------------------*/
3221 /* genMult - generates code for multiplication                     */
3222 /*-----------------------------------------------------------------*/
3223 static void genMult (iCode *ic)
3224 {
3225     operand *left = IC_LEFT(ic);
3226     operand *right = IC_RIGHT(ic);
3227     operand *result= IC_RESULT(ic);   
3228
3229     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3230     /* assign the amsops */
3231     aopOp (left,ic,FALSE);
3232     aopOp (right,ic,FALSE);
3233     aopOp (result,ic,TRUE);
3234
3235   DEBUGpic14_AopType(__LINE__,left,right,result);
3236
3237     /* special cases first */
3238     /* both are bits */
3239     if (AOP_TYPE(left) == AOP_CRY &&
3240         AOP_TYPE(right)== AOP_CRY) {
3241         genMultbits(left,right,result);
3242         goto release ;
3243     }
3244
3245     /* if both are of size == 1 */
3246     if (AOP_SIZE(left) == 1 &&
3247         AOP_SIZE(right) == 1 ) {
3248         genMultOneByte(left,right,result);
3249         goto release ;
3250     }
3251
3252     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3253
3254     /* should have been converted to function call */
3255     //assert(0) ;
3256
3257 release :
3258     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3259     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3260     freeAsmop(result,NULL,ic,TRUE); 
3261 }
3262
3263 /*-----------------------------------------------------------------*/
3264 /* genDivbits :- division of bits                                  */
3265 /*-----------------------------------------------------------------*/
3266 static void genDivbits (operand *left, 
3267                         operand *right, 
3268                         operand *result)
3269 {
3270
3271     char *l;
3272
3273     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3274     /* the result must be bit */    
3275     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3276     l = aopGet(AOP(left),0,FALSE,FALSE);
3277
3278     MOVA(l);    
3279
3280     pic14_emitcode("div","ab");
3281     pic14_emitcode("rrc","a");
3282     aopPut(AOP(result),"c",0);
3283 }
3284
3285 /*-----------------------------------------------------------------*/
3286 /* genDivOneByte : 8 bit division                                  */
3287 /*-----------------------------------------------------------------*/
3288 static void genDivOneByte (operand *left,
3289                            operand *right,
3290                            operand *result)
3291 {
3292     sym_link *opetype = operandType(result);
3293     char *l ;
3294     symbol *lbl ;
3295     int size,offset;
3296
3297     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3298     size = AOP_SIZE(result) - 1;
3299     offset = 1;
3300     /* signed or unsigned */
3301     if (SPEC_USIGN(opetype)) {
3302         /* unsigned is easy */
3303         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3304         l = aopGet(AOP(left),0,FALSE,FALSE);
3305         MOVA(l);        
3306         pic14_emitcode("div","ab");
3307         aopPut(AOP(result),"a",0);
3308         while (size--)
3309             aopPut(AOP(result),zero,offset++);
3310         return ;
3311     }
3312
3313     /* signed is a little bit more difficult */
3314
3315     /* save the signs of the operands */
3316     l = aopGet(AOP(left),0,FALSE,FALSE);    
3317     MOVA(l);    
3318     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3319     pic14_emitcode("push","acc"); /* save it on the stack */
3320
3321     /* now sign adjust for both left & right */
3322     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3323     MOVA(l);       
3324     lbl = newiTempLabel(NULL);
3325     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3326     pic14_emitcode("cpl","a");   
3327     pic14_emitcode("inc","a");
3328     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3329     pic14_emitcode("mov","b,a");
3330
3331     /* sign adjust left side */
3332     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3333     MOVA(l);
3334
3335     lbl = newiTempLabel(NULL);
3336     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3337     pic14_emitcode("cpl","a");
3338     pic14_emitcode("inc","a");
3339     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3340
3341     /* now the division */
3342     pic14_emitcode("div","ab");
3343     /* we are interested in the lower order
3344     only */
3345     pic14_emitcode("mov","b,a");
3346     lbl = newiTempLabel(NULL);
3347     pic14_emitcode("pop","acc");   
3348     /* if there was an over flow we don't 
3349     adjust the sign of the result */
3350     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3351     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3352     CLRC;
3353     pic14_emitcode("clr","a");
3354     pic14_emitcode("subb","a,b");
3355     pic14_emitcode("mov","b,a");
3356     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3357
3358     /* now we are done */
3359     aopPut(AOP(result),"b",0);
3360     if(size > 0){
3361         pic14_emitcode("mov","c,b.7");
3362         pic14_emitcode("subb","a,acc");   
3363     }
3364     while (size--)
3365         aopPut(AOP(result),"a",offset++);
3366
3367 }
3368
3369 /*-----------------------------------------------------------------*/
3370 /* genDiv - generates code for division                            */
3371 /*-----------------------------------------------------------------*/
3372 static void genDiv (iCode *ic)
3373 {
3374     operand *left = IC_LEFT(ic);
3375     operand *right = IC_RIGHT(ic);
3376     operand *result= IC_RESULT(ic);   
3377
3378     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3379     /* assign the amsops */
3380     aopOp (left,ic,FALSE);
3381     aopOp (right,ic,FALSE);
3382     aopOp (result,ic,TRUE);
3383
3384     /* special cases first */
3385     /* both are bits */
3386     if (AOP_TYPE(left) == AOP_CRY &&
3387         AOP_TYPE(right)== AOP_CRY) {
3388         genDivbits(left,right,result);
3389         goto release ;
3390     }
3391
3392     /* if both are of size == 1 */
3393     if (AOP_SIZE(left) == 1 &&
3394         AOP_SIZE(right) == 1 ) {
3395         genDivOneByte(left,right,result);
3396         goto release ;
3397     }
3398
3399     /* should have been converted to function call */
3400     assert(0);
3401 release :
3402     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3403     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3404     freeAsmop(result,NULL,ic,TRUE); 
3405 }
3406
3407 /*-----------------------------------------------------------------*/
3408 /* genModbits :- modulus of bits                                   */
3409 /*-----------------------------------------------------------------*/
3410 static void genModbits (operand *left, 
3411                         operand *right, 
3412                         operand *result)
3413 {
3414
3415     char *l;
3416
3417     /* the result must be bit */    
3418     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3419     l = aopGet(AOP(left),0,FALSE,FALSE);
3420
3421     MOVA(l);       
3422
3423     pic14_emitcode("div","ab");
3424     pic14_emitcode("mov","a,b");
3425     pic14_emitcode("rrc","a");
3426     aopPut(AOP(result),"c",0);
3427 }
3428
3429 /*-----------------------------------------------------------------*/
3430 /* genModOneByte : 8 bit modulus                                   */
3431 /*-----------------------------------------------------------------*/
3432 static void genModOneByte (operand *left,
3433                            operand *right,
3434                            operand *result)
3435 {
3436     sym_link *opetype = operandType(result);
3437     char *l ;
3438     symbol *lbl ;
3439
3440     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3441     /* signed or unsigned */
3442     if (SPEC_USIGN(opetype)) {
3443         /* unsigned is easy */
3444         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3445         l = aopGet(AOP(left),0,FALSE,FALSE);
3446         MOVA(l);    
3447         pic14_emitcode("div","ab");
3448         aopPut(AOP(result),"b",0);
3449         return ;
3450     }
3451
3452     /* signed is a little bit more difficult */
3453
3454     /* save the signs of the operands */
3455     l = aopGet(AOP(left),0,FALSE,FALSE);    
3456     MOVA(l);
3457
3458     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3459     pic14_emitcode("push","acc"); /* save it on the stack */
3460
3461     /* now sign adjust for both left & right */
3462     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3463     MOVA(l);
3464
3465     lbl = newiTempLabel(NULL);
3466     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3467     pic14_emitcode("cpl","a");   
3468     pic14_emitcode("inc","a");
3469     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3470     pic14_emitcode("mov","b,a"); 
3471
3472     /* sign adjust left side */
3473     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3474     MOVA(l);
3475
3476     lbl = newiTempLabel(NULL);
3477     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3478     pic14_emitcode("cpl","a");   
3479     pic14_emitcode("inc","a");
3480     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3481
3482     /* now the multiplication */
3483     pic14_emitcode("div","ab");
3484     /* we are interested in the lower order
3485     only */
3486     lbl = newiTempLabel(NULL);
3487     pic14_emitcode("pop","acc");   
3488     /* if there was an over flow we don't 
3489     adjust the sign of the result */
3490     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3491     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3492     CLRC ;
3493     pic14_emitcode("clr","a");
3494     pic14_emitcode("subb","a,b");
3495     pic14_emitcode("mov","b,a");
3496     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3497
3498     /* now we are done */
3499     aopPut(AOP(result),"b",0);
3500
3501 }
3502
3503 /*-----------------------------------------------------------------*/
3504 /* genMod - generates code for division                            */
3505 /*-----------------------------------------------------------------*/
3506 static void genMod (iCode *ic)
3507 {
3508     operand *left = IC_LEFT(ic);
3509     operand *right = IC_RIGHT(ic);
3510     operand *result= IC_RESULT(ic);  
3511
3512     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3513     /* assign the amsops */
3514     aopOp (left,ic,FALSE);
3515     aopOp (right,ic,FALSE);
3516     aopOp (result,ic,TRUE);
3517
3518     /* special cases first */
3519     /* both are bits */
3520     if (AOP_TYPE(left) == AOP_CRY &&
3521         AOP_TYPE(right)== AOP_CRY) {
3522         genModbits(left,right,result);
3523         goto release ;
3524     }
3525
3526     /* if both are of size == 1 */
3527     if (AOP_SIZE(left) == 1 &&
3528         AOP_SIZE(right) == 1 ) {
3529         genModOneByte(left,right,result);
3530         goto release ;
3531     }
3532
3533     /* should have been converted to function call */
3534     assert(0);
3535
3536 release :
3537     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3538     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3539     freeAsmop(result,NULL,ic,TRUE); 
3540 }
3541
3542 /*-----------------------------------------------------------------*/
3543 /* genIfxJump :- will create a jump depending on the ifx           */
3544 /*-----------------------------------------------------------------*/
3545 /*
3546   note: May need to add parameter to indicate when a variable is in bit space.
3547 */
3548 static void genIfxJump (iCode *ic, char *jval)
3549 {
3550
3551     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3552     /* if true label then we jump if condition
3553     supplied is true */
3554     if ( IC_TRUE(ic) ) {
3555
3556         if(strcmp(jval,"a") == 0)
3557           emitSKPZ;
3558         else if (strcmp(jval,"c") == 0)
3559           emitSKPC;
3560         else {
3561           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3562           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3563         }
3564
3565         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3566         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3567
3568     }
3569     else {
3570         /* false label is present */
3571         if(strcmp(jval,"a") == 0)
3572           emitSKPNZ;
3573         else if (strcmp(jval,"c") == 0)
3574           emitSKPNC;
3575         else {
3576           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3577           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3578         }
3579
3580         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3581         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3582
3583     }
3584
3585
3586     /* mark the icode as generated */
3587     ic->generated = 1;
3588 }
3589
3590 /*-----------------------------------------------------------------*/
3591 /* genSkip                                                         */
3592 /*-----------------------------------------------------------------*/
3593 static void genSkip(iCode *ifx,int status_bit)
3594 {
3595   if(!ifx)
3596     return;
3597
3598   if ( IC_TRUE(ifx) ) {
3599     switch(status_bit) {
3600     case 'z':
3601       emitSKPNZ;
3602       break;
3603
3604     case 'c':
3605       emitSKPNC;
3606       break;
3607
3608     case 'd':
3609       emitSKPDC;
3610       break;
3611
3612     }
3613
3614     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3615     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3616
3617   } else {
3618
3619     switch(status_bit) {
3620
3621     case 'z':
3622       emitSKPZ;
3623       break;
3624
3625     case 'c':
3626       emitSKPC;
3627       break;
3628
3629     case 'd':
3630       emitSKPDC;
3631       break;
3632     }
3633     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3634     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3635
3636   }
3637
3638 }
3639
3640 /*-----------------------------------------------------------------*/
3641 /* genSkipc                                                        */
3642 /*-----------------------------------------------------------------*/
3643 static void genSkipc(resolvedIfx *rifx)
3644 {
3645   if(!rifx)
3646     return;
3647
3648   if(rifx->condition)
3649     emitSKPC;
3650   else
3651     emitSKPNC;
3652
3653   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3654   rifx->generated = 1;
3655 }
3656
3657 /*-----------------------------------------------------------------*/
3658 /* genSkipz2                                                       */
3659 /*-----------------------------------------------------------------*/
3660 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3661 {
3662   if(!rifx)
3663     return;
3664
3665   if( (rifx->condition ^ invert_condition) & 1)
3666     emitSKPZ;
3667   else
3668     emitSKPNZ;
3669
3670   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3671   rifx->generated = 1;
3672 }
3673
3674 /*-----------------------------------------------------------------*/
3675 /* genSkipz                                                        */
3676 /*-----------------------------------------------------------------*/
3677 static void genSkipz(iCode *ifx, int condition)
3678 {
3679   if(!ifx)
3680     return;
3681
3682   if(condition)
3683     emitSKPNZ;
3684   else
3685     emitSKPZ;
3686
3687   if ( IC_TRUE(ifx) )
3688     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3689   else
3690     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3691
3692   if ( IC_TRUE(ifx) )
3693     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3694   else
3695     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3696
3697 }
3698 /*-----------------------------------------------------------------*/
3699 /* genSkipCond                                                     */
3700 /*-----------------------------------------------------------------*/
3701 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3702 {
3703   if(!rifx)
3704     return;
3705
3706   if(rifx->condition)
3707     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3708   else
3709     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3710
3711
3712   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3713   rifx->generated = 1;
3714 }
3715
3716 #if 0
3717 /*-----------------------------------------------------------------*/
3718 /* genChkZeroes :- greater or less than comparison                 */
3719 /*     For each byte in a literal that is zero, inclusive or the   */
3720 /*     the corresponding byte in the operand with W                */
3721 /*     returns true if any of the bytes are zero                   */
3722 /*-----------------------------------------------------------------*/
3723 static int genChkZeroes(operand *op, int lit,  int size)
3724 {
3725
3726   int i;
3727   int flag =1;
3728
3729   while(size--) {
3730     i = (lit >> (size*8)) & 0xff;
3731
3732     if(i==0) {
3733       if(flag) 
3734         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3735       else
3736         emitpcode(POC_IORFW, popGet(AOP(op),size));
3737       flag = 0;
3738     }
3739   }
3740
3741   return (flag==0);
3742 }
3743 #endif
3744
3745 /*-----------------------------------------------------------------*/
3746 /* genCmp :- greater or less than comparison                       */
3747 /*-----------------------------------------------------------------*/
3748 static void genCmp (operand *left,operand *right,
3749                     operand *result, iCode *ifx, int sign)
3750 {
3751   int size; //, offset = 0 ;
3752   unsigned long lit = 0L,i = 0;
3753   resolvedIfx rFalseIfx;
3754   //  resolvedIfx rTrueIfx;
3755   symbol *truelbl;
3756   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3757 /*
3758   if(ifx) {
3759     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3760     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3761   }
3762 */
3763
3764   resolveIfx(&rFalseIfx,ifx);
3765   truelbl  = newiTempLabel(NULL);
3766   size = max(AOP_SIZE(left),AOP_SIZE(right));
3767
3768   DEBUGpic14_AopType(__LINE__,left,right,result);
3769
3770 #define _swapp
3771
3772   /* if literal is on the right then swap with left */
3773   if ((AOP_TYPE(right) == AOP_LIT)) {
3774     operand *tmp = right ;
3775     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3776     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3777 #ifdef _swapp
3778
3779     lit = (lit - 1) & mask;
3780     right = left;
3781     left = tmp;
3782     rFalseIfx.condition ^= 1;
3783 #endif
3784
3785   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3786     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3787   }
3788
3789
3790   //if(IC_TRUE(ifx) == NULL)
3791   /* if left & right are bit variables */
3792   if (AOP_TYPE(left) == AOP_CRY &&
3793       AOP_TYPE(right) == AOP_CRY ) {
3794     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3795     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3796   } else {
3797     /* subtract right from left if at the
3798        end the carry flag is set then we know that
3799        left is greater than right */
3800
3801     //    {
3802
3803     symbol *lbl  = newiTempLabel(NULL);
3804
3805 #ifndef _swapp
3806     if(AOP_TYPE(right) == AOP_LIT) {
3807
3808       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3809
3810       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3811
3812       /* special cases */
3813
3814       if(lit == 0) {
3815
3816         if(sign != 0) 
3817           genSkipCond(&rFalseIfx,left,size-1,7);
3818         else 
3819           /* no need to compare to 0...*/
3820           /* NOTE: this is a de-generate compare that most certainly 
3821            *       creates some dead code. */
3822           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3823
3824         if(ifx) ifx->generated = 1;
3825         return;
3826
3827       }
3828       size--;
3829
3830       if(size == 0) {
3831         //i = (lit >> (size*8)) & 0xff;
3832         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3833         
3834         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3835
3836         i = ((0-lit) & 0xff);
3837         if(sign) {
3838           if( i == 0x81) { 
3839             /* lit is 0x7f, all signed chars are less than
3840              * this except for 0x7f itself */
3841             emitpcode(POC_XORLW, popGetLit(0x7f));
3842             genSkipz2(&rFalseIfx,0);
3843           } else {
3844             emitpcode(POC_ADDLW, popGetLit(0x80));
3845             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3846             genSkipc(&rFalseIfx);
3847           }
3848
3849         } else {
3850           if(lit == 1) {
3851             genSkipz2(&rFalseIfx,1);
3852           } else {
3853             emitpcode(POC_ADDLW, popGetLit(i));
3854             genSkipc(&rFalseIfx);
3855           }
3856         }
3857
3858         if(ifx) ifx->generated = 1;
3859         return;
3860       }
3861
3862       /* chars are out of the way. now do ints and longs */
3863
3864
3865       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3866         
3867       /* special cases */
3868
3869       if(sign) {
3870
3871         if(lit == 0) {
3872           genSkipCond(&rFalseIfx,left,size,7);
3873           if(ifx) ifx->generated = 1;
3874           return;
3875         }
3876
3877         if(lit <0x100) {
3878           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3879
3880           //rFalseIfx.condition ^= 1;
3881           //genSkipCond(&rFalseIfx,left,size,7);
3882           //rFalseIfx.condition ^= 1;
3883
3884           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3885           if(rFalseIfx.condition)
3886             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3887           else
3888             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3889
3890           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3891           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3892           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3893
3894           while(size > 1)
3895             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3896
3897           if(rFalseIfx.condition) {
3898             emitSKPZ;
3899             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3900
3901           } else {
3902             emitSKPNZ;
3903           }
3904
3905           genSkipc(&rFalseIfx);
3906           emitpLabel(truelbl->key);
3907           if(ifx) ifx->generated = 1;
3908           return;
3909
3910         }
3911
3912         if(size == 1) {
3913
3914           if( (lit & 0xff) == 0) {
3915             /* lower byte is zero */
3916             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3917             i = ((lit >> 8) & 0xff) ^0x80;
3918             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3919             emitpcode(POC_ADDLW, popGetLit( 0x80));
3920             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3921             genSkipc(&rFalseIfx);
3922
3923
3924             if(ifx) ifx->generated = 1;
3925             return;
3926
3927           }
3928         } else {
3929           /* Special cases for signed longs */
3930           if( (lit & 0xffffff) == 0) {
3931             /* lower byte is zero */
3932             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3933             i = ((lit >> 8*3) & 0xff) ^0x80;
3934             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3935             emitpcode(POC_ADDLW, popGetLit( 0x80));
3936             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3937             genSkipc(&rFalseIfx);
3938
3939
3940             if(ifx) ifx->generated = 1;
3941             return;
3942
3943           }
3944
3945         }
3946
3947
3948         if(lit & (0x80 << (size*8))) {
3949           /* lit is negative */
3950           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3951
3952           //genSkipCond(&rFalseIfx,left,size,7);
3953
3954           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3955
3956           if(rFalseIfx.condition)
3957             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3958           else
3959             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3960
3961
3962         } else {
3963           /* lit is positive */
3964           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3965           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3966           if(rFalseIfx.condition)
3967             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3968           else
3969             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3970
3971         }
3972
3973         /*
3974           This works, but is only good for ints.
3975           It also requires a "known zero" register.
3976           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3977           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3978           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3979           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3980           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3981           genSkipc(&rFalseIfx);
3982
3983           emitpLabel(truelbl->key);
3984           if(ifx) ifx->generated = 1;
3985           return;
3986         **/
3987           
3988         /* There are no more special cases, so perform a general compare */
3989   
3990         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3991         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3992
3993         while(size--) {
3994
3995           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3996           emitSKPNZ;
3997           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3998         }
3999         //rFalseIfx.condition ^= 1;
4000         genSkipc(&rFalseIfx);
4001
4002         emitpLabel(truelbl->key);
4003
4004         if(ifx) ifx->generated = 1;
4005         return;
4006
4007
4008       }
4009
4010
4011       /* sign is out of the way. So now do an unsigned compare */
4012       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4013
4014
4015       /* General case - compare to an unsigned literal on the right.*/
4016
4017       i = (lit >> (size*8)) & 0xff;
4018       emitpcode(POC_MOVLW, popGetLit(i));
4019       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4020       while(size--) {
4021         i = (lit >> (size*8)) & 0xff;
4022
4023         if(i) {
4024           emitpcode(POC_MOVLW, popGetLit(i));
4025           emitSKPNZ;
4026           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4027         } else {
4028           /* this byte of the lit is zero, 
4029            *if it's not the last then OR in the variable */
4030           if(size)
4031             emitpcode(POC_IORFW, popGet(AOP(left),size));
4032         }
4033       }
4034
4035
4036       emitpLabel(lbl->key);
4037       //if(emitFinalCheck)
4038       genSkipc(&rFalseIfx);
4039       if(sign)
4040         emitpLabel(truelbl->key);
4041
4042       if(ifx) ifx->generated = 1;
4043       return;
4044
4045
4046     }
4047 #endif  // _swapp
4048
4049     if(AOP_TYPE(left) == AOP_LIT) {
4050       //symbol *lbl = newiTempLabel(NULL);
4051
4052       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4053
4054
4055       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4056
4057       /* Special cases */
4058       if((lit == 0) && (sign == 0)){
4059
4060         size--;
4061         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4062         while(size) 
4063           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4064
4065         genSkipz2(&rFalseIfx,0);
4066         if(ifx) ifx->generated = 1;
4067         return;
4068       }
4069
4070       if(size==1) {
4071         /* Special cases */
4072         lit &= 0xff;
4073         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4074           /* degenerate compare can never be true */
4075           if(rFalseIfx.condition == 0)
4076             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4077
4078           if(ifx) ifx->generated = 1;
4079           return;
4080         }
4081
4082         if(sign) {
4083           /* signed comparisons to a literal byte */
4084
4085           int lp1 = (lit+1) & 0xff;
4086
4087           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4088           switch (lp1) {
4089           case 0:
4090             rFalseIfx.condition ^= 1;
4091             genSkipCond(&rFalseIfx,right,0,7);
4092             break;
4093           case 0x7f:
4094             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4095             emitpcode(POC_XORLW, popGetLit(0x7f));
4096             genSkipz2(&rFalseIfx,1);
4097             break;
4098           default:
4099             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4100             emitpcode(POC_ADDLW, popGetLit(0x80));
4101             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4102             rFalseIfx.condition ^= 1;
4103             genSkipc(&rFalseIfx);
4104             break;
4105           }
4106         } else {
4107           /* unsigned comparisons to a literal byte */
4108
4109           switch(lit & 0xff ) {
4110           case 0:
4111             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4112             genSkipz2(&rFalseIfx,0);
4113             break;
4114           case 0x7f:
4115             rFalseIfx.condition ^= 1;
4116             genSkipCond(&rFalseIfx,right,0,7);
4117             break;
4118
4119           default:
4120             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4121             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4122             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4123             rFalseIfx.condition ^= 1;
4124             if (AOP_TYPE(result) == AOP_CRY)
4125               genSkipc(&rFalseIfx);
4126             else {
4127               emitpcode(POC_CLRF, popGet(AOP(result),0));
4128               emitpcode(POC_RLF, popGet(AOP(result),0));
4129             }         
4130             break;
4131           }
4132         }
4133
4134         if(ifx) ifx->generated = 1;
4135         //goto check_carry;
4136         return;
4137
4138       } else {
4139
4140         /* Size is greater than 1 */
4141
4142         if(sign) {
4143           int lp1 = lit+1;
4144
4145           size--;
4146
4147           if(lp1 == 0) {
4148             /* this means lit = 0xffffffff, or -1 */
4149
4150
4151             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4152             rFalseIfx.condition ^= 1;
4153             genSkipCond(&rFalseIfx,right,size,7);
4154             if(ifx) ifx->generated = 1;
4155             return;
4156           }
4157
4158           if(lit == 0) {
4159             int s = size;
4160
4161             if(rFalseIfx.condition) {
4162               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4163               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4164             }
4165
4166             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4167             while(size--)
4168               emitpcode(POC_IORFW, popGet(AOP(right),size));
4169
4170
4171             emitSKPZ;
4172             if(rFalseIfx.condition) {
4173               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4174               emitpLabel(truelbl->key);
4175             }else {
4176               rFalseIfx.condition ^= 1;
4177               genSkipCond(&rFalseIfx,right,s,7);
4178             }
4179
4180             if(ifx) ifx->generated = 1;
4181             return;
4182           }
4183
4184           if((size == 1) &&  (0 == (lp1&0xff))) {
4185             /* lower byte of signed word is zero */
4186             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4187             i = ((lp1 >> 8) & 0xff) ^0x80;
4188             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4189             emitpcode(POC_ADDLW, popGetLit( 0x80));
4190             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4191             rFalseIfx.condition ^= 1;
4192             genSkipc(&rFalseIfx);
4193
4194
4195             if(ifx) ifx->generated = 1;
4196             return;
4197           }
4198
4199           if(lit & (0x80 << (size*8))) {
4200             /* Lit is less than zero */
4201             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4202             //rFalseIfx.condition ^= 1;
4203             //genSkipCond(&rFalseIfx,left,size,7);
4204             //rFalseIfx.condition ^= 1;
4205             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4206             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4207
4208             if(rFalseIfx.condition)
4209               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4210             else
4211               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4212
4213
4214           } else {
4215             /* Lit is greater than or equal to zero */
4216             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4217             //rFalseIfx.condition ^= 1;
4218             //genSkipCond(&rFalseIfx,right,size,7);
4219             //rFalseIfx.condition ^= 1;
4220
4221             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4222             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4223
4224             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4225             if(rFalseIfx.condition)
4226               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4227             else
4228               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4229
4230           }
4231
4232
4233           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4234           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4235
4236           while(size--) {
4237
4238             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4239             emitSKPNZ;
4240             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4241           }
4242           rFalseIfx.condition ^= 1;
4243           //rFalseIfx.condition = 1;
4244           genSkipc(&rFalseIfx);
4245
4246           emitpLabel(truelbl->key);
4247
4248           if(ifx) ifx->generated = 1;
4249           return;
4250           // end of if (sign)
4251         } else {
4252
4253           /* compare word or long to an unsigned literal on the right.*/
4254
4255
4256           size--;
4257           if(lit < 0xff) {
4258             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4259             switch (lit) {
4260             case 0:
4261               break; /* handled above */
4262 /*
4263             case 0xff:
4264               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4265               while(size--)
4266                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4267               genSkipz2(&rFalseIfx,0);
4268               break;
4269 */
4270             default:
4271               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4272               while(--size)
4273                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4274
4275               emitSKPZ;
4276               if(rFalseIfx.condition)
4277                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4278               else
4279                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4280
4281
4282               emitpcode(POC_MOVLW, popGetLit(lit+1));
4283               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4284
4285               rFalseIfx.condition ^= 1;
4286               genSkipc(&rFalseIfx);
4287             }
4288
4289             emitpLabel(truelbl->key);
4290
4291             if(ifx) ifx->generated = 1;
4292             return;
4293           }
4294
4295
4296           lit++;
4297           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4298           i = (lit >> (size*8)) & 0xff;
4299
4300           emitpcode(POC_MOVLW, popGetLit(i));
4301           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4302
4303           while(size--) {
4304             i = (lit >> (size*8)) & 0xff;
4305
4306             if(i) {
4307               emitpcode(POC_MOVLW, popGetLit(i));
4308               emitSKPNZ;
4309               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4310             } else {
4311               /* this byte of the lit is zero, 
4312                *if it's not the last then OR in the variable */
4313               if(size)
4314                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4315             }
4316           }
4317
4318
4319           emitpLabel(lbl->key);
4320
4321           rFalseIfx.condition ^= 1;
4322           genSkipc(&rFalseIfx);
4323         }
4324
4325         if(sign)
4326           emitpLabel(truelbl->key);
4327         if(ifx) ifx->generated = 1;
4328         return;
4329       }
4330     }
4331     /* Compare two variables */
4332
4333     DEBUGpic14_emitcode(";sign","%d",sign);
4334
4335     size--;
4336     if(sign) {
4337       /* Sigh. thus sucks... */
4338       if(size) {
4339         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4340         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4341         emitpcode(POC_MOVLW, popGetLit(0x80));
4342         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4343         emitpcode(POC_XORFW, popGet(AOP(right),size));
4344         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4345       } else {
4346         /* Signed char comparison */
4347         /* Special thanks to Nikolai Golovchenko for this snippet */
4348         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4349         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4350         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4351         emitpcode(POC_XORFW, popGet(AOP(left),0));
4352         emitpcode(POC_XORFW, popGet(AOP(right),0));
4353         emitpcode(POC_ADDLW, popGetLit(0x80));
4354
4355         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4356         genSkipc(&rFalseIfx);
4357           
4358         if(ifx) ifx->generated = 1;
4359         return;
4360       }
4361
4362     } else {
4363
4364       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4365       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4366     }
4367
4368
4369     /* The rest of the bytes of a multi-byte compare */
4370     while (size) {
4371
4372       emitSKPZ;
4373       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4374       size--;
4375
4376       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4377       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4378
4379
4380     }
4381
4382     emitpLabel(lbl->key);
4383
4384     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4385     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4386         (AOP_TYPE(result) == AOP_REG)) {
4387       emitpcode(POC_CLRF, popGet(AOP(result),0));
4388       emitpcode(POC_RLF, popGet(AOP(result),0));
4389     } else {
4390       genSkipc(&rFalseIfx);
4391     }         
4392     //genSkipc(&rFalseIfx);
4393     if(ifx) ifx->generated = 1;
4394
4395     return;
4396
4397   }
4398
4399   // check_carry:
4400   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4401     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4402     pic14_outBitC(result);
4403   } else {
4404     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4405     /* if the result is used in the next
4406        ifx conditional branch then generate
4407        code a little differently */
4408     if (ifx )
4409       genIfxJump (ifx,"c");
4410     else
4411       pic14_outBitC(result);
4412     /* leave the result in acc */
4413   }
4414
4415 }
4416
4417 /*-----------------------------------------------------------------*/
4418 /* genCmpGt :- greater than comparison                             */
4419 /*-----------------------------------------------------------------*/
4420 static void genCmpGt (iCode *ic, iCode *ifx)
4421 {
4422     operand *left, *right, *result;
4423     sym_link *letype , *retype;
4424     int sign ;
4425
4426     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4427     left = IC_LEFT(ic);
4428     right= IC_RIGHT(ic);
4429     result = IC_RESULT(ic);
4430
4431     letype = getSpec(operandType(left));
4432     retype =getSpec(operandType(right));
4433     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4434     /* assign the amsops */
4435     aopOp (left,ic,FALSE);
4436     aopOp (right,ic,FALSE);
4437     aopOp (result,ic,TRUE);
4438
4439     genCmp(right, left, result, ifx, sign);
4440
4441     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4443     freeAsmop(result,NULL,ic,TRUE); 
4444 }
4445
4446 /*-----------------------------------------------------------------*/
4447 /* genCmpLt - less than comparisons                                */
4448 /*-----------------------------------------------------------------*/
4449 static void genCmpLt (iCode *ic, iCode *ifx)
4450 {
4451     operand *left, *right, *result;
4452     sym_link *letype , *retype;
4453     int sign ;
4454
4455     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4456     left = IC_LEFT(ic);
4457     right= IC_RIGHT(ic);
4458     result = IC_RESULT(ic);
4459
4460     letype = getSpec(operandType(left));
4461     retype =getSpec(operandType(right));
4462     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4463
4464     /* assign the amsops */
4465     aopOp (left,ic,FALSE);
4466     aopOp (right,ic,FALSE);
4467     aopOp (result,ic,TRUE);
4468
4469     genCmp(left, right, result, ifx, sign);
4470
4471     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4473     freeAsmop(result,NULL,ic,TRUE); 
4474 }
4475
4476 /*-----------------------------------------------------------------*/
4477 /* genc16bit2lit - compare a 16 bit value to a literal             */
4478 /*-----------------------------------------------------------------*/
4479 static void genc16bit2lit(operand *op, int lit, int offset)
4480 {
4481   int i;
4482
4483   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4484   if( (lit&0xff) == 0) 
4485     i=1;
4486   else
4487     i=0;
4488
4489   switch( BYTEofLONG(lit,i)) { 
4490   case 0:
4491     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4492     break;
4493   case 1:
4494     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4495     break;
4496   case 0xff:
4497     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4498     break;
4499   default:
4500     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4501     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4502   }
4503
4504   i ^= 1;
4505
4506   switch( BYTEofLONG(lit,i)) { 
4507   case 0:
4508     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4509     break;
4510   case 1:
4511     emitSKPNZ;
4512     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4513     break;
4514   case 0xff:
4515     emitSKPNZ;
4516     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4517     break;
4518   default:
4519     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4520     emitSKPNZ;
4521     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4522
4523   }
4524
4525 }
4526
4527 /*-----------------------------------------------------------------*/
4528 /* gencjneshort - compare and jump if not equal                    */
4529 /*-----------------------------------------------------------------*/
4530 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4531 {
4532   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4533   int offset = 0;
4534   int res_offset = 0;  /* the result may be a different size then left or right */
4535   int res_size = AOP_SIZE(result);
4536   resolvedIfx rIfx;
4537   symbol *lbl;
4538
4539   unsigned long lit = 0L;
4540   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4541   DEBUGpic14_AopType(__LINE__,left,right,result);
4542   if(result)
4543     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4544   resolveIfx(&rIfx,ifx);
4545   lbl =  newiTempLabel(NULL);
4546
4547
4548   /* if the left side is a literal or 
4549      if the right is in a pointer register and left 
4550      is not */
4551   if ((AOP_TYPE(left) == AOP_LIT) || 
4552       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4553     operand *t = right;
4554     right = left;
4555     left = t;
4556   }
4557   if(AOP_TYPE(right) == AOP_LIT)
4558     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4559
4560   /* if the right side is a literal then anything goes */
4561   if (AOP_TYPE(right) == AOP_LIT &&
4562       AOP_TYPE(left) != AOP_DIR ) {
4563     switch(size) {
4564     case 2:
4565       genc16bit2lit(left, lit, 0);
4566       emitSKPNZ;
4567       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4568       break;
4569     default:
4570       while (size--) {
4571         if(lit & 0xff) {
4572           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4573           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4574         } else {
4575           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4576         }
4577
4578         emitSKPNZ;
4579         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4580         offset++;
4581         if(res_offset < res_size-1)
4582           res_offset++;
4583         lit >>= 8;
4584       }
4585       break;
4586     }
4587   }
4588
4589   /* if the right side is in a register or in direct space or
4590      if the left is a pointer register & right is not */    
4591   else if (AOP_TYPE(right) == AOP_REG ||
4592            AOP_TYPE(right) == AOP_DIR || 
4593            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4594            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4595     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4596     int lbl_key = lbl->key;
4597
4598     if(result) {
4599       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4600       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4601     }else {
4602       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4603       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4604               __FUNCTION__,__LINE__);
4605       return;
4606     }
4607
4608 /*     switch(size) { */
4609 /*     case 2: */
4610 /*       genc16bit2lit(left, lit, 0); */
4611 /*       emitSKPNZ; */
4612 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4613 /*       break; */
4614 /*     default: */
4615     while (size--) {
4616       int emit_skip=1;
4617       if((AOP_TYPE(left) == AOP_DIR) && 
4618          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4619
4620         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4621         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4622
4623       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4624             
4625         switch (lit & 0xff) {
4626         case 0:
4627           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4628           break;
4629         case 1:
4630           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4631           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4632           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4633           emit_skip=0;
4634           break;
4635         case 0xff:
4636           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4638           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4639           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4640           emit_skip=0;
4641           break;
4642         default:
4643           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4644           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4645         }
4646         lit >>= 8;
4647
4648       } else {
4649         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4650       }
4651       if(emit_skip) {
4652         if(AOP_TYPE(result) == AOP_CRY) {
4653           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4654           if(rIfx.condition)
4655             emitSKPNZ;
4656           else
4657             emitSKPZ;
4658           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4659         } else {
4660           /* fix me. probably need to check result size too */
4661           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4662           if(rIfx.condition)
4663             emitSKPZ;
4664           else
4665             emitSKPNZ;
4666           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4667           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4668         }
4669         if(ifx)
4670           ifx->generated=1;
4671       }
4672       emit_skip++;
4673       offset++;
4674       if(res_offset < res_size-1)
4675         res_offset++;
4676     }
4677 /*       break; */
4678 /*     } */
4679   } else if(AOP_TYPE(right) == AOP_REG &&
4680             AOP_TYPE(left) != AOP_DIR){
4681
4682     while(size--) {
4683       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4684       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4685       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4686       if(rIfx.condition)
4687         emitSKPNZ;
4688       else
4689         emitSKPZ;
4690       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4691       offset++;
4692       if(res_offset < res_size-1)
4693         res_offset++;
4694     }
4695       
4696   }else{
4697     /* right is a pointer reg need both a & b */
4698     while(size--) {
4699       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4700       if(strcmp(l,"b"))
4701         pic14_emitcode("mov","b,%s",l);
4702       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4703       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4704       offset++;
4705     }
4706   }
4707
4708   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4709   if(!rIfx.condition)
4710     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4711
4712   emitpLabel(lbl->key);
4713
4714   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4715
4716   if(ifx)
4717     ifx->generated = 1;
4718 }
4719
4720 #if 0
4721 /*-----------------------------------------------------------------*/
4722 /* gencjne - compare and jump if not equal                         */
4723 /*-----------------------------------------------------------------*/
4724 static void gencjne(operand *left, operand *right, iCode *ifx)
4725 {
4726     symbol *tlbl  = newiTempLabel(NULL);
4727
4728     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4729     gencjneshort(left, right, lbl);
4730
4731     pic14_emitcode("mov","a,%s",one);
4732     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4733     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4734     pic14_emitcode("clr","a");
4735     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4736
4737     emitpLabel(lbl->key);
4738     emitpLabel(tlbl->key);
4739
4740 }
4741 #endif
4742
4743 /*-----------------------------------------------------------------*/
4744 /* genCmpEq - generates code for equal to                          */
4745 /*-----------------------------------------------------------------*/
4746 static void genCmpEq (iCode *ic, iCode *ifx)
4747 {
4748     operand *left, *right, *result;
4749     unsigned long lit = 0L;
4750     int size,offset=0;
4751
4752     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4753
4754     if(ifx)
4755       DEBUGpic14_emitcode ("; ifx is non-null","");
4756     else
4757       DEBUGpic14_emitcode ("; ifx is null","");
4758
4759     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4760     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4761     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4762
4763     size = max(AOP_SIZE(left),AOP_SIZE(right));
4764
4765     DEBUGpic14_AopType(__LINE__,left,right,result);
4766
4767     /* if literal, literal on the right or 
4768     if the right is in a pointer register and left 
4769     is not */
4770     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4771         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4772       operand *tmp = right ;
4773       right = left;
4774       left = tmp;
4775     }
4776
4777
4778     if(ifx && !AOP_SIZE(result)){
4779         symbol *tlbl;
4780         /* if they are both bit variables */
4781         if (AOP_TYPE(left) == AOP_CRY &&
4782             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4783             if(AOP_TYPE(right) == AOP_LIT){
4784                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4785                 if(lit == 0L){
4786                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4787                     pic14_emitcode("cpl","c");
4788                 } else if(lit == 1L) {
4789                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4790                 } else {
4791                     pic14_emitcode("clr","c");
4792                 }
4793                 /* AOP_TYPE(right) == AOP_CRY */
4794             } else {
4795                 symbol *lbl = newiTempLabel(NULL);
4796                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4797                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4798                 pic14_emitcode("cpl","c");
4799                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4800             }
4801             /* if true label then we jump if condition
4802             supplied is true */
4803             tlbl = newiTempLabel(NULL);
4804             if ( IC_TRUE(ifx) ) {
4805                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4806                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4807             } else {
4808                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4809                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4810             }
4811             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4812
4813             {
4814               /* left and right are both bit variables, result is carry */
4815               resolvedIfx rIfx;
4816               
4817               resolveIfx(&rIfx,ifx);
4818
4819               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4820               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4821               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4822               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4823               genSkipz2(&rIfx,0);
4824             }
4825         } else {
4826
4827           /* They're not both bit variables. Is the right a literal? */
4828           if(AOP_TYPE(right) == AOP_LIT) {
4829             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4830             
4831             switch(size) {
4832
4833             case 1:
4834               switch(lit & 0xff) {
4835               case 1:
4836                 if ( IC_TRUE(ifx) ) {
4837                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4838                   emitSKPNZ;
4839                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4840                 } else {
4841                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4842                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4843                 }
4844                 break;
4845               case 0xff:
4846                 if ( IC_TRUE(ifx) ) {
4847                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4848                   emitSKPNZ;
4849                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4850                 } else {
4851                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4852                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4853                 }
4854                 break;
4855               default:
4856                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4857                 if(lit)
4858                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4859                 genSkip(ifx,'z');
4860               }
4861
4862
4863               /* end of size == 1 */
4864               break;
4865               
4866             case 2:
4867               genc16bit2lit(left,lit,offset);
4868               genSkip(ifx,'z');
4869               break;
4870               /* end of size == 2 */
4871
4872             default:
4873               /* size is 4 */
4874               if(lit==0) {
4875                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4876                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4877                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4878                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4879
4880               } else {
4881
4882                 /* search for patterns that can be optimized */
4883
4884                 genc16bit2lit(left,lit,0);
4885                 lit >>= 16;
4886                 if(lit) {
4887                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4888                   //genSkip(ifx,'z');
4889                   genc16bit2lit(left,lit,2);
4890                 } else {
4891                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4892                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4893
4894                 }
4895                 
4896               }
4897
4898               genSkip(ifx,'z');
4899             }
4900           
4901             ifx->generated = 1;
4902             goto release ;
4903             
4904
4905           } else if(AOP_TYPE(right) == AOP_CRY ) {
4906             /* we know the left is not a bit, but that the right is */
4907             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4908             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4909                       popGet(AOP(right),offset));
4910             emitpcode(POC_XORLW,popGetLit(1));
4911
4912             /* if the two are equal, then W will be 0 and the Z bit is set
4913              * we could test Z now, or go ahead and check the high order bytes if
4914              * the variable we're comparing is larger than a byte. */
4915
4916             while(--size)
4917               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4918
4919             if ( IC_TRUE(ifx) ) {
4920               emitSKPNZ;
4921               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4922               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4923             } else {
4924               emitSKPZ;
4925               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4926               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4927             }
4928
4929           } else {
4930             /* They're both variables that are larger than bits */
4931             int s = size;
4932
4933             tlbl = newiTempLabel(NULL);
4934
4935             while(size--) {
4936               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4937               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4938
4939               if ( IC_TRUE(ifx) ) {
4940                 if(size) {
4941                   emitSKPZ;
4942                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4943                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4944                 } else {
4945                   emitSKPNZ;
4946                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4947                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4948                 }
4949               } else {
4950                 emitSKPZ;
4951                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4952                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4953               }
4954               offset++;
4955             }
4956             if(s>1 && IC_TRUE(ifx)) {
4957               emitpLabel(tlbl->key);
4958               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4959             }
4960           }
4961         }
4962         /* mark the icode as generated */
4963         ifx->generated = 1;
4964         goto release ;
4965     }
4966
4967     /* if they are both bit variables */
4968     if (AOP_TYPE(left) == AOP_CRY &&
4969         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4970         if(AOP_TYPE(right) == AOP_LIT){
4971             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4972             if(lit == 0L){
4973                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4974                 pic14_emitcode("cpl","c");
4975             } else if(lit == 1L) {
4976                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4977             } else {
4978                 pic14_emitcode("clr","c");
4979             }
4980             /* AOP_TYPE(right) == AOP_CRY */
4981         } else {
4982             symbol *lbl = newiTempLabel(NULL);
4983             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4984             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4985             pic14_emitcode("cpl","c");
4986             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4987         }
4988         /* c = 1 if egal */
4989         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4990             pic14_outBitC(result);
4991             goto release ;
4992         }
4993         if (ifx) {
4994             genIfxJump (ifx,"c");
4995             goto release ;
4996         }
4997         /* if the result is used in an arithmetic operation
4998         then put the result in place */
4999         pic14_outBitC(result);
5000     } else {
5001       
5002       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5003       gencjne(left,right,result,ifx);
5004 /*
5005       if(ifx) 
5006         gencjne(left,right,newiTempLabel(NULL));
5007       else {
5008         if(IC_TRUE(ifx)->key)
5009           gencjne(left,right,IC_TRUE(ifx)->key);
5010         else
5011           gencjne(left,right,IC_FALSE(ifx)->key);
5012         ifx->generated = 1;
5013         goto release ;
5014       }
5015       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5016         aopPut(AOP(result),"a",0);
5017         goto release ;
5018       }
5019
5020       if (ifx) {
5021         genIfxJump (ifx,"a");
5022         goto release ;
5023       }
5024 */
5025       /* if the result is used in an arithmetic operation
5026          then put the result in place */
5027 /*
5028       if (AOP_TYPE(result) != AOP_CRY) 
5029         pic14_outAcc(result);
5030 */
5031       /* leave the result in acc */
5032     }
5033
5034 release:
5035     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5036     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5037     freeAsmop(result,NULL,ic,TRUE);
5038 }
5039
5040 /*-----------------------------------------------------------------*/
5041 /* ifxForOp - returns the icode containing the ifx for operand     */
5042 /*-----------------------------------------------------------------*/
5043 static iCode *ifxForOp ( operand *op, iCode *ic )
5044 {
5045     /* if true symbol then needs to be assigned */
5046     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5047     if (IS_TRUE_SYMOP(op))
5048         return NULL ;
5049
5050     /* if this has register type condition and
5051     the next instruction is ifx with the same operand
5052     and live to of the operand is upto the ifx only then */
5053     if (ic->next &&
5054         ic->next->op == IFX &&
5055         IC_COND(ic->next)->key == op->key &&
5056         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5057         return ic->next;
5058
5059     if (ic->next &&
5060         ic->next->op == IFX &&
5061         IC_COND(ic->next)->key == op->key) {
5062       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5063       return ic->next;
5064     }
5065
5066     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5067     if (ic->next &&
5068         ic->next->op == IFX)
5069       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5070
5071     if (ic->next &&
5072         ic->next->op == IFX &&
5073         IC_COND(ic->next)->key == op->key) {
5074       DEBUGpic14_emitcode ("; "," key is okay");
5075       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5076                            OP_SYMBOL(op)->liveTo,
5077                            ic->next->seq);
5078     }
5079
5080
5081     return NULL;
5082 }
5083 /*-----------------------------------------------------------------*/
5084 /* genAndOp - for && operation                                     */
5085 /*-----------------------------------------------------------------*/
5086 static void genAndOp (iCode *ic)
5087 {
5088     operand *left,*right, *result;
5089 /*     symbol *tlbl; */
5090
5091     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5092     /* note here that && operations that are in an
5093     if statement are taken away by backPatchLabels
5094     only those used in arthmetic operations remain */
5095     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5096     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5097     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5098
5099     DEBUGpic14_AopType(__LINE__,left,right,result);
5100
5101     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5102     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5103     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5104
5105     /* if both are bit variables */
5106 /*     if (AOP_TYPE(left) == AOP_CRY && */
5107 /*         AOP_TYPE(right) == AOP_CRY ) { */
5108 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5109 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5110 /*         pic14_outBitC(result); */
5111 /*     } else { */
5112 /*         tlbl = newiTempLabel(NULL); */
5113 /*         pic14_toBoolean(left);     */
5114 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5115 /*         pic14_toBoolean(right); */
5116 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5117 /*         pic14_outBitAcc(result); */
5118 /*     } */
5119
5120     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5121     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5122     freeAsmop(result,NULL,ic,TRUE);
5123 }
5124
5125
5126 /*-----------------------------------------------------------------*/
5127 /* genOrOp - for || operation                                      */
5128 /*-----------------------------------------------------------------*/
5129 /*
5130   tsd pic port -
5131   modified this code, but it doesn't appear to ever get called
5132 */
5133
5134 static void genOrOp (iCode *ic)
5135 {
5136     operand *left,*right, *result;
5137     symbol *tlbl;
5138
5139     /* note here that || operations that are in an
5140     if statement are taken away by backPatchLabels
5141     only those used in arthmetic operations remain */
5142     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5143     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5144     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5145     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5146
5147     DEBUGpic14_AopType(__LINE__,left,right,result);
5148
5149     /* if both are bit variables */
5150     if (AOP_TYPE(left) == AOP_CRY &&
5151         AOP_TYPE(right) == AOP_CRY ) {
5152       pic14_emitcode("clrc","");
5153       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5154                AOP(left)->aopu.aop_dir,
5155                AOP(left)->aopu.aop_dir);
5156       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5157                AOP(right)->aopu.aop_dir,
5158                AOP(right)->aopu.aop_dir);
5159       pic14_emitcode("setc","");
5160
5161     } else {
5162         tlbl = newiTempLabel(NULL);
5163         pic14_toBoolean(left);
5164         emitSKPZ;
5165         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5166         pic14_toBoolean(right);
5167         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5168
5169         pic14_outBitAcc(result);
5170     }
5171
5172     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5173     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5174     freeAsmop(result,NULL,ic,TRUE);            
5175 }
5176
5177 /*-----------------------------------------------------------------*/
5178 /* isLiteralBit - test if lit == 2^n                               */
5179 /*-----------------------------------------------------------------*/
5180 static int isLiteralBit(unsigned long lit)
5181 {
5182     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5183     0x100L,0x200L,0x400L,0x800L,
5184     0x1000L,0x2000L,0x4000L,0x8000L,
5185     0x10000L,0x20000L,0x40000L,0x80000L,
5186     0x100000L,0x200000L,0x400000L,0x800000L,
5187     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5188     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5189     int idx;
5190     
5191     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5192     for(idx = 0; idx < 32; idx++)
5193         if(lit == pw[idx])
5194             return idx+1;
5195     return 0;
5196 }
5197
5198 /*-----------------------------------------------------------------*/
5199 /* continueIfTrue -                                                */
5200 /*-----------------------------------------------------------------*/
5201 static void continueIfTrue (iCode *ic)
5202 {
5203     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5204     if(IC_TRUE(ic))
5205         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5206     ic->generated = 1;
5207 }
5208
5209 /*-----------------------------------------------------------------*/
5210 /* jmpIfTrue -                                                     */
5211 /*-----------------------------------------------------------------*/
5212 static void jumpIfTrue (iCode *ic)
5213 {
5214     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5215     if(!IC_TRUE(ic))
5216         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5217     ic->generated = 1;
5218 }
5219
5220 /*-----------------------------------------------------------------*/
5221 /* jmpTrueOrFalse -                                                */
5222 /*-----------------------------------------------------------------*/
5223 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5224 {
5225     // ugly but optimized by peephole
5226     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5227     if(IC_TRUE(ic)){
5228         symbol *nlbl = newiTempLabel(NULL);
5229         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5230         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5231         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5232         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5233     }
5234     else{
5235         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5236         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5237     }
5238     ic->generated = 1;
5239 }
5240
5241 /*-----------------------------------------------------------------*/
5242 /* genAnd  - code for and                                          */
5243 /*-----------------------------------------------------------------*/
5244 static void genAnd (iCode *ic, iCode *ifx)
5245 {
5246   operand *left, *right, *result;
5247   int size, offset=0;  
5248   unsigned long lit = 0L;
5249   int bytelit = 0;
5250   resolvedIfx rIfx;
5251
5252
5253   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5254   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5255   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5256   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5257
5258   resolveIfx(&rIfx,ifx);
5259
5260   /* if left is a literal & right is not then exchange them */
5261   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5262       AOP_NEEDSACC(left)) {
5263     operand *tmp = right ;
5264     right = left;
5265     left = tmp;
5266   }
5267
5268   /* if result = right then exchange them */
5269   if(pic14_sameRegs(AOP(result),AOP(right))){
5270     operand *tmp = right ;
5271     right = left;
5272     left = tmp;
5273   }
5274
5275   /* if right is bit then exchange them */
5276   if (AOP_TYPE(right) == AOP_CRY &&
5277       AOP_TYPE(left) != AOP_CRY){
5278     operand *tmp = right ;
5279     right = left;
5280     left = tmp;
5281   }
5282   if(AOP_TYPE(right) == AOP_LIT)
5283     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5284
5285   size = AOP_SIZE(result);
5286
5287   DEBUGpic14_AopType(__LINE__,left,right,result);
5288
5289   // if(bit & yy)
5290   // result = bit & yy;
5291   if (AOP_TYPE(left) == AOP_CRY){
5292     // c = bit & literal;
5293     if(AOP_TYPE(right) == AOP_LIT){
5294       if(lit & 1) {
5295         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5296           // no change
5297           goto release;
5298         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5299       } else {
5300         // bit(result) = 0;
5301         if(size && (AOP_TYPE(result) == AOP_CRY)){
5302           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5303           goto release;
5304         }
5305         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5306           jumpIfTrue(ifx);
5307           goto release;
5308         }
5309         pic14_emitcode("clr","c");
5310       }
5311     } else {
5312       if (AOP_TYPE(right) == AOP_CRY){
5313         // c = bit & bit;
5314         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5315         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5316       } else {
5317         // c = bit & val;
5318         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5319         // c = lsb
5320         pic14_emitcode("rrc","a");
5321         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5322       }
5323     }
5324     // bit = c
5325     // val = c
5326     if(size)
5327       pic14_outBitC(result);
5328     // if(bit & ...)
5329     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5330       genIfxJump(ifx, "c");           
5331     goto release ;
5332   }
5333
5334   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5335   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5336   if((AOP_TYPE(right) == AOP_LIT) &&
5337      (AOP_TYPE(result) == AOP_CRY) &&
5338      (AOP_TYPE(left) != AOP_CRY)){
5339     int posbit = isLiteralBit(lit);
5340     /* left &  2^n */
5341     if(posbit){
5342       posbit--;
5343       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5344       // bit = left & 2^n
5345       if(size)
5346         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5347       // if(left &  2^n)
5348       else{
5349         if(ifx){
5350 /*
5351           if(IC_TRUE(ifx)) {
5352             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5353             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5354           } else {
5355             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5356             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5357           }
5358 */
5359           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5360                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5361           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5362           
5363           ifx->generated = 1;
5364         }
5365         goto release;
5366       }
5367     } else {
5368       symbol *tlbl = newiTempLabel(NULL);
5369       int sizel = AOP_SIZE(left);
5370       if(size)
5371         pic14_emitcode("setb","c");
5372       while(sizel--){
5373         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5374           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5375           // byte ==  2^n ?
5376           if((posbit = isLiteralBit(bytelit)) != 0)
5377             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5378           else{
5379             if(bytelit != 0x0FFL)
5380               pic14_emitcode("anl","a,%s",
5381                              aopGet(AOP(right),offset,FALSE,TRUE));
5382             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5383           }
5384         }
5385         offset++;
5386       }
5387       // bit = left & literal
5388       if(size){
5389         pic14_emitcode("clr","c");
5390         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5391       }
5392       // if(left & literal)
5393       else{
5394         if(ifx)
5395           jmpTrueOrFalse(ifx, tlbl);
5396         goto release ;
5397       }
5398     }
5399     pic14_outBitC(result);
5400     goto release ;
5401   }
5402
5403   /* if left is same as result */
5404   if(pic14_sameRegs(AOP(result),AOP(left))){
5405     int know_W = -1;
5406     for(;size--; offset++,lit>>=8) {
5407       if(AOP_TYPE(right) == AOP_LIT){
5408         switch(lit & 0xff) {
5409         case 0x00:
5410           /*  and'ing with 0 has clears the result */
5411           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5412           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5413           break;
5414         case 0xff:
5415           /* and'ing with 0xff is a nop when the result and left are the same */
5416           break;
5417
5418         default:
5419           {
5420             int p = my_powof2( (~lit) & 0xff );
5421             if(p>=0) {
5422               /* only one bit is set in the literal, so use a bcf instruction */
5423               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5424               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5425
5426             } else {
5427               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5428               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5429               if(know_W != (lit&0xff))
5430                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5431               know_W = lit &0xff;
5432               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5433             }
5434           }    
5435         }
5436       } else {
5437         if (AOP_TYPE(left) == AOP_ACC) {
5438           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5439         } else {                    
5440           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5441           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5442
5443         }
5444       }
5445     }
5446
5447   } else {
5448     // left & result in different registers
5449     if(AOP_TYPE(result) == AOP_CRY){
5450       // result = bit
5451       // if(size), result in bit
5452       // if(!size && ifx), conditional oper: if(left & right)
5453       symbol *tlbl = newiTempLabel(NULL);
5454       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5455       if(size)
5456         pic14_emitcode("setb","c");
5457       while(sizer--){
5458         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5459         pic14_emitcode("anl","a,%s",
5460                        aopGet(AOP(left),offset,FALSE,FALSE));
5461         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5462         offset++;
5463       }
5464       if(size){
5465         CLRC;
5466         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5467         pic14_outBitC(result);
5468       } else if(ifx)
5469         jmpTrueOrFalse(ifx, tlbl);
5470     } else {
5471       for(;(size--);offset++) {
5472         // normal case
5473         // result = left & right
5474         if(AOP_TYPE(right) == AOP_LIT){
5475           int t = (lit >> (offset*8)) & 0x0FFL;
5476           switch(t) { 
5477           case 0x00:
5478             pic14_emitcode("clrf","%s",
5479                            aopGet(AOP(result),offset,FALSE,FALSE));
5480             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5481             break;
5482           case 0xff:
5483             pic14_emitcode("movf","%s,w",
5484                            aopGet(AOP(left),offset,FALSE,FALSE));
5485             pic14_emitcode("movwf","%s",
5486                            aopGet(AOP(result),offset,FALSE,FALSE));
5487             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5488             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5489             break;
5490           default:
5491             pic14_emitcode("movlw","0x%x",t);
5492             pic14_emitcode("andwf","%s,w",
5493                            aopGet(AOP(left),offset,FALSE,FALSE));
5494             pic14_emitcode("movwf","%s",
5495                            aopGet(AOP(result),offset,FALSE,FALSE));
5496               
5497             emitpcode(POC_MOVLW, popGetLit(t));
5498             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5499             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5500           }
5501           continue;
5502         }
5503
5504         if (AOP_TYPE(left) == AOP_ACC) {
5505           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5506           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5507         } else {
5508           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5509           pic14_emitcode("andwf","%s,w",
5510                          aopGet(AOP(left),offset,FALSE,FALSE));
5511           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5512           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5513         }
5514         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5515         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5516       }
5517     }
5518   }
5519
5520   release :
5521     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5522   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5523   freeAsmop(result,NULL,ic,TRUE);     
5524 }
5525
5526 /*-----------------------------------------------------------------*/
5527 /* genOr  - code for or                                            */
5528 /*-----------------------------------------------------------------*/
5529 static void genOr (iCode *ic, iCode *ifx)
5530 {
5531     operand *left, *right, *result;
5532     int size, offset=0;
5533     unsigned long lit = 0L;
5534
5535     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5536
5537     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5538     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5539     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5540
5541     DEBUGpic14_AopType(__LINE__,left,right,result);
5542
5543     /* if left is a literal & right is not then exchange them */
5544     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5545         AOP_NEEDSACC(left)) {
5546         operand *tmp = right ;
5547         right = left;
5548         left = tmp;
5549     }
5550
5551     /* if result = right then exchange them */
5552     if(pic14_sameRegs(AOP(result),AOP(right))){
5553         operand *tmp = right ;
5554         right = left;
5555         left = tmp;
5556     }
5557
5558     /* if right is bit then exchange them */
5559     if (AOP_TYPE(right) == AOP_CRY &&
5560         AOP_TYPE(left) != AOP_CRY){
5561         operand *tmp = right ;
5562         right = left;
5563         left = tmp;
5564     }
5565
5566     DEBUGpic14_AopType(__LINE__,left,right,result);
5567
5568     if(AOP_TYPE(right) == AOP_LIT)
5569         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5570
5571     size = AOP_SIZE(result);
5572
5573     // if(bit | yy)
5574     // xx = bit | yy;
5575     if (AOP_TYPE(left) == AOP_CRY){
5576         if(AOP_TYPE(right) == AOP_LIT){
5577             // c = bit & literal;
5578             if(lit){
5579                 // lit != 0 => result = 1
5580                 if(AOP_TYPE(result) == AOP_CRY){
5581                   if(size)
5582                     emitpcode(POC_BSF, popGet(AOP(result),0));
5583                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5584                   //     AOP(result)->aopu.aop_dir,
5585                   //     AOP(result)->aopu.aop_dir);
5586                     else if(ifx)
5587                         continueIfTrue(ifx);
5588                     goto release;
5589                 }
5590             } else {
5591                 // lit == 0 => result = left
5592                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5593                     goto release;
5594                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5595             }
5596         } else {
5597             if (AOP_TYPE(right) == AOP_CRY){
5598               if(pic14_sameRegs(AOP(result),AOP(left))){
5599                 // c = bit | bit;
5600                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5601                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5602                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5603
5604                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5605                          AOP(result)->aopu.aop_dir,
5606                          AOP(result)->aopu.aop_dir);
5607                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5608                          AOP(right)->aopu.aop_dir,
5609                          AOP(right)->aopu.aop_dir);
5610                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5611                          AOP(result)->aopu.aop_dir,
5612                          AOP(result)->aopu.aop_dir);
5613               } else {
5614                 if( AOP_TYPE(result) == AOP_ACC) {
5615                   emitpcode(POC_MOVLW, popGetLit(0));
5616                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5617                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5618                   emitpcode(POC_MOVLW, popGetLit(1));
5619
5620                 } else {
5621
5622                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5623                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5624                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5625                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5626
5627                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5628                                  AOP(result)->aopu.aop_dir,
5629                                  AOP(result)->aopu.aop_dir);
5630                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5631                                  AOP(right)->aopu.aop_dir,
5632                                  AOP(right)->aopu.aop_dir);
5633                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5634                                  AOP(left)->aopu.aop_dir,
5635                                  AOP(left)->aopu.aop_dir);
5636                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5637                                  AOP(result)->aopu.aop_dir,
5638                                  AOP(result)->aopu.aop_dir);
5639                 }
5640               }
5641             } else {
5642                 // c = bit | val;
5643                 symbol *tlbl = newiTempLabel(NULL);
5644                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5645
5646
5647                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5648                 if( AOP_TYPE(right) == AOP_ACC) {
5649                   emitpcode(POC_IORLW, popGetLit(0));
5650                   emitSKPNZ;
5651                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5652                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5653                 }
5654
5655
5656
5657                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5658                     pic14_emitcode(";XXX setb","c");
5659                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5660                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5661                 pic14_toBoolean(right);
5662                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5663                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5664                     jmpTrueOrFalse(ifx, tlbl);
5665                     goto release;
5666                 } else {
5667                     CLRC;
5668                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5669                 }
5670             }
5671         }
5672         // bit = c
5673         // val = c
5674         if(size)
5675             pic14_outBitC(result);
5676         // if(bit | ...)
5677         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5678             genIfxJump(ifx, "c");           
5679         goto release ;
5680     }
5681
5682     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5683     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5684     if((AOP_TYPE(right) == AOP_LIT) &&
5685        (AOP_TYPE(result) == AOP_CRY) &&
5686        (AOP_TYPE(left) != AOP_CRY)){
5687         if(lit){
5688           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5689             // result = 1
5690             if(size)
5691                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5692             else 
5693                 continueIfTrue(ifx);
5694             goto release;
5695         } else {
5696           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5697             // lit = 0, result = boolean(left)
5698             if(size)
5699                 pic14_emitcode(";XXX setb","c");
5700             pic14_toBoolean(right);
5701             if(size){
5702                 symbol *tlbl = newiTempLabel(NULL);
5703                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5704                 CLRC;
5705                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5706             } else {
5707                 genIfxJump (ifx,"a");
5708                 goto release;
5709             }
5710         }
5711         pic14_outBitC(result);
5712         goto release ;
5713     }
5714
5715     /* if left is same as result */
5716     if(pic14_sameRegs(AOP(result),AOP(left))){
5717       int know_W = -1;
5718       for(;size--; offset++,lit>>=8) {
5719         if(AOP_TYPE(right) == AOP_LIT){
5720           if((lit & 0xff) == 0)
5721             /*  or'ing with 0 has no effect */
5722             continue;
5723           else {
5724             int p = my_powof2(lit & 0xff);
5725             if(p>=0) {
5726               /* only one bit is set in the literal, so use a bsf instruction */
5727               emitpcode(POC_BSF,
5728                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5729             } else {
5730               if(know_W != (lit & 0xff))
5731                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5732               know_W = lit & 0xff;
5733               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5734             }
5735                     
5736           }
5737         } else {
5738           if (AOP_TYPE(left) == AOP_ACC) {
5739             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5740             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5741           } else {                  
5742             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5743             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5744
5745             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5746             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5747
5748           }
5749         }
5750       }
5751     } else {
5752         // left & result in different registers
5753         if(AOP_TYPE(result) == AOP_CRY){
5754             // result = bit
5755             // if(size), result in bit
5756             // if(!size && ifx), conditional oper: if(left | right)
5757             symbol *tlbl = newiTempLabel(NULL);
5758             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5759             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5760
5761
5762             if(size)
5763                 pic14_emitcode(";XXX setb","c");
5764             while(sizer--){
5765                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5766                 pic14_emitcode(";XXX orl","a,%s",
5767                          aopGet(AOP(left),offset,FALSE,FALSE));
5768                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5769                 offset++;
5770             }
5771             if(size){
5772                 CLRC;
5773                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5774                 pic14_outBitC(result);
5775             } else if(ifx)
5776                 jmpTrueOrFalse(ifx, tlbl);
5777         } else for(;(size--);offset++){
5778           // normal case
5779           // result = left & right
5780           if(AOP_TYPE(right) == AOP_LIT){
5781             int t = (lit >> (offset*8)) & 0x0FFL;
5782             switch(t) { 
5783             case 0x00:
5784               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5785               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5786
5787               pic14_emitcode("movf","%s,w",
5788                        aopGet(AOP(left),offset,FALSE,FALSE));
5789               pic14_emitcode("movwf","%s",
5790                        aopGet(AOP(result),offset,FALSE,FALSE));
5791               break;
5792             default:
5793               emitpcode(POC_MOVLW,  popGetLit(t));
5794               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5795               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5796
5797               pic14_emitcode("movlw","0x%x",t);
5798               pic14_emitcode("iorwf","%s,w",
5799                        aopGet(AOP(left),offset,FALSE,FALSE));
5800               pic14_emitcode("movwf","%s",
5801                        aopGet(AOP(result),offset,FALSE,FALSE));
5802               
5803             }
5804             continue;
5805           }
5806
5807           // faster than result <- left, anl result,right
5808           // and better if result is SFR
5809           if (AOP_TYPE(left) == AOP_ACC) {
5810             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5811             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5812           } else {
5813             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5814             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5815
5816             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5817             pic14_emitcode("iorwf","%s,w",
5818                      aopGet(AOP(left),offset,FALSE,FALSE));
5819           }
5820           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5821           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5822         }
5823     }
5824
5825 release :
5826     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5828     freeAsmop(result,NULL,ic,TRUE);     
5829 }
5830
5831 /*-----------------------------------------------------------------*/
5832 /* genXor - code for xclusive or                                   */
5833 /*-----------------------------------------------------------------*/
5834 static void genXor (iCode *ic, iCode *ifx)
5835 {
5836   operand *left, *right, *result;
5837   int size, offset=0;
5838   unsigned long lit = 0L;
5839
5840   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5841
5842   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5843   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5844   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5845
5846   /* if left is a literal & right is not ||
5847      if left needs acc & right does not */
5848   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5849       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5850     operand *tmp = right ;
5851     right = left;
5852     left = tmp;
5853   }
5854
5855   /* if result = right then exchange them */
5856   if(pic14_sameRegs(AOP(result),AOP(right))){
5857     operand *tmp = right ;
5858     right = left;
5859     left = tmp;
5860   }
5861
5862   /* if right is bit then exchange them */
5863   if (AOP_TYPE(right) == AOP_CRY &&
5864       AOP_TYPE(left) != AOP_CRY){
5865     operand *tmp = right ;
5866     right = left;
5867     left = tmp;
5868   }
5869   if(AOP_TYPE(right) == AOP_LIT)
5870     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5871
5872   size = AOP_SIZE(result);
5873
5874   // if(bit ^ yy)
5875   // xx = bit ^ yy;
5876   if (AOP_TYPE(left) == AOP_CRY){
5877     if(AOP_TYPE(right) == AOP_LIT){
5878       // c = bit & literal;
5879       if(lit>>1){
5880         // lit>>1  != 0 => result = 1
5881         if(AOP_TYPE(result) == AOP_CRY){
5882           if(size)
5883             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5884             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5885           else if(ifx)
5886             continueIfTrue(ifx);
5887           goto release;
5888         }
5889         pic14_emitcode("setb","c");
5890       } else{
5891         // lit == (0 or 1)
5892         if(lit == 0){
5893           // lit == 0, result = left
5894           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5895             goto release;
5896           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5897         } else{
5898           // lit == 1, result = not(left)
5899           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5900             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5901             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5902             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5903             goto release;
5904           } else {
5905             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5906             pic14_emitcode("cpl","c");
5907           }
5908         }
5909       }
5910
5911     } else {
5912       // right != literal
5913       symbol *tlbl = newiTempLabel(NULL);
5914       if (AOP_TYPE(right) == AOP_CRY){
5915         // c = bit ^ bit;
5916         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5917       }
5918       else{
5919         int sizer = AOP_SIZE(right);
5920         // c = bit ^ val
5921         // if val>>1 != 0, result = 1
5922         pic14_emitcode("setb","c");
5923         while(sizer){
5924           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5925           if(sizer == 1)
5926             // test the msb of the lsb
5927             pic14_emitcode("anl","a,#0xfe");
5928           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5929           sizer--;
5930         }
5931         // val = (0,1)
5932         pic14_emitcode("rrc","a");
5933       }
5934       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5935       pic14_emitcode("cpl","c");
5936       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5937     }
5938     // bit = c
5939     // val = c
5940     if(size)
5941       pic14_outBitC(result);
5942     // if(bit | ...)
5943     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5944       genIfxJump(ifx, "c");           
5945     goto release ;
5946   }
5947
5948   if(pic14_sameRegs(AOP(result),AOP(left))){
5949     /* if left is same as result */
5950     for(;size--; offset++) {
5951       if(AOP_TYPE(right) == AOP_LIT){
5952         int t  = (lit >> (offset*8)) & 0x0FFL;
5953         if(t == 0x00L)
5954           continue;
5955         else
5956           if (IS_AOP_PREG(left)) {
5957             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5958             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5959             aopPut(AOP(result),"a",offset);
5960           } else {
5961             emitpcode(POC_MOVLW, popGetLit(t));
5962             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5963             pic14_emitcode("xrl","%s,%s",
5964                            aopGet(AOP(left),offset,FALSE,TRUE),
5965                            aopGet(AOP(right),offset,FALSE,FALSE));
5966           }
5967       } else {
5968         if (AOP_TYPE(left) == AOP_ACC)
5969           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5970         else {
5971           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5972           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5973 /*
5974           if (IS_AOP_PREG(left)) {
5975             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5976             aopPut(AOP(result),"a",offset);
5977           } else
5978             pic14_emitcode("xrl","%s,a",
5979                            aopGet(AOP(left),offset,FALSE,TRUE));
5980 */
5981         }
5982       }
5983     }
5984   } else {
5985     // left & result in different registers
5986     if(AOP_TYPE(result) == AOP_CRY){
5987       // result = bit
5988       // if(size), result in bit
5989       // if(!size && ifx), conditional oper: if(left ^ right)
5990       symbol *tlbl = newiTempLabel(NULL);
5991       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5992       if(size)
5993         pic14_emitcode("setb","c");
5994       while(sizer--){
5995         if((AOP_TYPE(right) == AOP_LIT) &&
5996            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5997           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5998         } else {
5999           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6000           pic14_emitcode("xrl","a,%s",
6001                          aopGet(AOP(left),offset,FALSE,FALSE));
6002         }
6003         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6004         offset++;
6005       }
6006       if(size){
6007         CLRC;
6008         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6009         pic14_outBitC(result);
6010       } else if(ifx)
6011         jmpTrueOrFalse(ifx, tlbl);
6012     } else for(;(size--);offset++){
6013       // normal case
6014       // result = left & right
6015       if(AOP_TYPE(right) == AOP_LIT){
6016         int t = (lit >> (offset*8)) & 0x0FFL;
6017         switch(t) { 
6018         case 0x00:
6019           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6020           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6021           pic14_emitcode("movf","%s,w",
6022                          aopGet(AOP(left),offset,FALSE,FALSE));
6023           pic14_emitcode("movwf","%s",
6024                          aopGet(AOP(result),offset,FALSE,FALSE));
6025           break;
6026         case 0xff:
6027           emitpcode(POC_COMFW,popGet(AOP(left),offset));
6028           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6029           pic14_emitcode("comf","%s,w",
6030                          aopGet(AOP(left),offset,FALSE,FALSE));
6031           pic14_emitcode("movwf","%s",
6032                          aopGet(AOP(result),offset,FALSE,FALSE));
6033           break;
6034         default:
6035           emitpcode(POC_MOVLW, popGetLit(t));
6036           emitpcode(POC_XORFW,popGet(AOP(left),offset));
6037           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6038           pic14_emitcode("movlw","0x%x",t);
6039           pic14_emitcode("xorwf","%s,w",
6040                          aopGet(AOP(left),offset,FALSE,FALSE));
6041           pic14_emitcode("movwf","%s",
6042                          aopGet(AOP(result),offset,FALSE,FALSE));
6043
6044         }
6045         continue;
6046       }
6047
6048       // faster than result <- left, anl result,right
6049       // and better if result is SFR
6050       if (AOP_TYPE(left) == AOP_ACC) {
6051         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6052         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6053       } else {
6054         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6055         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6056         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6057         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6058       }
6059       if ( AOP_TYPE(result) != AOP_ACC){
6060         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6061         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6062       }
6063     }
6064   }
6065
6066   release :
6067     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6069   freeAsmop(result,NULL,ic,TRUE);     
6070 }
6071
6072 /*-----------------------------------------------------------------*/
6073 /* genInline - write the inline code out                           */
6074 /*-----------------------------------------------------------------*/
6075 static void genInline (iCode *ic)
6076 {
6077     char *buffer, *bp, *bp1;
6078     
6079     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6080
6081     _G.inLine += (!options.asmpeep);
6082
6083     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6084     strcpy(buffer,IC_INLINE(ic));
6085
6086     /* emit each line as a code */
6087     while (*bp) {
6088         if (*bp == '\n') {
6089             *bp++ = '\0';
6090
6091             if(*bp1)
6092               addpCode2pBlock(pb,AssembleLine(bp1));
6093             bp1 = bp;
6094         } else {
6095             if (*bp == ':') {
6096                 bp++;
6097                 *bp = '\0';
6098                 bp++;
6099                 pic14_emitcode(bp1,"");
6100                 bp1 = bp;
6101             } else
6102                 bp++;
6103         }
6104     }
6105     if ((bp1 != bp) && *bp1)
6106       addpCode2pBlock(pb,AssembleLine(bp1));
6107
6108     Safe_free(buffer);
6109
6110     _G.inLine -= (!options.asmpeep);
6111 }
6112
6113 /*-----------------------------------------------------------------*/
6114 /* genRRC - rotate right with carry                                */
6115 /*-----------------------------------------------------------------*/
6116 static void genRRC (iCode *ic)
6117 {
6118   operand *left , *result ;
6119   int size, offset = 0, same;
6120
6121   /* rotate right with carry */
6122   left = IC_LEFT(ic);
6123   result=IC_RESULT(ic);
6124   aopOp (left,ic,FALSE);
6125   aopOp (result,ic,FALSE);
6126
6127   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6128
6129   same = pic14_sameRegs(AOP(result),AOP(left));
6130
6131   size = AOP_SIZE(result);    
6132
6133   /* get the lsb and put it into the carry */
6134   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6135
6136   offset = 0 ;
6137
6138   while(size--) {
6139
6140     if(same) {
6141       emitpcode(POC_RRF, popGet(AOP(left),offset));
6142     } else {
6143       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6144       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6145     }
6146
6147     offset++;
6148   }
6149
6150   freeAsmop(left,NULL,ic,TRUE);
6151   freeAsmop(result,NULL,ic,TRUE);
6152 }
6153
6154 /*-----------------------------------------------------------------*/
6155 /* genRLC - generate code for rotate left with carry               */
6156 /*-----------------------------------------------------------------*/
6157 static void genRLC (iCode *ic)
6158 {    
6159   operand *left , *result ;
6160   int size, offset = 0;
6161   int same;
6162
6163   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6164   /* rotate right with carry */
6165   left = IC_LEFT(ic);
6166   result=IC_RESULT(ic);
6167   aopOp (left,ic,FALSE);
6168   aopOp (result,ic,FALSE);
6169
6170   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6171
6172   same = pic14_sameRegs(AOP(result),AOP(left));
6173
6174   /* move it to the result */
6175   size = AOP_SIZE(result);    
6176
6177   /* get the msb and put it into the carry */
6178   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6179
6180   offset = 0 ;
6181
6182   while(size--) {
6183
6184     if(same) {
6185       emitpcode(POC_RLF, popGet(AOP(left),offset));
6186     } else {
6187       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6188       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6189     }
6190
6191     offset++;
6192   }
6193
6194
6195   freeAsmop(left,NULL,ic,TRUE);
6196   freeAsmop(result,NULL,ic,TRUE);
6197 }
6198
6199 /*-----------------------------------------------------------------*/
6200 /* genGetHbit - generates code get highest order bit               */
6201 /*-----------------------------------------------------------------*/
6202 static void genGetHbit (iCode *ic)
6203 {
6204     operand *left, *result;
6205     left = IC_LEFT(ic);
6206     result=IC_RESULT(ic);
6207     aopOp (left,ic,FALSE);
6208     aopOp (result,ic,FALSE);
6209
6210     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6211     /* get the highest order byte into a */
6212     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6213     if(AOP_TYPE(result) == AOP_CRY){
6214         pic14_emitcode("rlc","a");
6215         pic14_outBitC(result);
6216     }
6217     else{
6218         pic14_emitcode("rl","a");
6219         pic14_emitcode("anl","a,#0x01");
6220         pic14_outAcc(result);
6221     }
6222
6223
6224     freeAsmop(left,NULL,ic,TRUE);
6225     freeAsmop(result,NULL,ic,TRUE);
6226 }
6227
6228 /*-----------------------------------------------------------------*/
6229 /* AccRol - rotate left accumulator by known count                 */
6230 /*-----------------------------------------------------------------*/
6231 static void AccRol (int shCount)
6232 {
6233     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6234     shCount &= 0x0007;              // shCount : 0..7
6235     switch(shCount){
6236         case 0 :
6237             break;
6238         case 1 :
6239             pic14_emitcode("rl","a");
6240             break;
6241         case 2 :
6242             pic14_emitcode("rl","a");
6243             pic14_emitcode("rl","a");
6244             break;
6245         case 3 :
6246             pic14_emitcode("swap","a");
6247             pic14_emitcode("rr","a");
6248             break;
6249         case 4 :
6250             pic14_emitcode("swap","a");
6251             break;
6252         case 5 :
6253             pic14_emitcode("swap","a");
6254             pic14_emitcode("rl","a");
6255             break;
6256         case 6 :
6257             pic14_emitcode("rr","a");
6258             pic14_emitcode("rr","a");
6259             break;
6260         case 7 :
6261             pic14_emitcode("rr","a");
6262             break;
6263     }
6264 }
6265
6266 /*-----------------------------------------------------------------*/
6267 /* AccLsh - left shift accumulator by known count                  */
6268 /*-----------------------------------------------------------------*/
6269 static void AccLsh (int shCount)
6270 {
6271     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6272     if(shCount != 0){
6273         if(shCount == 1)
6274             pic14_emitcode("add","a,acc");
6275         else 
6276             if(shCount == 2) {
6277             pic14_emitcode("add","a,acc");
6278             pic14_emitcode("add","a,acc");
6279         } else {
6280             /* rotate left accumulator */
6281             AccRol(shCount);
6282             /* and kill the lower order bits */
6283             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6284         }
6285     }
6286 }
6287
6288 /*-----------------------------------------------------------------*/
6289 /* AccRsh - right shift accumulator by known count                 */
6290 /*-----------------------------------------------------------------*/
6291 static void AccRsh (int shCount)
6292 {
6293     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6294     if(shCount != 0){
6295         if(shCount == 1){
6296             CLRC;
6297             pic14_emitcode("rrc","a");
6298         } else {
6299             /* rotate right accumulator */
6300             AccRol(8 - shCount);
6301             /* and kill the higher order bits */
6302             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6303         }
6304     }
6305 }
6306
6307 #if 0
6308 /*-----------------------------------------------------------------*/
6309 /* AccSRsh - signed right shift accumulator by known count                 */
6310 /*-----------------------------------------------------------------*/
6311 static void AccSRsh (int shCount)
6312 {
6313     symbol *tlbl ;
6314     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6315     if(shCount != 0){
6316         if(shCount == 1){
6317             pic14_emitcode("mov","c,acc.7");
6318             pic14_emitcode("rrc","a");
6319         } else if(shCount == 2){
6320             pic14_emitcode("mov","c,acc.7");
6321             pic14_emitcode("rrc","a");
6322             pic14_emitcode("mov","c,acc.7");
6323             pic14_emitcode("rrc","a");
6324         } else {
6325             tlbl = newiTempLabel(NULL);
6326             /* rotate right accumulator */
6327             AccRol(8 - shCount);
6328             /* and kill the higher order bits */
6329             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6330             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6331             pic14_emitcode("orl","a,#0x%02x",
6332                      (unsigned char)~SRMask[shCount]);
6333             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6334         }
6335     }
6336 }
6337 #endif
6338 /*-----------------------------------------------------------------*/
6339 /* shiftR1Left2Result - shift right one byte from left to result   */
6340 /*-----------------------------------------------------------------*/
6341 static void shiftR1Left2ResultSigned (operand *left, int offl,
6342                                 operand *result, int offr,
6343                                 int shCount)
6344 {
6345   int same;
6346
6347   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6348
6349   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6350
6351   switch(shCount) {
6352   case 1:
6353     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6354     if(same) 
6355       emitpcode(POC_RRF, popGet(AOP(result),offr));
6356     else {
6357       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6359     }
6360
6361     break;
6362   case 2:
6363
6364     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6365     if(same) 
6366       emitpcode(POC_RRF, popGet(AOP(result),offr));
6367     else {
6368       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6369       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6370     }
6371     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6372     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6373
6374     break;
6375
6376   case 3:
6377     if(same)
6378       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6379     else {
6380       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6381       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6382     }
6383
6384     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6385     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6386     emitpcode(POC_ANDLW, popGetLit(0x1f));
6387
6388     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6389     emitpcode(POC_IORLW, popGetLit(0xe0));
6390
6391     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392     break;
6393
6394   case 4:
6395     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6396     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6397     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6398     emitpcode(POC_IORLW,  popGetLit(0xf0));
6399     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6400     break;
6401   case 5:
6402     if(same) {
6403       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6404     } else {
6405       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6406       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6407     }
6408     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6409     emitpcode(POC_ANDLW,  popGetLit(0x07));
6410     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6411     emitpcode(POC_IORLW,  popGetLit(0xf8));
6412     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6413     break;
6414
6415   case 6:
6416     if(same) {
6417       emitpcode(POC_MOVLW, popGetLit(0x00));
6418       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6419       emitpcode(POC_MOVLW, popGetLit(0xfe));
6420       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6421       emitpcode(POC_IORLW, popGetLit(0x01));
6422       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423     } else {
6424       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6425       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6426       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6427       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6428       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6429     }
6430     break;
6431
6432   case 7:
6433     if(same) {
6434       emitpcode(POC_MOVLW, popGetLit(0x00));
6435       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6436       emitpcode(POC_MOVLW, popGetLit(0xff));
6437       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438     } else {
6439       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6440       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6441       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6442     }
6443
6444   default:
6445     break;
6446   }
6447 }
6448
6449 /*-----------------------------------------------------------------*/
6450 /* shiftR1Left2Result - shift right one byte from left to result   */
6451 /*-----------------------------------------------------------------*/
6452 static void shiftR1Left2Result (operand *left, int offl,
6453                                 operand *result, int offr,
6454                                 int shCount, int sign)
6455 {
6456   int same;
6457
6458   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6459
6460   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6461
6462   /* Copy the msb into the carry if signed. */
6463   if(sign) {
6464     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6465     return;
6466   }
6467
6468
6469
6470   switch(shCount) {
6471   case 1:
6472     emitCLRC;
6473     if(same) 
6474       emitpcode(POC_RRF, popGet(AOP(result),offr));
6475     else {
6476       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6477       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6478     }
6479     break;
6480   case 2:
6481     emitCLRC;
6482     if(same) {
6483       emitpcode(POC_RRF, popGet(AOP(result),offr));
6484     } else {
6485       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6486       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487     }
6488     emitCLRC;
6489     emitpcode(POC_RRF, popGet(AOP(result),offr));
6490
6491     break;
6492   case 3:
6493     if(same)
6494       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6495     else {
6496       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6498     }
6499
6500     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6501     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6502     emitpcode(POC_ANDLW, popGetLit(0x1f));
6503     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6504     break;
6505       
6506   case 4:
6507     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6508     emitpcode(POC_ANDLW, popGetLit(0x0f));
6509     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6510     break;
6511
6512   case 5:
6513     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6514     emitpcode(POC_ANDLW, popGetLit(0x0f));
6515     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6516     emitCLRC;
6517     emitpcode(POC_RRF, popGet(AOP(result),offr));
6518
6519     break;
6520   case 6:
6521
6522     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6523     emitpcode(POC_ANDLW, popGetLit(0x80));
6524     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6525     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6526     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6527     break;
6528
6529   case 7:
6530
6531     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6532     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6533     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6534
6535     break;
6536
6537   default:
6538     break;
6539   }
6540 }
6541
6542 /*-----------------------------------------------------------------*/
6543 /* shiftL1Left2Result - shift left one byte from left to result    */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftL1Left2Result (operand *left, int offl,
6546                                 operand *result, int offr, int shCount)
6547 {
6548   int same;
6549
6550   //    char *l;
6551   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6552
6553   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6554   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6555     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6556     //    MOVA(l);
6557     /* shift left accumulator */
6558     //AccLsh(shCount); // don't comment out just yet...
6559   //    aopPut(AOP(result),"a",offr);
6560
6561   switch(shCount) {
6562   case 1:
6563     /* Shift left 1 bit position */
6564     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6565     if(same) {
6566       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6567     } else {
6568       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6569       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6570     }
6571     break;
6572   case 2:
6573     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6574     emitpcode(POC_ANDLW,popGetLit(0x7e));
6575     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6576     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6577     break;
6578   case 3:
6579     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6580     emitpcode(POC_ANDLW,popGetLit(0x3e));
6581     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6582     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6583     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6584     break;
6585   case 4:
6586     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587     emitpcode(POC_ANDLW, popGetLit(0xf0));
6588     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589     break;
6590   case 5:
6591     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6592     emitpcode(POC_ANDLW, popGetLit(0xf0));
6593     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6594     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6595     break;
6596   case 6:
6597     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6598     emitpcode(POC_ANDLW, popGetLit(0x30));
6599     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6600     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6601     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6602     break;
6603   case 7:
6604     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6605     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6606     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6607     break;
6608
6609   default:
6610     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6611   }
6612
6613 }
6614
6615 /*-----------------------------------------------------------------*/
6616 /* movLeft2Result - move byte from left to result                  */
6617 /*-----------------------------------------------------------------*/
6618 static void movLeft2Result (operand *left, int offl,
6619                             operand *result, int offr)
6620 {
6621   char *l;
6622   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6623   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6624     l = aopGet(AOP(left),offl,FALSE,FALSE);
6625
6626     if (*l == '@' && (IS_AOP_PREG(result))) {
6627       pic14_emitcode("mov","a,%s",l);
6628       aopPut(AOP(result),"a",offr);
6629     } else {
6630       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6631       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6632     }
6633   }
6634 }
6635
6636 /*-----------------------------------------------------------------*/
6637 /* shiftL2Left2Result - shift left two bytes from left to result   */
6638 /*-----------------------------------------------------------------*/
6639 static void shiftL2Left2Result (operand *left, int offl,
6640                                 operand *result, int offr, int shCount)
6641 {
6642
6643
6644   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6645
6646   if(pic14_sameRegs(AOP(result), AOP(left))) {
6647     switch(shCount) {
6648     case 0:
6649       break;
6650     case 1:
6651     case 2:
6652     case 3:
6653
6654       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6655       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6656       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6657
6658       while(--shCount) {
6659         emitCLRC;
6660         emitpcode(POC_RLF, popGet(AOP(result),offr));
6661         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6662       }
6663
6664       break;
6665     case 4:
6666     case 5:
6667       emitpcode(POC_MOVLW, popGetLit(0x0f));
6668       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6669       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6670       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6671       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6672       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6673       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6674       if(shCount >=5) {
6675         emitpcode(POC_RLF, popGet(AOP(result),offr));
6676         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6677       }
6678       break;
6679     case 6:
6680       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6681       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6682       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6683       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6684       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6685       emitpcode(POC_ANDLW,popGetLit(0xc0));
6686       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6688       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6689       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6690       break;
6691     case 7:
6692       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6693       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6694       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6695       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6696       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6697     }
6698
6699   } else {
6700     switch(shCount) {
6701     case 0:
6702       break;
6703     case 1:
6704     case 2:
6705     case 3:
6706       /* note, use a mov/add for the shift since the mov has a
6707          chance of getting optimized out */
6708       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6709       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6710       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6711       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6712       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6713
6714       while(--shCount) {
6715         emitCLRC;
6716         emitpcode(POC_RLF, popGet(AOP(result),offr));
6717         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6718       }
6719       break;
6720
6721     case 4:
6722     case 5:
6723       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6724       emitpcode(POC_ANDLW, popGetLit(0xF0));
6725       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6726       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6727       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6728       emitpcode(POC_ANDLW, popGetLit(0xF0));
6729       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6730       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6731
6732
6733       if(shCount == 5) {
6734         emitpcode(POC_RLF, popGet(AOP(result),offr));
6735         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6736       }
6737       break;
6738     case 6:
6739       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6740       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6742       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6743
6744       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6745       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6746       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6747       emitpcode(POC_ANDLW,popGetLit(0xc0));
6748       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6749       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6750       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6751       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6752       break;
6753     case 7:
6754       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6755       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6756       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6757       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6758       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6759     }
6760   }
6761
6762 }
6763 /*-----------------------------------------------------------------*/
6764 /* shiftR2Left2Result - shift right two bytes from left to result  */
6765 /*-----------------------------------------------------------------*/
6766 static void shiftR2Left2Result (operand *left, int offl,
6767                                 operand *result, int offr,
6768                                 int shCount, int sign)
6769 {
6770   int same=0;
6771
6772   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6773   same = pic14_sameRegs(AOP(result), AOP(left));
6774
6775   if(same && ((offl + MSB16) == offr)){
6776     same=1;
6777     /* don't crash result[offr] */
6778     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6779     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6780   }
6781 /* else {
6782     movLeft2Result(left,offl, result, offr);
6783     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6784   }
6785 */
6786   /* a:x >> shCount (x = lsb(result))*/
6787 /*
6788   if(sign)
6789     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6790   else {
6791     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6792 */
6793   switch(shCount) {
6794   case 0:
6795     break;
6796   case 1:
6797   case 2:
6798   case 3:
6799     if(sign)
6800       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6801     else
6802       emitCLRC;
6803
6804     if(same) {
6805       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6806       emitpcode(POC_RRF,popGet(AOP(result),offr));
6807     } else {
6808       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6809       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6810       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6811       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6812     }
6813
6814     while(--shCount) {
6815       if(sign)
6816         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6817       else
6818         emitCLRC;
6819       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6820       emitpcode(POC_RRF,popGet(AOP(result),offr));
6821     }
6822     break;
6823   case 4:
6824   case 5:
6825     if(same) {
6826
6827       emitpcode(POC_MOVLW, popGetLit(0xf0));
6828       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6829       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6830
6831       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6832       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6833       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6834       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6835     } else {
6836       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6837       emitpcode(POC_ANDLW, popGetLit(0x0f));
6838       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6839
6840       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6841       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6842       emitpcode(POC_ANDLW, popGetLit(0xf0));
6843       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6844       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6845     }
6846
6847     if(shCount >=5) {
6848       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6849       emitpcode(POC_RRF, popGet(AOP(result),offr));
6850     }
6851
6852     if(sign) {
6853       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6854       emitpcode(POC_BTFSC, 
6855                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6856       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6857     }
6858
6859     break;
6860
6861   case 6:
6862     if(same) {
6863
6864       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6865       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6866
6867       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6868       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6869       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6870       emitpcode(POC_ANDLW,popGetLit(0x03));
6871       if(sign) {
6872         emitpcode(POC_BTFSC, 
6873                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6874         emitpcode(POC_IORLW,popGetLit(0xfc));
6875       }
6876       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6877       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6878       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6879       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6880     } else {
6881       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6882       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6883       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6884       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6885       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6886       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6887       emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6888       emitpcode(POC_ANDLW,popGetLit(0x03));
6889       if(sign) {
6890         emitpcode(POC_BTFSC, 
6891                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6892         emitpcode(POC_IORLW,popGetLit(0xfc));
6893       }
6894       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6895       //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6896
6897         
6898     }
6899
6900     break;
6901   case 7:
6902     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6903     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6904     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6905     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6906     if(sign) {
6907       emitSKPNC;
6908       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6909     } else 
6910       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6911   }
6912 }
6913
6914
6915 /*-----------------------------------------------------------------*/
6916 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6917 /*-----------------------------------------------------------------*/
6918 static void shiftLLeftOrResult (operand *left, int offl,
6919                                 operand *result, int offr, int shCount)
6920 {
6921     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6922     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6923     /* shift left accumulator */
6924     AccLsh(shCount);
6925     /* or with result */
6926     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6927     /* back to result */
6928     aopPut(AOP(result),"a",offr);
6929 }
6930
6931 /*-----------------------------------------------------------------*/
6932 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6933 /*-----------------------------------------------------------------*/
6934 static void shiftRLeftOrResult (operand *left, int offl,
6935                                 operand *result, int offr, int shCount)
6936 {
6937     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6938     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6939     /* shift right accumulator */
6940     AccRsh(shCount);
6941     /* or with result */
6942     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6943     /* back to result */
6944     aopPut(AOP(result),"a",offr);
6945 }
6946
6947 /*-----------------------------------------------------------------*/
6948 /* genlshOne - left shift a one byte quantity by known count       */
6949 /*-----------------------------------------------------------------*/
6950 static void genlshOne (operand *result, operand *left, int shCount)
6951 {       
6952     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6953     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6954 }
6955
6956 /*-----------------------------------------------------------------*/
6957 /* genlshTwo - left shift two bytes by known amount != 0           */
6958 /*-----------------------------------------------------------------*/
6959 static void genlshTwo (operand *result,operand *left, int shCount)
6960 {
6961     int size;
6962     
6963     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6964     size = pic14_getDataSize(result);
6965
6966     /* if shCount >= 8 */
6967     if (shCount >= 8) {
6968         shCount -= 8 ;
6969
6970         if (size > 1){
6971             if (shCount)
6972                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6973             else 
6974                 movLeft2Result(left, LSB, result, MSB16);
6975         }
6976         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6977     }
6978
6979     /*  1 <= shCount <= 7 */
6980     else {  
6981         if(size == 1)
6982             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6983         else 
6984             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6985     }
6986 }
6987
6988 /*-----------------------------------------------------------------*/
6989 /* shiftLLong - shift left one long from left to result            */
6990 /* offl = LSB or MSB16                                             */
6991 /*-----------------------------------------------------------------*/
6992 static void shiftLLong (operand *left, operand *result, int offr )
6993 {
6994     char *l;
6995     int size = AOP_SIZE(result);
6996
6997     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6998     if(size >= LSB+offr){
6999         l = aopGet(AOP(left),LSB,FALSE,FALSE);
7000         MOVA(l);
7001         pic14_emitcode("add","a,acc");
7002         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7003             size >= MSB16+offr && offr != LSB )
7004             pic14_emitcode("xch","a,%s",
7005                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7006         else        
7007             aopPut(AOP(result),"a",LSB+offr);
7008     }
7009
7010     if(size >= MSB16+offr){
7011         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7012             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7013             MOVA(l);
7014         }
7015         pic14_emitcode("rlc","a");
7016         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7017             size >= MSB24+offr && offr != LSB)
7018             pic14_emitcode("xch","a,%s",
7019                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7020         else        
7021             aopPut(AOP(result),"a",MSB16+offr);
7022     }
7023
7024     if(size >= MSB24+offr){
7025         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7026             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7027             MOVA(l);
7028         }
7029         pic14_emitcode("rlc","a");
7030         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7031             size >= MSB32+offr && offr != LSB )
7032             pic14_emitcode("xch","a,%s",
7033                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7034         else        
7035             aopPut(AOP(result),"a",MSB24+offr);
7036     }
7037
7038     if(size > MSB32+offr){
7039         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7040             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7041             MOVA(l);    
7042         }
7043         pic14_emitcode("rlc","a");
7044         aopPut(AOP(result),"a",MSB32+offr);
7045     }
7046     if(offr != LSB)
7047         aopPut(AOP(result),zero,LSB);       
7048 }
7049
7050 /*-----------------------------------------------------------------*/
7051 /* genlshFour - shift four byte by a known amount != 0             */
7052 /*-----------------------------------------------------------------*/
7053 static void genlshFour (operand *result, operand *left, int shCount)
7054 {
7055     int size;
7056
7057     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7058     size = AOP_SIZE(result);
7059
7060     /* if shifting more that 3 bytes */
7061     if (shCount >= 24 ) {
7062         shCount -= 24;
7063         if (shCount)
7064             /* lowest order of left goes to the highest
7065             order of the destination */
7066             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7067         else
7068             movLeft2Result(left, LSB, result, MSB32);
7069         aopPut(AOP(result),zero,LSB);
7070         aopPut(AOP(result),zero,MSB16);
7071         aopPut(AOP(result),zero,MSB32);
7072         return;
7073     }
7074
7075     /* more than two bytes */
7076     else if ( shCount >= 16 ) {
7077         /* lower order two bytes goes to higher order two bytes */
7078         shCount -= 16;
7079         /* if some more remaining */
7080         if (shCount)
7081             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7082         else {
7083             movLeft2Result(left, MSB16, result, MSB32);
7084             movLeft2Result(left, LSB, result, MSB24);
7085         }
7086         aopPut(AOP(result),zero,MSB16);
7087         aopPut(AOP(result),zero,LSB);
7088         return;
7089     }    
7090
7091     /* if more than 1 byte */
7092     else if ( shCount >= 8 ) {
7093         /* lower order three bytes goes to higher order  three bytes */
7094         shCount -= 8;
7095         if(size == 2){
7096             if(shCount)
7097                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7098             else
7099                 movLeft2Result(left, LSB, result, MSB16);
7100         }
7101         else{   /* size = 4 */
7102             if(shCount == 0){
7103                 movLeft2Result(left, MSB24, result, MSB32);
7104                 movLeft2Result(left, MSB16, result, MSB24);
7105                 movLeft2Result(left, LSB, result, MSB16);
7106                 aopPut(AOP(result),zero,LSB);
7107             }
7108             else if(shCount == 1)
7109                 shiftLLong(left, result, MSB16);
7110             else{
7111                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7112                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7113                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7114                 aopPut(AOP(result),zero,LSB);
7115             }
7116         }
7117     }
7118
7119     /* 1 <= shCount <= 7 */
7120     else if(shCount <= 2){
7121         shiftLLong(left, result, LSB);
7122         if(shCount == 2)
7123             shiftLLong(result, result, LSB);
7124     }
7125     /* 3 <= shCount <= 7, optimize */
7126     else{
7127         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7128         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7129         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7130     }
7131 }
7132
7133 /*-----------------------------------------------------------------*/
7134 /* genLeftShiftLiteral - left shifting by known count              */
7135 /*-----------------------------------------------------------------*/
7136 static void genLeftShiftLiteral (operand *left,
7137                                  operand *right,
7138                                  operand *result,
7139                                  iCode *ic)
7140 {    
7141     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7142     int size;
7143
7144     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7145     freeAsmop(right,NULL,ic,TRUE);
7146
7147     aopOp(left,ic,FALSE);
7148     aopOp(result,ic,FALSE);
7149
7150     size = getSize(operandType(result));
7151
7152 #if VIEW_SIZE
7153     pic14_emitcode("; shift left ","result %d, left %d",size,
7154              AOP_SIZE(left));
7155 #endif
7156
7157     /* I suppose that the left size >= result size */
7158     if(shCount == 0){
7159         while(size--){
7160             movLeft2Result(left, size, result, size);
7161         }
7162     }
7163
7164     else if(shCount >= (size * 8))
7165         while(size--)
7166             aopPut(AOP(result),zero,size);
7167     else{
7168         switch (size) {
7169             case 1:
7170                 genlshOne (result,left,shCount);
7171                 break;
7172
7173             case 2:
7174             case 3:
7175                 genlshTwo (result,left,shCount);
7176                 break;
7177
7178             case 4:
7179                 genlshFour (result,left,shCount);
7180                 break;
7181         }
7182     }
7183     freeAsmop(left,NULL,ic,TRUE);
7184     freeAsmop(result,NULL,ic,TRUE);
7185 }
7186
7187 /*-----------------------------------------------------------------*
7188  * genMultiAsm - repeat assembly instruction for size of register.
7189  * if endian == 1, then the high byte (i.e base address + size of 
7190  * register) is used first else the low byte is used first;
7191  *-----------------------------------------------------------------*/
7192 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7193 {
7194
7195   int offset = 0;
7196
7197   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7198
7199   if(!reg)
7200     return;
7201
7202   if(!endian) {
7203     endian = 1;
7204   } else {
7205     endian = -1;
7206     offset = size-1;
7207   }
7208
7209   while(size--) {
7210     emitpcode(poc,    popGet(AOP(reg),offset));
7211     offset += endian;
7212   }
7213
7214 }
7215 /*-----------------------------------------------------------------*/
7216 /* genLeftShift - generates code for left shifting                 */
7217 /*-----------------------------------------------------------------*/
7218 static void genLeftShift (iCode *ic)
7219 {
7220   operand *left,*right, *result;
7221   int size, offset;
7222   char *l;
7223   symbol *tlbl , *tlbl1;
7224   pCodeOp *pctemp;
7225
7226   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7227
7228   right = IC_RIGHT(ic);
7229   left  = IC_LEFT(ic);
7230   result = IC_RESULT(ic);
7231
7232   aopOp(right,ic,FALSE);
7233
7234   /* if the shift count is known then do it 
7235      as efficiently as possible */
7236   if (AOP_TYPE(right) == AOP_LIT) {
7237     genLeftShiftLiteral (left,right,result,ic);
7238     return ;
7239   }
7240
7241   /* shift count is unknown then we have to form 
7242      a loop get the loop count in B : Note: we take
7243      only the lower order byte since shifting
7244      more that 32 bits make no sense anyway, ( the
7245      largest size of an object can be only 32 bits ) */  
7246
7247     
7248   aopOp(left,ic,FALSE);
7249   aopOp(result,ic,FALSE);
7250
7251   /* now move the left to the result if they are not the
7252      same */
7253   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7254       AOP_SIZE(result) > 1) {
7255
7256     size = AOP_SIZE(result);
7257     offset=0;
7258     while (size--) {
7259       l = aopGet(AOP(left),offset,FALSE,TRUE);
7260       if (*l == '@' && (IS_AOP_PREG(result))) {
7261
7262         pic14_emitcode("mov","a,%s",l);
7263         aopPut(AOP(result),"a",offset);
7264       } else {
7265         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7266         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7267         //aopPut(AOP(result),l,offset);
7268       }
7269       offset++;
7270     }
7271   }
7272
7273   size = AOP_SIZE(result);
7274
7275   /* if it is only one byte then */
7276   if (size == 1) {
7277     if(optimized_for_speed) {
7278       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7279       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7280       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7281       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7282       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7283       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7284       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7285       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7286       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7287       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7288       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7289       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7290     } else {
7291
7292       tlbl = newiTempLabel(NULL);
7293       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7294         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7295         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7296       }
7297
7298       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7299       emitpcode(POC_RRF,    popGet(AOP(result),0));
7300       emitpLabel(tlbl->key);
7301       emitpcode(POC_RLF,    popGet(AOP(result),0));
7302       emitpcode(POC_ADDLW,  popGetLit(1));
7303       emitSKPC;
7304       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7305     }
7306     goto release ;
7307   }
7308     
7309   if (pic14_sameRegs(AOP(left),AOP(result))) {
7310
7311     tlbl = newiTempLabel(NULL);
7312     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7313     genMultiAsm(POC_RRF, result, size,1);
7314     emitpLabel(tlbl->key);
7315     genMultiAsm(POC_RLF, result, size,0);
7316     emitpcode(POC_ADDLW,  popGetLit(1));
7317     emitSKPC;
7318     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7319     goto release;
7320   }
7321
7322   //tlbl = newiTempLabel(NULL);
7323   //offset = 0 ;   
7324   //tlbl1 = newiTempLabel(NULL);
7325
7326   //reAdjustPreg(AOP(result));    
7327     
7328   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7329   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7330   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7331   //MOVA(l);
7332   //pic14_emitcode("add","a,acc");         
7333   //aopPut(AOP(result),"a",offset++);
7334   //while (--size) {
7335   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7336   //  MOVA(l);
7337   //  pic14_emitcode("rlc","a");         
7338   //  aopPut(AOP(result),"a",offset++);
7339   //}
7340   //reAdjustPreg(AOP(result));
7341
7342   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7343   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7344
7345
7346   tlbl = newiTempLabel(NULL);
7347   tlbl1= newiTempLabel(NULL);
7348
7349   size = AOP_SIZE(result);
7350   offset = 1;
7351
7352   pctemp = popGetTempReg();  /* grab a temporary working register. */
7353
7354   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7355
7356   /* offset should be 0, 1 or 3 */
7357   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7358   emitSKPNZ;
7359   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7360
7361   emitpcode(POC_MOVWF, pctemp);
7362
7363
7364   emitpLabel(tlbl->key);
7365
7366   emitCLRC;
7367   emitpcode(POC_RLF,  popGet(AOP(result),0));
7368   while(--size)
7369     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7370
7371   emitpcode(POC_DECFSZ,  pctemp);
7372   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7373   emitpLabel(tlbl1->key);
7374
7375   popReleaseTempReg(pctemp);
7376
7377
7378  release:
7379   freeAsmop (right,NULL,ic,TRUE);
7380   freeAsmop(left,NULL,ic,TRUE);
7381   freeAsmop(result,NULL,ic,TRUE);
7382 }
7383
7384 /*-----------------------------------------------------------------*/
7385 /* genrshOne - right shift a one byte quantity by known count      */
7386 /*-----------------------------------------------------------------*/
7387 static void genrshOne (operand *result, operand *left,
7388                        int shCount, int sign)
7389 {
7390     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7391     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7392 }
7393
7394 /*-----------------------------------------------------------------*/
7395 /* genrshTwo - right shift two bytes by known amount != 0          */
7396 /*-----------------------------------------------------------------*/
7397 static void genrshTwo (operand *result,operand *left,
7398                        int shCount, int sign)
7399 {
7400   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7401   /* if shCount >= 8 */
7402   if (shCount >= 8) {
7403     shCount -= 8 ;
7404     if (shCount)
7405       shiftR1Left2Result(left, MSB16, result, LSB,
7406                          shCount, sign);
7407     else
7408       movLeft2Result(left, MSB16, result, LSB);
7409
7410     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7411
7412     if(sign) {
7413       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7414       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7415     }
7416   }
7417
7418   /*  1 <= shCount <= 7 */
7419   else
7420     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7421 }
7422
7423 /*-----------------------------------------------------------------*/
7424 /* shiftRLong - shift right one long from left to result           */
7425 /* offl = LSB or MSB16                                             */
7426 /*-----------------------------------------------------------------*/
7427 static void shiftRLong (operand *left, int offl,
7428                         operand *result, int sign)
7429 {
7430     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7431     if(!sign)
7432         pic14_emitcode("clr","c");
7433     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7434     if(sign)
7435         pic14_emitcode("mov","c,acc.7");
7436     pic14_emitcode("rrc","a");
7437     aopPut(AOP(result),"a",MSB32-offl);
7438     if(offl == MSB16)
7439         /* add sign of "a" */
7440         addSign(result, MSB32, sign);
7441
7442     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7443     pic14_emitcode("rrc","a");
7444     aopPut(AOP(result),"a",MSB24-offl);
7445
7446     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7447     pic14_emitcode("rrc","a");
7448     aopPut(AOP(result),"a",MSB16-offl);
7449
7450     if(offl == LSB){
7451         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7452         pic14_emitcode("rrc","a");
7453         aopPut(AOP(result),"a",LSB);
7454     }
7455 }
7456
7457 /*-----------------------------------------------------------------*/
7458 /* genrshFour - shift four byte by a known amount != 0             */
7459 /*-----------------------------------------------------------------*/
7460 static void genrshFour (operand *result, operand *left,
7461                         int shCount, int sign)
7462 {
7463   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7464   /* if shifting more that 3 bytes */
7465   if(shCount >= 24 ) {
7466     shCount -= 24;
7467     if(shCount)
7468       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7469     else
7470       movLeft2Result(left, MSB32, result, LSB);
7471
7472     addSign(result, MSB16, sign);
7473   }
7474   else if(shCount >= 16){
7475     shCount -= 16;
7476     if(shCount)
7477       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7478     else{
7479       movLeft2Result(left, MSB24, result, LSB);
7480       movLeft2Result(left, MSB32, result, MSB16);
7481     }
7482     addSign(result, MSB24, sign);
7483   }
7484   else if(shCount >= 8){
7485     shCount -= 8;
7486     if(shCount == 1)
7487       shiftRLong(left, MSB16, result, sign);
7488     else if(shCount == 0){
7489       movLeft2Result(left, MSB16, result, LSB);
7490       movLeft2Result(left, MSB24, result, MSB16);
7491       movLeft2Result(left, MSB32, result, MSB24);
7492       addSign(result, MSB32, sign);
7493     }
7494     else{
7495       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7496       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7497       /* the last shift is signed */
7498       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7499       addSign(result, MSB32, sign);
7500     }
7501   }
7502   else{   /* 1 <= shCount <= 7 */
7503     if(shCount <= 2){
7504       shiftRLong(left, LSB, result, sign);
7505       if(shCount == 2)
7506         shiftRLong(result, LSB, result, sign);
7507     }
7508     else{
7509       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7510       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7511       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7512     }
7513   }
7514 }
7515
7516 /*-----------------------------------------------------------------*/
7517 /* genRightShiftLiteral - right shifting by known count            */
7518 /*-----------------------------------------------------------------*/
7519 static void genRightShiftLiteral (operand *left,
7520                                   operand *right,
7521                                   operand *result,
7522                                   iCode *ic,
7523                                   int sign)
7524 {    
7525   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7526   int lsize,res_size;
7527
7528   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7529   freeAsmop(right,NULL,ic,TRUE);
7530
7531   aopOp(left,ic,FALSE);
7532   aopOp(result,ic,FALSE);
7533
7534 #if VIEW_SIZE
7535   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7536                  AOP_SIZE(left));
7537 #endif
7538
7539   lsize = pic14_getDataSize(left);
7540   res_size = pic14_getDataSize(result);
7541   /* test the LEFT size !!! */
7542
7543   /* I suppose that the left size >= result size */
7544   if(shCount == 0){
7545     while(res_size--)
7546       movLeft2Result(left, lsize, result, res_size);
7547   }
7548
7549   else if(shCount >= (lsize * 8)){
7550
7551     if(res_size == 1) {
7552       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7553       if(sign) {
7554         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7555         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7556       }
7557     } else {
7558
7559       if(sign) {
7560         emitpcode(POC_MOVLW, popGetLit(0));
7561         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7562         emitpcode(POC_MOVLW, popGetLit(0xff));
7563         while(res_size--)
7564           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7565
7566       } else {
7567
7568         while(res_size--)
7569           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7570       }
7571     }
7572   } else {
7573
7574     switch (res_size) {
7575     case 1:
7576       genrshOne (result,left,shCount,sign);
7577       break;
7578
7579     case 2:
7580       genrshTwo (result,left,shCount,sign);
7581       break;
7582
7583     case 4:
7584       genrshFour (result,left,shCount,sign);
7585       break;
7586     default :
7587       break;
7588     }
7589
7590   }
7591
7592   freeAsmop(left,NULL,ic,TRUE);
7593   freeAsmop(result,NULL,ic,TRUE);
7594 }
7595
7596 /*-----------------------------------------------------------------*/
7597 /* genSignedRightShift - right shift of signed number              */
7598 /*-----------------------------------------------------------------*/
7599 static void genSignedRightShift (iCode *ic)
7600 {
7601   operand *right, *left, *result;
7602   int size, offset;
7603   //  char *l;
7604   symbol *tlbl, *tlbl1 ;
7605   pCodeOp *pctemp;
7606
7607   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7608
7609   /* we do it the hard way put the shift count in b
7610      and loop thru preserving the sign */
7611   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7612
7613   right = IC_RIGHT(ic);
7614   left  = IC_LEFT(ic);
7615   result = IC_RESULT(ic);
7616
7617   aopOp(right,ic,FALSE);  
7618   aopOp(left,ic,FALSE);
7619   aopOp(result,ic,FALSE);
7620
7621
7622   if ( AOP_TYPE(right) == AOP_LIT) {
7623     genRightShiftLiteral (left,right,result,ic,1);
7624     return ;
7625   }
7626   /* shift count is unknown then we have to form 
7627      a loop get the loop count in B : Note: we take
7628      only the lower order byte since shifting
7629      more that 32 bits make no sense anyway, ( the
7630      largest size of an object can be only 32 bits ) */  
7631
7632   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7633   //pic14_emitcode("inc","b");
7634   //freeAsmop (right,NULL,ic,TRUE);
7635   //aopOp(left,ic,FALSE);
7636   //aopOp(result,ic,FALSE);
7637
7638   /* now move the left to the result if they are not the
7639      same */
7640   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7641       AOP_SIZE(result) > 1) {
7642
7643     size = AOP_SIZE(result);
7644     offset=0;
7645     while (size--) { 
7646       /*
7647         l = aopGet(AOP(left),offset,FALSE,TRUE);
7648         if (*l == '@' && IS_AOP_PREG(result)) {
7649
7650         pic14_emitcode("mov","a,%s",l);
7651         aopPut(AOP(result),"a",offset);
7652         } else
7653         aopPut(AOP(result),l,offset);
7654       */
7655       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7656       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7657
7658       offset++;
7659     }
7660   }
7661
7662   /* mov the highest order bit to OVR */    
7663   tlbl = newiTempLabel(NULL);
7664   tlbl1= newiTempLabel(NULL);
7665
7666   size = AOP_SIZE(result);
7667   offset = size - 1;
7668
7669   pctemp = popGetTempReg();  /* grab a temporary working register. */
7670
7671   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7672
7673   /* offset should be 0, 1 or 3 */
7674   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7675   emitSKPNZ;
7676   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7677
7678   emitpcode(POC_MOVWF, pctemp);
7679
7680
7681   emitpLabel(tlbl->key);
7682
7683   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7684   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7685
7686   while(--size) {
7687     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7688   }
7689
7690   emitpcode(POC_DECFSZ,  pctemp);
7691   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7692   emitpLabel(tlbl1->key);
7693
7694   popReleaseTempReg(pctemp);
7695 #if 0
7696   size = AOP_SIZE(result);
7697   offset = size - 1;
7698   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7699   pic14_emitcode("rlc","a");
7700   pic14_emitcode("mov","ov,c");
7701   /* if it is only one byte then */
7702   if (size == 1) {
7703     l = aopGet(AOP(left),0,FALSE,FALSE);
7704     MOVA(l);
7705     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7707     pic14_emitcode("mov","c,ov");
7708     pic14_emitcode("rrc","a");
7709     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7710     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7711     aopPut(AOP(result),"a",0);
7712     goto release ;
7713   }
7714
7715   reAdjustPreg(AOP(result));
7716   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7717   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7718   pic14_emitcode("mov","c,ov");
7719   while (size--) {
7720     l = aopGet(AOP(result),offset,FALSE,FALSE);
7721     MOVA(l);
7722     pic14_emitcode("rrc","a");         
7723     aopPut(AOP(result),"a",offset--);
7724   }
7725   reAdjustPreg(AOP(result));
7726   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7727   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7728
7729  release:
7730 #endif
7731
7732   freeAsmop(left,NULL,ic,TRUE);
7733   freeAsmop(result,NULL,ic,TRUE);
7734   freeAsmop(right,NULL,ic,TRUE);
7735 }
7736
7737 /*-----------------------------------------------------------------*/
7738 /* genRightShift - generate code for right shifting                */
7739 /*-----------------------------------------------------------------*/
7740 static void genRightShift (iCode *ic)
7741 {
7742     operand *right, *left, *result;
7743     sym_link *retype ;
7744     int size, offset;
7745     char *l;
7746     symbol *tlbl, *tlbl1 ;
7747
7748     /* if signed then we do it the hard way preserve the
7749     sign bit moving it inwards */
7750     retype = getSpec(operandType(IC_RESULT(ic)));
7751     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7752
7753     if (!SPEC_USIGN(retype)) {
7754         genSignedRightShift (ic);
7755         return ;
7756     }
7757
7758     /* signed & unsigned types are treated the same : i.e. the
7759     signed is NOT propagated inwards : quoting from the
7760     ANSI - standard : "for E1 >> E2, is equivalent to division
7761     by 2**E2 if unsigned or if it has a non-negative value,
7762     otherwise the result is implementation defined ", MY definition
7763     is that the sign does not get propagated */
7764
7765     right = IC_RIGHT(ic);
7766     left  = IC_LEFT(ic);
7767     result = IC_RESULT(ic);
7768
7769     aopOp(right,ic,FALSE);
7770
7771     /* if the shift count is known then do it 
7772     as efficiently as possible */
7773     if (AOP_TYPE(right) == AOP_LIT) {
7774         genRightShiftLiteral (left,right,result,ic, 0);
7775         return ;
7776     }
7777
7778     /* shift count is unknown then we have to form 
7779     a loop get the loop count in B : Note: we take
7780     only the lower order byte since shifting
7781     more that 32 bits make no sense anyway, ( the
7782     largest size of an object can be only 32 bits ) */  
7783
7784     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7785     pic14_emitcode("inc","b");
7786     aopOp(left,ic,FALSE);
7787     aopOp(result,ic,FALSE);
7788
7789     /* now move the left to the result if they are not the
7790     same */
7791     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7792         AOP_SIZE(result) > 1) {
7793
7794         size = AOP_SIZE(result);
7795         offset=0;
7796         while (size--) {
7797             l = aopGet(AOP(left),offset,FALSE,TRUE);
7798             if (*l == '@' && IS_AOP_PREG(result)) {
7799
7800                 pic14_emitcode("mov","a,%s",l);
7801                 aopPut(AOP(result),"a",offset);
7802             } else
7803                 aopPut(AOP(result),l,offset);
7804             offset++;
7805         }
7806     }
7807
7808     tlbl = newiTempLabel(NULL);
7809     tlbl1= newiTempLabel(NULL);
7810     size = AOP_SIZE(result);
7811     offset = size - 1;
7812
7813     /* if it is only one byte then */
7814     if (size == 1) {
7815
7816       tlbl = newiTempLabel(NULL);
7817       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7818         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7819         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7820       }
7821
7822       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7823       emitpcode(POC_RLF,    popGet(AOP(result),0));
7824       emitpLabel(tlbl->key);
7825       emitpcode(POC_RRF,    popGet(AOP(result),0));
7826       emitpcode(POC_ADDLW,  popGetLit(1));
7827       emitSKPC;
7828       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7829
7830       goto release ;
7831     }
7832
7833     reAdjustPreg(AOP(result));
7834     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7835     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7836     CLRC;
7837     while (size--) {
7838         l = aopGet(AOP(result),offset,FALSE,FALSE);
7839         MOVA(l);
7840         pic14_emitcode("rrc","a");         
7841         aopPut(AOP(result),"a",offset--);
7842     }
7843     reAdjustPreg(AOP(result));
7844
7845     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7846     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7847
7848 release:
7849     freeAsmop(left,NULL,ic,TRUE);
7850     freeAsmop (right,NULL,ic,TRUE);
7851     freeAsmop(result,NULL,ic,TRUE);
7852 }
7853
7854 /*-----------------------------------------------------------------*/
7855 /* genUnpackBits - generates code for unpacking bits               */
7856 /*-----------------------------------------------------------------*/
7857 static void genUnpackBits (operand *result, char *rname, int ptype)
7858 {    
7859     int shCnt ;
7860     int rlen = 0 ;
7861     sym_link *etype;
7862     int offset = 0 ;
7863
7864     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7865     etype = getSpec(operandType(result));
7866
7867     /* read the first byte  */
7868     switch (ptype) {
7869
7870     case POINTER:
7871     case IPOINTER:
7872         pic14_emitcode("mov","a,@%s",rname);
7873         break;
7874         
7875     case PPOINTER:
7876         pic14_emitcode("movx","a,@%s",rname);
7877         break;
7878         
7879     case FPOINTER:
7880         pic14_emitcode("movx","a,@dptr");
7881         break;
7882
7883     case CPOINTER:
7884         pic14_emitcode("clr","a");
7885         pic14_emitcode("movc","a","@a+dptr");
7886         break;
7887
7888     case GPOINTER:
7889         pic14_emitcode("lcall","__gptrget");
7890         break;
7891     }
7892
7893     /* if we have bitdisplacement then it fits   */
7894     /* into this byte completely or if length is */
7895     /* less than a byte                          */
7896     if ((shCnt = SPEC_BSTR(etype)) || 
7897         (SPEC_BLEN(etype) <= 8))  {
7898
7899         /* shift right acc */
7900         AccRsh(shCnt);
7901
7902         pic14_emitcode("anl","a,#0x%02x",
7903                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7904         aopPut(AOP(result),"a",offset);
7905         return ;
7906     }
7907
7908     /* bit field did not fit in a byte  */
7909     rlen = SPEC_BLEN(etype) - 8;
7910     aopPut(AOP(result),"a",offset++);
7911
7912     while (1)  {
7913
7914         switch (ptype) {
7915         case POINTER:
7916         case IPOINTER:
7917             pic14_emitcode("inc","%s",rname);
7918             pic14_emitcode("mov","a,@%s",rname);
7919             break;
7920             
7921         case PPOINTER:
7922             pic14_emitcode("inc","%s",rname);
7923             pic14_emitcode("movx","a,@%s",rname);
7924             break;
7925
7926         case FPOINTER:
7927             pic14_emitcode("inc","dptr");
7928             pic14_emitcode("movx","a,@dptr");
7929             break;
7930             
7931         case CPOINTER:
7932             pic14_emitcode("clr","a");
7933             pic14_emitcode("inc","dptr");
7934             pic14_emitcode("movc","a","@a+dptr");
7935             break;
7936             
7937         case GPOINTER:
7938             pic14_emitcode("inc","dptr");
7939             pic14_emitcode("lcall","__gptrget");
7940             break;
7941         }
7942
7943         rlen -= 8;            
7944         /* if we are done */
7945         if ( rlen <= 0 )
7946             break ;
7947         
7948         aopPut(AOP(result),"a",offset++);
7949                               
7950     }
7951     
7952     if (rlen) {
7953         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7954         aopPut(AOP(result),"a",offset);        
7955     }
7956     
7957     return ;
7958 }
7959
7960 #if 0
7961 /*-----------------------------------------------------------------*/
7962 /* genDataPointerGet - generates code when ptr offset is known     */
7963 /*-----------------------------------------------------------------*/
7964 static void genDataPointerGet (operand *left, 
7965                                operand *result, 
7966                                iCode *ic)
7967 {
7968   int size , offset = 0;
7969
7970
7971   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7972
7973
7974   /* optimization - most of the time, left and result are the same
7975    * address, but different types. for the pic code, we could omit
7976    * the following
7977    */
7978
7979   aopOp(result,ic,TRUE);
7980
7981   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7982
7983   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7984
7985   size = AOP_SIZE(result);
7986
7987   while (size--) {
7988     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7989     offset++;
7990   }
7991
7992   freeAsmop(left,NULL,ic,TRUE);
7993   freeAsmop(result,NULL,ic,TRUE);
7994 }
7995 #endif
7996 /*-----------------------------------------------------------------*/
7997 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7998 /*-----------------------------------------------------------------*/
7999 static void genNearPointerGet (operand *left, 
8000                                operand *result, 
8001                                iCode *ic)
8002 {
8003     asmop *aop = NULL;
8004     //regs *preg = NULL ;
8005     char *rname ;
8006     sym_link *rtype, *retype;
8007     sym_link *ltype = operandType(left);    
8008     //char buffer[80];
8009
8010     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8011
8012     rtype = operandType(result);
8013     retype= getSpec(rtype);
8014     
8015     aopOp(left,ic,FALSE);
8016     
8017     /* if left is rematerialisable and
8018        result is not bit variable type and
8019        the left is pointer to data space i.e
8020        lower 128 bytes of space */
8021     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8022         !IS_BITVAR(retype)         &&
8023         DCL_TYPE(ltype) == POINTER) {
8024       //genDataPointerGet (left,result,ic);
8025         return ;
8026     }
8027     
8028     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8029
8030         /* if the value is already in a pointer register
8031        then don't need anything more */
8032     if (!AOP_INPREG(AOP(left))) {
8033         /* otherwise get a free pointer register */
8034     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8035 /*
8036         aop = newAsmop(0);
8037         preg = getFreePtr(ic,&aop,FALSE);
8038         pic14_emitcode("mov","%s,%s",
8039                 preg->name,
8040                 aopGet(AOP(left),0,FALSE,TRUE));
8041         rname = preg->name ;
8042 */
8043     rname ="BAD";
8044     } else
8045         rname = aopGet(AOP(left),0,FALSE,FALSE);
8046     
8047     aopOp (result,ic,FALSE);
8048     
8049       /* if bitfield then unpack the bits */
8050     if (IS_BITVAR(retype)) 
8051         genUnpackBits (result,rname,POINTER);
8052     else {
8053         /* we have can just get the values */
8054       int size = AOP_SIZE(result);
8055       int offset = 0 ;  
8056         
8057       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8058
8059       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8060       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8061       while(size--) {
8062         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8063         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8064         if(size)
8065           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8066       }
8067 /*
8068         while (size--) {
8069             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8070
8071                 pic14_emitcode("mov","a,@%s",rname);
8072                 aopPut(AOP(result),"a",offset);
8073             } else {
8074                 sprintf(buffer,"@%s",rname);
8075                 aopPut(AOP(result),buffer,offset);
8076             }
8077             offset++ ;
8078             if (size)
8079                 pic14_emitcode("inc","%s",rname);
8080         }
8081 */
8082     }
8083
8084     /* now some housekeeping stuff */
8085     if (aop) {
8086         /* we had to allocate for this iCode */
8087     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8088         freeAsmop(NULL,aop,ic,TRUE);
8089     } else { 
8090         /* we did not allocate which means left
8091            already in a pointer register, then
8092            if size > 0 && this could be used again
8093            we have to point it back to where it 
8094            belongs */
8095     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8096         if (AOP_SIZE(result) > 1 &&
8097             !OP_SYMBOL(left)->remat &&
8098             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8099               ic->depth )) {
8100             int size = AOP_SIZE(result) - 1;
8101             while (size--)
8102                 pic14_emitcode("dec","%s",rname);
8103         }
8104     }
8105
8106     /* done */
8107     freeAsmop(left,NULL,ic,TRUE);
8108     freeAsmop(result,NULL,ic,TRUE);
8109      
8110 }
8111
8112 /*-----------------------------------------------------------------*/
8113 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8114 /*-----------------------------------------------------------------*/
8115 static void genPagedPointerGet (operand *left, 
8116                                operand *result, 
8117                                iCode *ic)
8118 {
8119     asmop *aop = NULL;
8120     regs *preg = NULL ;
8121     char *rname ;
8122     sym_link *rtype, *retype;    
8123
8124     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8125
8126     rtype = operandType(result);
8127     retype= getSpec(rtype);
8128     
8129     aopOp(left,ic,FALSE);
8130
8131   /* if the value is already in a pointer register
8132        then don't need anything more */
8133     if (!AOP_INPREG(AOP(left))) {
8134         /* otherwise get a free pointer register */
8135         aop = newAsmop(0);
8136         preg = getFreePtr(ic,&aop,FALSE);
8137         pic14_emitcode("mov","%s,%s",
8138                 preg->name,
8139                 aopGet(AOP(left),0,FALSE,TRUE));
8140         rname = preg->name ;
8141     } else
8142         rname = aopGet(AOP(left),0,FALSE,FALSE);
8143     
8144     freeAsmop(left,NULL,ic,TRUE);
8145     aopOp (result,ic,FALSE);
8146
8147     /* if bitfield then unpack the bits */
8148     if (IS_BITVAR(retype)) 
8149         genUnpackBits (result,rname,PPOINTER);
8150     else {
8151         /* we have can just get the values */
8152         int size = AOP_SIZE(result);
8153         int offset = 0 ;        
8154         
8155         while (size--) {
8156             
8157             pic14_emitcode("movx","a,@%s",rname);
8158             aopPut(AOP(result),"a",offset);
8159             
8160             offset++ ;
8161             
8162             if (size)
8163                 pic14_emitcode("inc","%s",rname);
8164         }
8165     }
8166
8167     /* now some housekeeping stuff */
8168     if (aop) {
8169         /* we had to allocate for this iCode */
8170         freeAsmop(NULL,aop,ic,TRUE);
8171     } else { 
8172         /* we did not allocate which means left
8173            already in a pointer register, then
8174            if size > 0 && this could be used again
8175            we have to point it back to where it 
8176            belongs */
8177         if (AOP_SIZE(result) > 1 &&
8178             !OP_SYMBOL(left)->remat &&
8179             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8180               ic->depth )) {
8181             int size = AOP_SIZE(result) - 1;
8182             while (size--)
8183                 pic14_emitcode("dec","%s",rname);
8184         }
8185     }
8186
8187     /* done */
8188     freeAsmop(result,NULL,ic,TRUE);
8189     
8190         
8191 }
8192
8193 /*-----------------------------------------------------------------*/
8194 /* genFarPointerGet - gget value from far space                    */
8195 /*-----------------------------------------------------------------*/
8196 static void genFarPointerGet (operand *left,
8197                               operand *result, iCode *ic)
8198 {
8199     int size, offset ;
8200     sym_link *retype = getSpec(operandType(result));
8201
8202     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8203
8204     aopOp(left,ic,FALSE);
8205
8206     /* if the operand is already in dptr 
8207     then we do nothing else we move the value to dptr */
8208     if (AOP_TYPE(left) != AOP_STR) {
8209         /* if this is remateriazable */
8210         if (AOP_TYPE(left) == AOP_IMMD)
8211             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8212         else { /* we need to get it byte by byte */
8213             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8214             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8215             if (options.model == MODEL_FLAT24)
8216             {
8217                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8218             }
8219         }
8220     }
8221     /* so dptr know contains the address */
8222     freeAsmop(left,NULL,ic,TRUE);
8223     aopOp(result,ic,FALSE);
8224
8225     /* if bit then unpack */
8226     if (IS_BITVAR(retype)) 
8227         genUnpackBits(result,"dptr",FPOINTER);
8228     else {
8229         size = AOP_SIZE(result);
8230         offset = 0 ;
8231
8232         while (size--) {
8233             pic14_emitcode("movx","a,@dptr");
8234             aopPut(AOP(result),"a",offset++);
8235             if (size)
8236                 pic14_emitcode("inc","dptr");
8237         }
8238     }
8239
8240     freeAsmop(result,NULL,ic,TRUE);
8241 }
8242 #if 0
8243 /*-----------------------------------------------------------------*/
8244 /* genCodePointerGet - get value from code space                  */
8245 /*-----------------------------------------------------------------*/
8246 static void genCodePointerGet (operand *left,
8247                                 operand *result, iCode *ic)
8248 {
8249     int size, offset ;
8250     sym_link *retype = getSpec(operandType(result));
8251
8252     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8253
8254     aopOp(left,ic,FALSE);
8255
8256     /* if the operand is already in dptr 
8257     then we do nothing else we move the value to dptr */
8258     if (AOP_TYPE(left) != AOP_STR) {
8259         /* if this is remateriazable */
8260         if (AOP_TYPE(left) == AOP_IMMD)
8261             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8262         else { /* we need to get it byte by byte */
8263             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8264             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8265             if (options.model == MODEL_FLAT24)
8266             {
8267                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8268             }
8269         }
8270     }
8271     /* so dptr know contains the address */
8272     freeAsmop(left,NULL,ic,TRUE);
8273     aopOp(result,ic,FALSE);
8274
8275     /* if bit then unpack */
8276     if (IS_BITVAR(retype)) 
8277         genUnpackBits(result,"dptr",CPOINTER);
8278     else {
8279         size = AOP_SIZE(result);
8280         offset = 0 ;
8281
8282         while (size--) {
8283             pic14_emitcode("clr","a");
8284             pic14_emitcode("movc","a,@a+dptr");
8285             aopPut(AOP(result),"a",offset++);
8286             if (size)
8287                 pic14_emitcode("inc","dptr");
8288         }
8289     }
8290
8291     freeAsmop(result,NULL,ic,TRUE);
8292 }
8293 #endif
8294 /*-----------------------------------------------------------------*/
8295 /* genGenPointerGet - gget value from generic pointer space        */
8296 /*-----------------------------------------------------------------*/
8297 static void genGenPointerGet (operand *left,
8298                               operand *result, iCode *ic)
8299 {
8300   int size, offset ;
8301   sym_link *retype = getSpec(operandType(result));
8302
8303   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8304   aopOp(left,ic,FALSE);
8305   aopOp(result,ic,FALSE);
8306
8307
8308   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8309
8310   /* if the operand is already in dptr 
8311      then we do nothing else we move the value to dptr */
8312   //  if (AOP_TYPE(left) != AOP_STR) {
8313     /* if this is remateriazable */
8314     if (AOP_TYPE(left) == AOP_IMMD) {
8315       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8316       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8317     }
8318     else { /* we need to get it byte by byte */
8319
8320       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8321       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8322
8323       size = AOP_SIZE(result);
8324       offset = 0 ;
8325
8326       while(size--) {
8327         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8328         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8329         if(size)
8330           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8331       }
8332       goto release;
8333     }
8334     //}
8335   /* so dptr know contains the address */
8336
8337   /* if bit then unpack */
8338   //if (IS_BITVAR(retype)) 
8339   //  genUnpackBits(result,"dptr",GPOINTER);
8340
8341  release:
8342   freeAsmop(left,NULL,ic,TRUE);
8343   freeAsmop(result,NULL,ic,TRUE);
8344
8345 }
8346
8347 /*-----------------------------------------------------------------*/
8348 /* genConstPointerGet - get value from const generic pointer space */
8349 /*-----------------------------------------------------------------*/
8350 static void genConstPointerGet (operand *left,
8351                                 operand *result, iCode *ic)
8352 {
8353   //sym_link *retype = getSpec(operandType(result));
8354   symbol *albl = newiTempLabel(NULL);
8355   symbol *blbl = newiTempLabel(NULL);
8356   PIC_OPCODE poc;
8357
8358   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8359   aopOp(left,ic,FALSE);
8360   aopOp(result,ic,FALSE);
8361
8362
8363   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8364
8365   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8366
8367   emitpcode(POC_CALL,popGetLabel(albl->key));
8368   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8369   emitpLabel(albl->key);
8370
8371   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8372     
8373   emitpcode(poc,popGet(AOP(left),1));
8374   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8375   emitpcode(poc,popGet(AOP(left),0));
8376   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8377
8378   emitpLabel(blbl->key);
8379
8380   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8381
8382
8383   freeAsmop(left,NULL,ic,TRUE);
8384   freeAsmop(result,NULL,ic,TRUE);
8385
8386 }
8387 /*-----------------------------------------------------------------*/
8388 /* genPointerGet - generate code for pointer get                   */
8389 /*-----------------------------------------------------------------*/
8390 static void genPointerGet (iCode *ic)
8391 {
8392     operand *left, *result ;
8393     sym_link *type, *etype;
8394     int p_type;
8395
8396     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8397
8398     left = IC_LEFT(ic);
8399     result = IC_RESULT(ic) ;
8400
8401     /* depending on the type of pointer we need to
8402     move it to the correct pointer register */
8403     type = operandType(left);
8404     etype = getSpec(type);
8405
8406     if (IS_PTR_CONST(type))
8407       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8408
8409     /* if left is of type of pointer then it is simple */
8410     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8411         p_type = DCL_TYPE(type);
8412     else {
8413         /* we have to go by the storage class */
8414         p_type = PTR_TYPE(SPEC_OCLS(etype));
8415
8416         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8417
8418         if (SPEC_OCLS(etype)->codesp ) {
8419           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8420           //p_type = CPOINTER ; 
8421         }
8422         else
8423             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8424               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8425                /*p_type = FPOINTER ;*/ 
8426             else
8427                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8428                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8429 /*                  p_type = PPOINTER; */
8430                 else
8431                     if (SPEC_OCLS(etype) == idata )
8432                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8433 /*                      p_type = IPOINTER; */
8434                     else
8435                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8436 /*                      p_type = POINTER ; */
8437     }
8438
8439     /* now that we have the pointer type we assign
8440     the pointer values */
8441     switch (p_type) {
8442
8443     case POINTER:       
8444     case IPOINTER:
8445         genNearPointerGet (left,result,ic);
8446         break;
8447
8448     case PPOINTER:
8449         genPagedPointerGet(left,result,ic);
8450         break;
8451
8452     case FPOINTER:
8453         genFarPointerGet (left,result,ic);
8454         break;
8455
8456     case CPOINTER:
8457         genConstPointerGet (left,result,ic);
8458         //pic14_emitcodePointerGet (left,result,ic);
8459         break;
8460
8461     case GPOINTER:
8462       if (IS_PTR_CONST(type))
8463         genConstPointerGet (left,result,ic);
8464       else
8465         genGenPointerGet (left,result,ic);
8466       break;
8467     }
8468
8469 }
8470
8471 /*-----------------------------------------------------------------*/
8472 /* genPackBits - generates code for packed bit storage             */
8473 /*-----------------------------------------------------------------*/
8474 static void genPackBits (sym_link    *etype ,
8475                          operand *right ,
8476                          char *rname, int p_type)
8477 {
8478     int shCount = 0 ;
8479     int offset = 0  ;
8480     int rLen = 0 ;
8481     int blen, bstr ;   
8482     char *l ;
8483
8484     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8485     blen = SPEC_BLEN(etype);
8486     bstr = SPEC_BSTR(etype);
8487
8488     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8489     MOVA(l);   
8490
8491     /* if the bit lenth is less than or    */
8492     /* it exactly fits a byte then         */
8493     if (SPEC_BLEN(etype) <= 8 )  {
8494         shCount = SPEC_BSTR(etype) ;
8495
8496         /* shift left acc */
8497         AccLsh(shCount);
8498
8499         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8500
8501
8502             switch (p_type) {
8503                 case POINTER:
8504                     pic14_emitcode ("mov","b,a");
8505                     pic14_emitcode("mov","a,@%s",rname);
8506                     break;
8507
8508                 case FPOINTER:
8509                     pic14_emitcode ("mov","b,a");
8510                     pic14_emitcode("movx","a,@dptr");
8511                     break;
8512
8513                 case GPOINTER:
8514                     pic14_emitcode ("push","b");
8515                     pic14_emitcode ("push","acc");
8516                     pic14_emitcode ("lcall","__gptrget");
8517                     pic14_emitcode ("pop","b");
8518                     break;
8519             }
8520
8521             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8522                       ((unsigned char)(0xFF << (blen+bstr)) | 
8523                        (unsigned char)(0xFF >> (8-bstr)) ) );
8524             pic14_emitcode ("orl","a,b");
8525             if (p_type == GPOINTER)
8526                 pic14_emitcode("pop","b");
8527         }
8528     }
8529
8530     switch (p_type) {
8531         case POINTER:
8532             pic14_emitcode("mov","@%s,a",rname);
8533             break;
8534
8535         case FPOINTER:
8536             pic14_emitcode("movx","@dptr,a");
8537             break;
8538
8539         case GPOINTER:
8540             DEBUGpic14_emitcode(";lcall","__gptrput");
8541             break;
8542     }
8543
8544     /* if we r done */
8545     if ( SPEC_BLEN(etype) <= 8 )
8546         return ;
8547
8548     pic14_emitcode("inc","%s",rname);
8549     rLen = SPEC_BLEN(etype) ;     
8550
8551     /* now generate for lengths greater than one byte */
8552     while (1) {
8553
8554         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8555
8556         rLen -= 8 ;
8557         if (rLen <= 0 )
8558             break ;
8559
8560         switch (p_type) {
8561             case POINTER:
8562                 if (*l == '@') {
8563                     MOVA(l);
8564                     pic14_emitcode("mov","@%s,a",rname);
8565                 } else
8566                     pic14_emitcode("mov","@%s,%s",rname,l);
8567                 break;
8568
8569             case FPOINTER:
8570                 MOVA(l);
8571                 pic14_emitcode("movx","@dptr,a");
8572                 break;
8573
8574             case GPOINTER:
8575                 MOVA(l);
8576                 DEBUGpic14_emitcode(";lcall","__gptrput");
8577                 break;  
8578         }   
8579         pic14_emitcode ("inc","%s",rname);
8580     }
8581
8582     MOVA(l);
8583
8584     /* last last was not complete */
8585     if (rLen)   {
8586         /* save the byte & read byte */
8587         switch (p_type) {
8588             case POINTER:
8589                 pic14_emitcode ("mov","b,a");
8590                 pic14_emitcode("mov","a,@%s",rname);
8591                 break;
8592
8593             case FPOINTER:
8594                 pic14_emitcode ("mov","b,a");
8595                 pic14_emitcode("movx","a,@dptr");
8596                 break;
8597
8598             case GPOINTER:
8599                 pic14_emitcode ("push","b");
8600                 pic14_emitcode ("push","acc");
8601                 pic14_emitcode ("lcall","__gptrget");
8602                 pic14_emitcode ("pop","b");
8603                 break;
8604         }
8605
8606         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8607         pic14_emitcode ("orl","a,b");
8608     }
8609
8610     if (p_type == GPOINTER)
8611         pic14_emitcode("pop","b");
8612
8613     switch (p_type) {
8614
8615     case POINTER:
8616         pic14_emitcode("mov","@%s,a",rname);
8617         break;
8618         
8619     case FPOINTER:
8620         pic14_emitcode("movx","@dptr,a");
8621         break;
8622         
8623     case GPOINTER:
8624         DEBUGpic14_emitcode(";lcall","__gptrput");
8625         break;                  
8626     }
8627 }
8628 /*-----------------------------------------------------------------*/
8629 /* genDataPointerSet - remat pointer to data space                 */
8630 /*-----------------------------------------------------------------*/
8631 static void genDataPointerSet(operand *right,
8632                               operand *result,
8633                               iCode *ic)
8634 {
8635     int size, offset = 0 ;
8636     char *l, buffer[256];
8637
8638     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8639     aopOp(right,ic,FALSE);
8640     
8641     l = aopGet(AOP(result),0,FALSE,TRUE);
8642     size = AOP_SIZE(right);
8643 /*
8644     if ( AOP_TYPE(result) == AOP_PCODE) {
8645       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8646               AOP(result)->aopu.pcop->name,
8647               PCOI(AOP(result)->aopu.pcop)->offset);
8648     }
8649 */
8650
8651     // tsd, was l+1 - the underline `_' prefix was being stripped
8652     while (size--) {
8653       if (offset) {
8654         sprintf(buffer,"(%s + %d)",l,offset);
8655         fprintf(stderr,"oops  %s\n",buffer);
8656       } else
8657         sprintf(buffer,"%s",l);
8658
8659         if (AOP_TYPE(right) == AOP_LIT) {
8660           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8661           lit = lit >> (8*offset);
8662           if(lit&0xff) {
8663             pic14_emitcode("movlw","%d",lit);
8664             pic14_emitcode("movwf","%s",buffer);
8665
8666             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8667             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8668             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8669
8670           } else {
8671             pic14_emitcode("clrf","%s",buffer);
8672             //emitpcode(POC_CLRF, popRegFromString(buffer));
8673             emitpcode(POC_CLRF, popGet(AOP(result),0));
8674           }
8675         }else {
8676           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8677           pic14_emitcode("movwf","%s",buffer);
8678
8679           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8680           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8681           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8682
8683         }
8684
8685         offset++;
8686     }
8687
8688     freeAsmop(right,NULL,ic,TRUE);
8689     freeAsmop(result,NULL,ic,TRUE);
8690 }
8691
8692 /*-----------------------------------------------------------------*/
8693 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8694 /*-----------------------------------------------------------------*/
8695 static void genNearPointerSet (operand *right,
8696                                operand *result, 
8697                                iCode *ic)
8698 {
8699   asmop *aop = NULL;
8700   char *l;
8701   sym_link *retype;
8702   sym_link *ptype = operandType(result);
8703
8704     
8705   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8706   retype= getSpec(operandType(right));
8707
8708   aopOp(result,ic,FALSE);
8709
8710     
8711   /* if the result is rematerializable &
8712      in data space & not a bit variable */
8713   //if (AOP_TYPE(result) == AOP_IMMD &&
8714   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8715       DCL_TYPE(ptype) == POINTER   &&
8716       !IS_BITVAR(retype)) {
8717     genDataPointerSet (right,result,ic);
8718     freeAsmop(result,NULL,ic,TRUE);
8719     return;
8720   }
8721
8722   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8723   aopOp(right,ic,FALSE);
8724   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8725
8726   /* if the value is already in a pointer register
8727      then don't need anything more */
8728   if (!AOP_INPREG(AOP(result))) {
8729     /* otherwise get a free pointer register */
8730     //aop = newAsmop(0);
8731     //preg = getFreePtr(ic,&aop,FALSE);
8732     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8733     //pic14_emitcode("mov","%s,%s",
8734     //         preg->name,
8735     //         aopGet(AOP(result),0,FALSE,TRUE));
8736     //rname = preg->name ;
8737     //pic14_emitcode("movwf","fsr");
8738     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8739     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8740     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8741     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8742     goto release;
8743
8744   }// else
8745   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8746
8747
8748   /* if bitfield then unpack the bits */
8749   if (IS_BITVAR(retype)) {
8750     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8751            "The programmer is obviously confused");
8752     //genPackBits (retype,right,rname,POINTER);
8753     exit(1);
8754   }
8755   else {
8756     /* we have can just get the values */
8757     int size = AOP_SIZE(right);
8758     int offset = 0 ;    
8759
8760     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8761     while (size--) {
8762       l = aopGet(AOP(right),offset,FALSE,TRUE);
8763       if (*l == '@' ) {
8764         //MOVA(l);
8765         //pic14_emitcode("mov","@%s,a",rname);
8766         pic14_emitcode("movf","indf,w ;1");
8767       } else {
8768
8769         if (AOP_TYPE(right) == AOP_LIT) {
8770           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8771           if(lit) {
8772             pic14_emitcode("movlw","%s",l);
8773             pic14_emitcode("movwf","indf ;2");
8774           } else 
8775             pic14_emitcode("clrf","indf");
8776         }else {
8777           pic14_emitcode("movf","%s,w",l);
8778           pic14_emitcode("movwf","indf ;2");
8779         }
8780         //pic14_emitcode("mov","@%s,%s",rname,l);
8781       }
8782       if (size)
8783         pic14_emitcode("incf","fsr,f ;3");
8784       //pic14_emitcode("inc","%s",rname);
8785       offset++;
8786     }
8787   }
8788
8789   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8790   /* now some housekeeping stuff */
8791   if (aop) {
8792     /* we had to allocate for this iCode */
8793     freeAsmop(NULL,aop,ic,TRUE);
8794   } else { 
8795     /* we did not allocate which means left
8796        already in a pointer register, then
8797        if size > 0 && this could be used again
8798        we have to point it back to where it 
8799        belongs */
8800     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8801     if (AOP_SIZE(right) > 1 &&
8802         !OP_SYMBOL(result)->remat &&
8803         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8804           ic->depth )) {
8805       int size = AOP_SIZE(right) - 1;
8806       while (size--)
8807         pic14_emitcode("decf","fsr,f");
8808       //pic14_emitcode("dec","%s",rname);
8809     }
8810   }
8811
8812   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8813   /* done */
8814  release:
8815   freeAsmop(right,NULL,ic,TRUE);
8816   freeAsmop(result,NULL,ic,TRUE);
8817 }
8818
8819 /*-----------------------------------------------------------------*/
8820 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8821 /*-----------------------------------------------------------------*/
8822 static void genPagedPointerSet (operand *right,
8823                                operand *result, 
8824                                iCode *ic)
8825 {
8826     asmop *aop = NULL;
8827     regs *preg = NULL ;
8828     char *rname , *l;
8829     sym_link *retype;
8830        
8831     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8832
8833     retype= getSpec(operandType(right));
8834     
8835     aopOp(result,ic,FALSE);
8836     
8837     /* if the value is already in a pointer register
8838        then don't need anything more */
8839     if (!AOP_INPREG(AOP(result))) {
8840         /* otherwise get a free pointer register */
8841         aop = newAsmop(0);
8842         preg = getFreePtr(ic,&aop,FALSE);
8843         pic14_emitcode("mov","%s,%s",
8844                 preg->name,
8845                 aopGet(AOP(result),0,FALSE,TRUE));
8846         rname = preg->name ;
8847     } else
8848         rname = aopGet(AOP(result),0,FALSE,FALSE);
8849     
8850     freeAsmop(result,NULL,ic,TRUE);
8851     aopOp (right,ic,FALSE);
8852
8853     /* if bitfield then unpack the bits */
8854     if (IS_BITVAR(retype)) 
8855         genPackBits (retype,right,rname,PPOINTER);
8856     else {
8857         /* we have can just get the values */
8858         int size = AOP_SIZE(right);
8859         int offset = 0 ;        
8860         
8861         while (size--) {
8862             l = aopGet(AOP(right),offset,FALSE,TRUE);
8863             
8864             MOVA(l);
8865             pic14_emitcode("movx","@%s,a",rname);
8866
8867             if (size)
8868                 pic14_emitcode("inc","%s",rname);
8869
8870             offset++;
8871         }
8872     }
8873     
8874     /* now some housekeeping stuff */
8875     if (aop) {
8876         /* we had to allocate for this iCode */
8877         freeAsmop(NULL,aop,ic,TRUE);
8878     } else { 
8879         /* we did not allocate which means left
8880            already in a pointer register, then
8881            if size > 0 && this could be used again
8882            we have to point it back to where it 
8883            belongs */
8884         if (AOP_SIZE(right) > 1 &&
8885             !OP_SYMBOL(result)->remat &&
8886             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8887               ic->depth )) {
8888             int size = AOP_SIZE(right) - 1;
8889             while (size--)
8890                 pic14_emitcode("dec","%s",rname);
8891         }
8892     }
8893
8894     /* done */
8895     freeAsmop(right,NULL,ic,TRUE);
8896     
8897         
8898 }
8899
8900 /*-----------------------------------------------------------------*/
8901 /* genFarPointerSet - set value from far space                     */
8902 /*-----------------------------------------------------------------*/
8903 static void genFarPointerSet (operand *right,
8904                               operand *result, iCode *ic)
8905 {
8906     int size, offset ;
8907     sym_link *retype = getSpec(operandType(right));
8908
8909     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8910     aopOp(result,ic,FALSE);
8911
8912     /* if the operand is already in dptr 
8913     then we do nothing else we move the value to dptr */
8914     if (AOP_TYPE(result) != AOP_STR) {
8915         /* if this is remateriazable */
8916         if (AOP_TYPE(result) == AOP_IMMD)
8917             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8918         else { /* we need to get it byte by byte */
8919             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8920             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8921             if (options.model == MODEL_FLAT24)
8922             {
8923                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8924             }
8925         }
8926     }
8927     /* so dptr know contains the address */
8928     freeAsmop(result,NULL,ic,TRUE);
8929     aopOp(right,ic,FALSE);
8930
8931     /* if bit then unpack */
8932     if (IS_BITVAR(retype)) 
8933         genPackBits(retype,right,"dptr",FPOINTER);
8934     else {
8935         size = AOP_SIZE(right);
8936         offset = 0 ;
8937
8938         while (size--) {
8939             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8940             MOVA(l);
8941             pic14_emitcode("movx","@dptr,a");
8942             if (size)
8943                 pic14_emitcode("inc","dptr");
8944         }
8945     }
8946
8947     freeAsmop(right,NULL,ic,TRUE);
8948 }
8949
8950 /*-----------------------------------------------------------------*/
8951 /* genGenPointerSet - set value from generic pointer space         */
8952 /*-----------------------------------------------------------------*/
8953 static void genGenPointerSet (operand *right,
8954                               operand *result, iCode *ic)
8955 {
8956   int size, offset ;
8957   sym_link *retype = getSpec(operandType(right));
8958
8959   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8960
8961   aopOp(result,ic,FALSE);
8962   aopOp(right,ic,FALSE);
8963   size = AOP_SIZE(right);
8964
8965   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8966
8967   /* if the operand is already in dptr 
8968      then we do nothing else we move the value to dptr */
8969   if (AOP_TYPE(result) != AOP_STR) {
8970     /* if this is remateriazable */
8971     if (AOP_TYPE(result) == AOP_IMMD) {
8972       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8973       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8974     }
8975     else { /* we need to get it byte by byte */
8976       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8977       size = AOP_SIZE(right);
8978       offset = 0 ;
8979
8980       /* hack hack! see if this the FSR. If so don't load W */
8981       if(AOP_TYPE(right) != AOP_ACC) {
8982
8983
8984         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8985         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8986
8987         if(AOP_SIZE(result) > 1) {
8988           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8989           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8990           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8991
8992         }
8993
8994         //if(size==2)
8995         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8996         //if(size==4) {
8997         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8998         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8999         //}
9000
9001         while(size--) {
9002           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9003           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9004           
9005           if(size)
9006             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9007         }
9008
9009
9010         goto release;
9011       } 
9012
9013       if(aopIdx(AOP(result),0) != 4) {
9014
9015         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9016         goto release;
9017       }
9018
9019       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9020       goto release;
9021
9022     }
9023   }
9024   /* so dptr know contains the address */
9025
9026
9027   /* if bit then unpack */
9028   if (IS_BITVAR(retype)) 
9029     genPackBits(retype,right,"dptr",GPOINTER);
9030   else {
9031     size = AOP_SIZE(right);
9032     offset = 0 ;
9033
9034   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9035
9036     while (size--) {
9037
9038       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9039       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9040
9041       if (AOP_TYPE(right) == AOP_LIT) 
9042         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9043       else
9044         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9045
9046       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9047
9048       offset++;
9049     }
9050   }
9051
9052  release:
9053   freeAsmop(right,NULL,ic,TRUE);
9054   freeAsmop(result,NULL,ic,TRUE);
9055 }
9056
9057 /*-----------------------------------------------------------------*/
9058 /* genPointerSet - stores the value into a pointer location        */
9059 /*-----------------------------------------------------------------*/
9060 static void genPointerSet (iCode *ic)
9061 {    
9062     operand *right, *result ;
9063     sym_link *type, *etype;
9064     int p_type;
9065
9066     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9067
9068     right = IC_RIGHT(ic);
9069     result = IC_RESULT(ic) ;
9070
9071     /* depending on the type of pointer we need to
9072     move it to the correct pointer register */
9073     type = operandType(result);
9074     etype = getSpec(type);
9075     /* if left is of type of pointer then it is simple */
9076     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9077         p_type = DCL_TYPE(type);
9078     }
9079     else {
9080         /* we have to go by the storage class */
9081         p_type = PTR_TYPE(SPEC_OCLS(etype));
9082
9083 /*      if (SPEC_OCLS(etype)->codesp ) { */
9084 /*          p_type = CPOINTER ;  */
9085 /*      } */
9086 /*      else */
9087 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9088 /*              p_type = FPOINTER ; */
9089 /*          else */
9090 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9091 /*                  p_type = PPOINTER ; */
9092 /*              else */
9093 /*                  if (SPEC_OCLS(etype) == idata ) */
9094 /*                      p_type = IPOINTER ; */
9095 /*                  else */
9096 /*                      p_type = POINTER ; */
9097     }
9098
9099     /* now that we have the pointer type we assign
9100     the pointer values */
9101     switch (p_type) {
9102
9103     case POINTER:
9104     case IPOINTER:
9105         genNearPointerSet (right,result,ic);
9106         break;
9107
9108     case PPOINTER:
9109         genPagedPointerSet (right,result,ic);
9110         break;
9111
9112     case FPOINTER:
9113         genFarPointerSet (right,result,ic);
9114         break;
9115
9116     case GPOINTER:
9117         genGenPointerSet (right,result,ic);
9118         break;
9119
9120     default:
9121       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9122               "genPointerSet: illegal pointer type");
9123     }
9124 }
9125
9126 /*-----------------------------------------------------------------*/
9127 /* genIfx - generate code for Ifx statement                        */
9128 /*-----------------------------------------------------------------*/
9129 static void genIfx (iCode *ic, iCode *popIc)
9130 {
9131   operand *cond = IC_COND(ic);
9132   int isbit =0;
9133
9134   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9135
9136   aopOp(cond,ic,FALSE);
9137
9138   /* get the value into acc */
9139   if (AOP_TYPE(cond) != AOP_CRY)
9140     pic14_toBoolean(cond);
9141   else
9142     isbit = 1;
9143   /* the result is now in the accumulator */
9144   freeAsmop(cond,NULL,ic,TRUE);
9145
9146   /* if there was something to be popped then do it */
9147   if (popIc)
9148     genIpop(popIc);
9149
9150   /* if the condition is  a bit variable */
9151   if (isbit && IS_ITEMP(cond) && 
9152       SPIL_LOC(cond)) {
9153     genIfxJump(ic,SPIL_LOC(cond)->rname);
9154     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9155   }
9156   else {
9157     if (isbit && !IS_ITEMP(cond))
9158       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9159     else
9160       genIfxJump(ic,"a");
9161   }
9162   ic->generated = 1;
9163
9164 }
9165
9166 /*-----------------------------------------------------------------*/
9167 /* genAddrOf - generates code for address of                       */
9168 /*-----------------------------------------------------------------*/
9169 static void genAddrOf (iCode *ic)
9170 {
9171   operand *right, *result, *left;
9172   int size, offset ;
9173
9174   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9175
9176
9177   //aopOp(IC_RESULT(ic),ic,FALSE);
9178
9179   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9180   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9181   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9182
9183   DEBUGpic14_AopType(__LINE__,left,right,result);
9184
9185   size = AOP_SIZE(IC_RESULT(ic));
9186   offset = 0;
9187
9188   while (size--) {
9189     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9190     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9191     offset++;
9192   }
9193
9194   freeAsmop(left,NULL,ic,FALSE);
9195   freeAsmop(result,NULL,ic,TRUE);
9196
9197 }
9198
9199 #if 0
9200 /*-----------------------------------------------------------------*/
9201 /* genFarFarAssign - assignment when both are in far space         */
9202 /*-----------------------------------------------------------------*/
9203 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9204 {
9205     int size = AOP_SIZE(right);
9206     int offset = 0;
9207     char *l ;
9208     /* first push the right side on to the stack */
9209     while (size--) {
9210         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9211         MOVA(l);
9212         pic14_emitcode ("push","acc");
9213     }
9214     
9215     freeAsmop(right,NULL,ic,FALSE);
9216     /* now assign DPTR to result */
9217     aopOp(result,ic,FALSE);
9218     size = AOP_SIZE(result);
9219     while (size--) {
9220         pic14_emitcode ("pop","acc");
9221         aopPut(AOP(result),"a",--offset);
9222     }
9223     freeAsmop(result,NULL,ic,FALSE);
9224         
9225 }
9226 #endif
9227
9228 /*-----------------------------------------------------------------*/
9229 /* genAssign - generate code for assignment                        */
9230 /*-----------------------------------------------------------------*/
9231 static void genAssign (iCode *ic)
9232 {
9233   operand *result, *right;
9234   int size, offset,know_W;
9235   unsigned long lit = 0L;
9236
9237   result = IC_RESULT(ic);
9238   right  = IC_RIGHT(ic) ;
9239
9240   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9241
9242   /* if they are the same */
9243   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9244     return ;
9245
9246   aopOp(right,ic,FALSE);
9247   aopOp(result,ic,TRUE);
9248
9249   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9250
9251   /* if they are the same registers */
9252   if (pic14_sameRegs(AOP(right),AOP(result)))
9253     goto release;
9254
9255   /* if the result is a bit */
9256   if (AOP_TYPE(result) == AOP_CRY) {
9257
9258     /* if the right size is a literal then
9259        we know what the value is */
9260     if (AOP_TYPE(right) == AOP_LIT) {
9261           
9262       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9263                   popGet(AOP(result),0));
9264
9265       if (((int) operandLitValue(right))) 
9266         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9267                        AOP(result)->aopu.aop_dir,
9268                        AOP(result)->aopu.aop_dir);
9269       else
9270         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9271                        AOP(result)->aopu.aop_dir,
9272                        AOP(result)->aopu.aop_dir);
9273       goto release;
9274     }
9275
9276     /* the right is also a bit variable */
9277     if (AOP_TYPE(right) == AOP_CRY) {
9278       emitpcode(POC_BCF,    popGet(AOP(result),0));
9279       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9280       emitpcode(POC_BSF,    popGet(AOP(result),0));
9281
9282       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9283                      AOP(result)->aopu.aop_dir,
9284                      AOP(result)->aopu.aop_dir);
9285       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9286                      AOP(right)->aopu.aop_dir,
9287                      AOP(right)->aopu.aop_dir);
9288       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9289                      AOP(result)->aopu.aop_dir,
9290                      AOP(result)->aopu.aop_dir);
9291       goto release ;
9292     }
9293
9294     /* we need to or */
9295     emitpcode(POC_BCF,    popGet(AOP(result),0));
9296     pic14_toBoolean(right);
9297     emitSKPZ;
9298     emitpcode(POC_BSF,    popGet(AOP(result),0));
9299     //aopPut(AOP(result),"a",0);
9300     goto release ;
9301   }
9302
9303   /* bit variables done */
9304   /* general case */
9305   size = AOP_SIZE(result);
9306   offset = 0 ;
9307   if(AOP_TYPE(right) == AOP_LIT)
9308     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9309
9310   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9311   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9312     if(aopIdx(AOP(result),0) == 4) {
9313   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9314       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9315       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9316       goto release;
9317     } else
9318       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9319   }
9320
9321   know_W=-1;
9322   while (size--) {
9323   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9324     if(AOP_TYPE(right) == AOP_LIT) {
9325       if(lit&0xff) {
9326         if(know_W != (lit&0xff))
9327           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9328         know_W = lit&0xff;
9329         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9330       } else
9331         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9332
9333       lit >>= 8;
9334
9335     } else if (AOP_TYPE(right) == AOP_CRY) {
9336       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9337       if(offset == 0) {
9338         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9339         emitpcode(POC_INCF, popGet(AOP(result),0));
9340       }
9341     } else {
9342   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9343       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9344       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9345     }
9346             
9347     offset++;
9348   }
9349
9350     
9351  release:
9352   freeAsmop (right,NULL,ic,FALSE);
9353   freeAsmop (result,NULL,ic,TRUE);
9354 }   
9355
9356 /*-----------------------------------------------------------------*/
9357 /* genJumpTab - genrates code for jump table                       */
9358 /*-----------------------------------------------------------------*/
9359 static void genJumpTab (iCode *ic)
9360 {
9361     symbol *jtab;
9362     char *l;
9363
9364     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9365
9366     aopOp(IC_JTCOND(ic),ic,FALSE);
9367     /* get the condition into accumulator */
9368     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9369     MOVA(l);
9370     /* multiply by three */
9371     pic14_emitcode("add","a,acc");
9372     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9373
9374     jtab = newiTempLabel(NULL);
9375     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9376     pic14_emitcode("jmp","@a+dptr");
9377     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9378
9379     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9380     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9381     emitSKPNC;
9382     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9383     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9384     emitpLabel(jtab->key);
9385
9386     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9387
9388     /* now generate the jump labels */
9389     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9390          jtab = setNextItem(IC_JTLABELS(ic))) {
9391         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9392         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9393         
9394     }
9395
9396 }
9397
9398 /*-----------------------------------------------------------------*/
9399 /* genMixedOperation - gen code for operators between mixed types  */
9400 /*-----------------------------------------------------------------*/
9401 /*
9402   TSD - Written for the PIC port - but this unfortunately is buggy.
9403   This routine is good in that it is able to efficiently promote 
9404   types to different (larger) sizes. Unfortunately, the temporary
9405   variables that are optimized out by this routine are sometimes
9406   used in other places. So until I know how to really parse the 
9407   iCode tree, I'm going to not be using this routine :(.
9408 */
9409 static int genMixedOperation (iCode *ic)
9410 {
9411 #if 0
9412   operand *result = IC_RESULT(ic);
9413   sym_link *ctype = operandType(IC_LEFT(ic));
9414   operand *right = IC_RIGHT(ic);
9415   int ret = 0;
9416   int big,small;
9417   int offset;
9418
9419   iCode *nextic;
9420   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9421
9422   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9423
9424   nextic = ic->next;
9425   if(!nextic)
9426     return 0;
9427
9428   nextright = IC_RIGHT(nextic);
9429   nextleft  = IC_LEFT(nextic);
9430   nextresult = IC_RESULT(nextic);
9431
9432   aopOp(right,ic,FALSE);
9433   aopOp(result,ic,FALSE);
9434   aopOp(nextright,  nextic, FALSE);
9435   aopOp(nextleft,   nextic, FALSE);
9436   aopOp(nextresult, nextic, FALSE);
9437
9438   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9439
9440     operand *t = right;
9441     right = nextright;
9442     nextright = t; 
9443
9444     pic14_emitcode(";remove right +","");
9445
9446   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9447 /*
9448     operand *t = right;
9449     right = nextleft;
9450     nextleft = t; 
9451 */
9452     pic14_emitcode(";remove left +","");
9453   } else
9454     return 0;
9455
9456   big = AOP_SIZE(nextleft);
9457   small = AOP_SIZE(nextright);
9458
9459   switch(nextic->op) {
9460
9461   case '+':
9462     pic14_emitcode(";optimize a +","");
9463     /* if unsigned or not an integral type */
9464     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9465       pic14_emitcode(";add a bit to something","");
9466     } else {
9467
9468       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9469
9470       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9471         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9472         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9473       } else
9474         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9475
9476       offset = 0;
9477       while(--big) {
9478
9479         offset++;
9480
9481         if(--small) {
9482           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9483             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9484             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9485           }
9486
9487           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488           emitSKPNC;
9489           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9490                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9491                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9492           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9494
9495         } else {
9496           pic14_emitcode("rlf","known_zero,w");
9497
9498           /*
9499             if right is signed
9500               btfsc  right,7
9501                addlw ff
9502           */
9503           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9504             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9505             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9506           } else {
9507             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9508           }
9509         }
9510       }
9511       ret = 1;
9512     }
9513   }
9514   ret = 1;
9515
9516 release:
9517   freeAsmop(right,NULL,ic,TRUE);
9518   freeAsmop(result,NULL,ic,TRUE);
9519   freeAsmop(nextright,NULL,ic,TRUE);
9520   freeAsmop(nextleft,NULL,ic,TRUE);
9521   if(ret)
9522     nextic->generated = 1;
9523
9524   return ret;
9525 #else
9526   return 0;
9527 #endif
9528 }
9529 /*-----------------------------------------------------------------*/
9530 /* genCast - gen code for casting                                  */
9531 /*-----------------------------------------------------------------*/
9532 static void genCast (iCode *ic)
9533 {
9534     operand *result = IC_RESULT(ic);
9535     sym_link *ctype = operandType(IC_LEFT(ic));
9536     sym_link *rtype = operandType(IC_RIGHT(ic));
9537     operand *right = IC_RIGHT(ic);
9538     int size, offset ;
9539
9540     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9541     /* if they are equivalent then do nothing */
9542     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9543         return ;
9544
9545     aopOp(right,ic,FALSE) ;
9546     aopOp(result,ic,FALSE);
9547
9548     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9549
9550     /* if the result is a bit */
9551     if (AOP_TYPE(result) == AOP_CRY) {
9552         /* if the right size is a literal then
9553         we know what the value is */
9554       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9555         if (AOP_TYPE(right) == AOP_LIT) {
9556
9557           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9558                       popGet(AOP(result),0));
9559
9560             if (((int) operandLitValue(right))) 
9561               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9562                        AOP(result)->aopu.aop_dir,
9563                        AOP(result)->aopu.aop_dir);
9564             else
9565               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9566                        AOP(result)->aopu.aop_dir,
9567                        AOP(result)->aopu.aop_dir);
9568
9569             goto release;
9570         }
9571
9572         /* the right is also a bit variable */
9573         if (AOP_TYPE(right) == AOP_CRY) {
9574
9575           emitCLRC;
9576           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9577
9578           pic14_emitcode("clrc","");
9579           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9580                    AOP(right)->aopu.aop_dir,
9581                    AOP(right)->aopu.aop_dir);
9582             aopPut(AOP(result),"c",0);
9583             goto release ;
9584         }
9585
9586         /* we need to or */
9587         if (AOP_TYPE(right) == AOP_REG) {
9588           emitpcode(POC_BCF,    popGet(AOP(result),0));
9589           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9590           emitpcode(POC_BSF,    popGet(AOP(result),0));
9591         }
9592         pic14_toBoolean(right);
9593         aopPut(AOP(result),"a",0);
9594         goto release ;
9595     }
9596
9597     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9598       int offset = 1;
9599       size = AOP_SIZE(result);
9600
9601       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9602
9603       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9604       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9605       emitpcode(POC_INCF,   popGet(AOP(result),0));
9606
9607       while (size--)
9608         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9609
9610       goto release;
9611     }
9612
9613     /* if they are the same size : or less */
9614     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9615
9616         /* if they are in the same place */
9617       if (pic14_sameRegs(AOP(right),AOP(result)))
9618         goto release;
9619
9620       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9621       if (IS_PTR_CONST(rtype))
9622         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9623       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9624         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9625
9626       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9627         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9628         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9629         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9630         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9631         if(AOP_SIZE(result) <2)
9632           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9633
9634       } else {
9635
9636         /* if they in different places then copy */
9637         size = AOP_SIZE(result);
9638         offset = 0 ;
9639         while (size--) {
9640           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9641           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9642
9643           //aopPut(AOP(result),
9644           // aopGet(AOP(right),offset,FALSE,FALSE),
9645           // offset);
9646
9647           offset++;
9648         }
9649       }
9650       goto release;
9651     }
9652
9653
9654     /* if the result is of type pointer */
9655     if (IS_PTR(ctype)) {
9656
9657         int p_type;
9658         sym_link *type = operandType(right);
9659         sym_link *etype = getSpec(type);
9660       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9661
9662         /* pointer to generic pointer */
9663         if (IS_GENPTR(ctype)) {
9664             char *l = zero;
9665             
9666             if (IS_PTR(type)) 
9667                 p_type = DCL_TYPE(type);
9668             else {
9669                 /* we have to go by the storage class */
9670                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9671
9672 /*              if (SPEC_OCLS(etype)->codesp )  */
9673 /*                  p_type = CPOINTER ;  */
9674 /*              else */
9675 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9676 /*                      p_type = FPOINTER ; */
9677 /*                  else */
9678 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9679 /*                          p_type = PPOINTER; */
9680 /*                      else */
9681 /*                          if (SPEC_OCLS(etype) == idata ) */
9682 /*                              p_type = IPOINTER ; */
9683 /*                          else */
9684 /*                              p_type = POINTER ; */
9685             }
9686                 
9687             /* the first two bytes are known */
9688       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9689             size = GPTRSIZE - 1; 
9690             offset = 0 ;
9691             while (size--) {
9692               if(offset < AOP_SIZE(right)) {
9693       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9694                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9695                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9696                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9697                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9698                 } else { 
9699                   aopPut(AOP(result),
9700                          aopGet(AOP(right),offset,FALSE,FALSE),
9701                          offset);
9702                 }
9703               } else 
9704                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9705               offset++;
9706             }
9707             /* the last byte depending on type */
9708             switch (p_type) {
9709             case IPOINTER:
9710             case POINTER:
9711                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9712                 break;
9713             case FPOINTER:
9714               pic14_emitcode(";BUG!? ","%d",__LINE__);
9715                 l = one;
9716                 break;
9717             case CPOINTER:
9718               pic14_emitcode(";BUG!? ","%d",__LINE__);
9719                 l = "#0x02";
9720                 break;                          
9721             case PPOINTER:
9722               pic14_emitcode(";BUG!? ","%d",__LINE__);
9723                 l = "#0x03";
9724                 break;
9725                 
9726             default:
9727                 /* this should never happen */
9728                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9729                        "got unknown pointer type");
9730                 exit(1);
9731             }
9732             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9733             goto release ;
9734         }
9735         
9736         /* just copy the pointers */
9737         size = AOP_SIZE(result);
9738         offset = 0 ;
9739         while (size--) {
9740             aopPut(AOP(result),
9741                    aopGet(AOP(right),offset,FALSE,FALSE),
9742                    offset);
9743             offset++;
9744         }
9745         goto release ;
9746     }
9747     
9748
9749
9750     /* so we now know that the size of destination is greater
9751     than the size of the source.
9752     Now, if the next iCode is an operator then we might be
9753     able to optimize the operation without performing a cast.
9754     */
9755     if(genMixedOperation(ic))
9756       goto release;
9757
9758     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9759     
9760     /* we move to result for the size of source */
9761     size = AOP_SIZE(right);
9762     offset = 0 ;
9763     while (size--) {
9764       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9765       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9766       offset++;
9767     }
9768
9769     /* now depending on the sign of the destination */
9770     size = AOP_SIZE(result) - AOP_SIZE(right);
9771     /* if unsigned or not an integral type */
9772     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9773       while (size--)
9774         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9775     } else {
9776       /* we need to extend the sign :{ */
9777
9778       if(size == 1) {
9779         /* Save one instruction of casting char to int */
9780         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9781         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9782         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9783       } else {
9784         emitpcodeNULLop(POC_CLRW);
9785
9786         if(offset)
9787           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9788         else
9789           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9790         
9791         emitpcode(POC_MOVLW,   popGetLit(0xff));
9792
9793         while (size--)
9794           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9795       }
9796     }
9797
9798 release:
9799     freeAsmop(right,NULL,ic,TRUE);
9800     freeAsmop(result,NULL,ic,TRUE);
9801
9802 }
9803
9804 /*-----------------------------------------------------------------*/
9805 /* genDjnz - generate decrement & jump if not zero instrucion      */
9806 /*-----------------------------------------------------------------*/
9807 static int genDjnz (iCode *ic, iCode *ifx)
9808 {
9809     symbol *lbl, *lbl1;
9810     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9811
9812     if (!ifx)
9813         return 0;
9814     
9815     /* if the if condition has a false label
9816        then we cannot save */
9817     if (IC_FALSE(ifx))
9818         return 0;
9819
9820     /* if the minus is not of the form 
9821        a = a - 1 */
9822     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9823         !IS_OP_LITERAL(IC_RIGHT(ic)))
9824         return 0;
9825
9826     if (operandLitValue(IC_RIGHT(ic)) != 1)
9827         return 0;
9828
9829     /* if the size of this greater than one then no
9830        saving */
9831     if (getSize(operandType(IC_RESULT(ic))) > 1)
9832         return 0;
9833
9834     /* otherwise we can save BIG */
9835     lbl = newiTempLabel(NULL);
9836     lbl1= newiTempLabel(NULL);
9837
9838     aopOp(IC_RESULT(ic),ic,FALSE);
9839     
9840     if (IS_AOP_PREG(IC_RESULT(ic))) {
9841         pic14_emitcode("dec","%s",
9842                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9844         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9845     } else {    
9846
9847
9848       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9849       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9850
9851       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9852       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9853
9854     }
9855 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9856 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9857 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9858 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9859
9860     
9861     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9862     ifx->generated = 1;
9863     return 1;
9864 }
9865
9866 /*-----------------------------------------------------------------*/
9867 /* genReceive - generate code for a receive iCode                  */
9868 /*-----------------------------------------------------------------*/
9869 static void genReceive (iCode *ic)
9870 {    
9871   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9872
9873   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9874       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9875         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9876
9877     int size = getSize(operandType(IC_RESULT(ic)));
9878     int offset =  fReturnSizePic - size;
9879     while (size--) {
9880       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9881                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9882       offset++;
9883     }
9884     aopOp(IC_RESULT(ic),ic,FALSE);  
9885     size = AOP_SIZE(IC_RESULT(ic));
9886     offset = 0;
9887     while (size--) {
9888       pic14_emitcode ("pop","acc");
9889       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9890     }
9891         
9892   } else {
9893     _G.accInUse++;
9894     aopOp(IC_RESULT(ic),ic,FALSE);  
9895     _G.accInUse--;
9896     assignResultValue(IC_RESULT(ic));   
9897   }
9898
9899   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9900 }
9901
9902 /*-----------------------------------------------------------------*/
9903 /* genpic14Code - generate code for pic14 based controllers        */
9904 /*-----------------------------------------------------------------*/
9905 /*
9906  * At this point, ralloc.c has gone through the iCode and attempted
9907  * to optimize in a way suitable for a PIC. Now we've got to generate
9908  * PIC instructions that correspond to the iCode.
9909  *
9910  * Once the instructions are generated, we'll pass through both the
9911  * peep hole optimizer and the pCode optimizer.
9912  *-----------------------------------------------------------------*/
9913
9914 void genpic14Code (iCode *lic)
9915 {
9916     iCode *ic;
9917     int cln = 0;
9918
9919     lineHead = lineCurr = NULL;
9920
9921     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9922     addpBlock(pb);
9923
9924     /* if debug information required */
9925     if (options.debug && currFunc) { 
9926       if (currFunc) {
9927         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9928         _G.debugLine = 1;
9929         if (IS_STATIC(currFunc->etype)) {
9930           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9931           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9932         } else {
9933           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9934           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9935         }
9936         _G.debugLine = 0;
9937       }
9938     }
9939
9940
9941     for (ic = lic ; ic ; ic = ic->next ) {
9942
9943       DEBUGpic14_emitcode(";ic","");
9944         if ( cln != ic->lineno ) {
9945             if ( options.debug ) {
9946                 _G.debugLine = 1;
9947                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9948                          FileBaseName(ic->filename),ic->lineno,
9949                          ic->level,ic->block);
9950                 _G.debugLine = 0;
9951             }
9952             /*
9953               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9954               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9955               printCLine(ic->filename, ic->lineno));
9956             */
9957             addpCode2pBlock(pb,
9958                             newpCodeCSource(ic->lineno, 
9959                                             ic->filename, 
9960                                             printCLine(ic->filename, ic->lineno)));
9961
9962             cln = ic->lineno ;
9963         }
9964         /* if the result is marked as
9965            spilt and rematerializable or code for
9966            this has already been generated then
9967            do nothing */
9968         if (resultRemat(ic) || ic->generated ) 
9969             continue ;
9970         
9971         /* depending on the operation */
9972         switch (ic->op) {
9973         case '!' :
9974             genNot(ic);
9975             break;
9976             
9977         case '~' :
9978             genCpl(ic);
9979             break;
9980             
9981         case UNARYMINUS:
9982             genUminus (ic);
9983             break;
9984             
9985         case IPUSH:
9986             genIpush (ic);
9987             break;
9988             
9989         case IPOP:
9990             /* IPOP happens only when trying to restore a 
9991                spilt live range, if there is an ifx statement
9992                following this pop then the if statement might
9993                be using some of the registers being popped which
9994                would destory the contents of the register so
9995                we need to check for this condition and handle it */
9996             if (ic->next            && 
9997                 ic->next->op == IFX &&
9998                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9999                 genIfx (ic->next,ic);
10000             else
10001                 genIpop (ic);
10002             break; 
10003             
10004         case CALL:
10005             genCall (ic);
10006             break;
10007             
10008         case PCALL:
10009             genPcall (ic);
10010             break;
10011             
10012         case FUNCTION:
10013             genFunction (ic);
10014             break;
10015             
10016         case ENDFUNCTION:
10017             genEndFunction (ic);
10018             break;
10019             
10020         case RETURN:
10021             genRet (ic);
10022             break;
10023             
10024         case LABEL:
10025             genLabel (ic);
10026             break;
10027             
10028         case GOTO:
10029             genGoto (ic);
10030             break;
10031             
10032         case '+' :
10033             genPlus (ic) ;
10034             break;
10035             
10036         case '-' :
10037             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10038                 genMinus (ic);
10039             break;
10040             
10041         case '*' :
10042             genMult (ic);
10043             break;
10044             
10045         case '/' :
10046             genDiv (ic) ;
10047             break;
10048             
10049         case '%' :
10050             genMod (ic);
10051             break;
10052             
10053         case '>' :
10054             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10055             break;
10056             
10057         case '<' :
10058             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10059             break;
10060             
10061         case LE_OP:
10062         case GE_OP:
10063         case NE_OP:
10064             
10065             /* note these two are xlated by algebraic equivalence
10066                during parsing SDCC.y */
10067             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10068                    "got '>=' or '<=' shouldn't have come here");
10069             break;      
10070             
10071         case EQ_OP:
10072             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10073             break;          
10074             
10075         case AND_OP:
10076             genAndOp (ic);
10077             break;
10078             
10079         case OR_OP:
10080             genOrOp (ic);
10081             break;
10082             
10083         case '^' :
10084             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10085             break;
10086             
10087         case '|' :
10088                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10089             break;
10090             
10091         case BITWISEAND:
10092             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10093             break;
10094             
10095         case INLINEASM:
10096             genInline (ic);
10097             break;
10098             
10099         case RRC:
10100             genRRC (ic);
10101             break;
10102             
10103         case RLC:
10104             genRLC (ic);
10105             break;
10106             
10107         case GETHBIT:
10108             genGetHbit (ic);
10109             break;
10110             
10111         case LEFT_OP:
10112             genLeftShift (ic);
10113             break;
10114             
10115         case RIGHT_OP:
10116             genRightShift (ic);
10117             break;
10118             
10119         case GET_VALUE_AT_ADDRESS:
10120             genPointerGet(ic);
10121             break;
10122             
10123         case '=' :
10124             if (POINTER_SET(ic))
10125                 genPointerSet(ic);
10126             else
10127                 genAssign(ic);
10128             break;
10129             
10130         case IFX:
10131             genIfx (ic,NULL);
10132             break;
10133             
10134         case ADDRESS_OF:
10135             genAddrOf (ic);
10136             break;
10137             
10138         case JUMPTABLE:
10139             genJumpTab (ic);
10140             break;
10141             
10142         case CAST:
10143             genCast (ic);
10144             break;
10145             
10146         case RECEIVE:
10147             genReceive(ic);
10148             break;
10149             
10150         case SEND:
10151             addSet(&_G.sendSet,ic);
10152             break;
10153
10154         default :
10155             ic = ic;
10156         }
10157     }
10158     
10159
10160     /* now we are ready to call the 
10161        peep hole optimizer */
10162     if (!options.nopeep) {
10163       peepHole (&lineHead);
10164     }
10165     /* now do the actual printing */
10166     printLine (lineHead,codeOutFile);
10167
10168 #ifdef PCODE_DEBUG
10169     DFPRINTF((stderr,"printing pBlock\n\n"));
10170     printpBlock(stdout,pb);
10171 #endif
10172
10173     return;
10174 }