Indirect pointer access to banks 2 and 3 on the 'f877 now works.
[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   } else {
6781     movLeft2Result(left,offl, result, offr);
6782     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6783   }
6784   /* a:x >> shCount (x = lsb(result))*/
6785 /*
6786   if(sign)
6787     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6788   else {
6789     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6790 */
6791   switch(shCount) {
6792   case 0:
6793     break;
6794   case 1:
6795   case 2:
6796   case 3:
6797     if(sign)
6798       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6799     else
6800       emitCLRC;
6801
6802     if(same) {
6803       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6804       emitpcode(POC_RRF,popGet(AOP(result),offr));
6805     } else {
6806       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6807       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6809       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6810     }
6811
6812     while(--shCount) {
6813       if(sign)
6814         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6815       else
6816         emitCLRC;
6817       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6818       emitpcode(POC_RRF,popGet(AOP(result),offr));
6819     }
6820     break;
6821   case 4:
6822   case 5:
6823     if(same) {
6824
6825       emitpcode(POC_MOVLW, popGetLit(0xf0));
6826       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6827       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6828
6829       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6830       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6831       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6832       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6833     } else {
6834       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6835       emitpcode(POC_ANDLW, popGetLit(0x0f));
6836       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6837
6838       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6839       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6840       emitpcode(POC_ANDLW, popGetLit(0xf0));
6841       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6842       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6843     }
6844
6845     if(shCount >=5) {
6846       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6847       emitpcode(POC_RRF, popGet(AOP(result),offr));
6848     }
6849
6850     if(sign) {
6851       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6852       emitpcode(POC_BTFSC, 
6853                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6854       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6855     }
6856
6857     break;
6858
6859   case 6:
6860     if(same) {
6861
6862       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6863       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6864
6865       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6866       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6867       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6868       emitpcode(POC_ANDLW,popGetLit(0x03));
6869       if(sign) {
6870         emitpcode(POC_BTFSC, 
6871                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6872         emitpcode(POC_IORLW,popGetLit(0xfc));
6873       }
6874       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6875       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6876       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6877       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6878     } else {
6879       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6880       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6881       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6882       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6883       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6884       emitpcode(POC_ANDLW,popGetLit(0x03));
6885       if(sign) {
6886         emitpcode(POC_BTFSC, 
6887                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6888         emitpcode(POC_IORLW,popGetLit(0xfc));
6889       }
6890       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6891       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6892
6893         
6894     }
6895
6896     break;
6897   case 7:
6898     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6899     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6900     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6901     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6902     if(sign) {
6903       emitSKPNC;
6904       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6905     } else 
6906       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6907   }
6908 }
6909
6910
6911 /*-----------------------------------------------------------------*/
6912 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6913 /*-----------------------------------------------------------------*/
6914 static void shiftLLeftOrResult (operand *left, int offl,
6915                                 operand *result, int offr, int shCount)
6916 {
6917     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6918     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6919     /* shift left accumulator */
6920     AccLsh(shCount);
6921     /* or with result */
6922     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6923     /* back to result */
6924     aopPut(AOP(result),"a",offr);
6925 }
6926
6927 /*-----------------------------------------------------------------*/
6928 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6929 /*-----------------------------------------------------------------*/
6930 static void shiftRLeftOrResult (operand *left, int offl,
6931                                 operand *result, int offr, int shCount)
6932 {
6933     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6934     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6935     /* shift right accumulator */
6936     AccRsh(shCount);
6937     /* or with result */
6938     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6939     /* back to result */
6940     aopPut(AOP(result),"a",offr);
6941 }
6942
6943 /*-----------------------------------------------------------------*/
6944 /* genlshOne - left shift a one byte quantity by known count       */
6945 /*-----------------------------------------------------------------*/
6946 static void genlshOne (operand *result, operand *left, int shCount)
6947 {       
6948     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6949     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6950 }
6951
6952 /*-----------------------------------------------------------------*/
6953 /* genlshTwo - left shift two bytes by known amount != 0           */
6954 /*-----------------------------------------------------------------*/
6955 static void genlshTwo (operand *result,operand *left, int shCount)
6956 {
6957     int size;
6958     
6959     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6960     size = pic14_getDataSize(result);
6961
6962     /* if shCount >= 8 */
6963     if (shCount >= 8) {
6964         shCount -= 8 ;
6965
6966         if (size > 1){
6967             if (shCount)
6968                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6969             else 
6970                 movLeft2Result(left, LSB, result, MSB16);
6971         }
6972         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6973     }
6974
6975     /*  1 <= shCount <= 7 */
6976     else {  
6977         if(size == 1)
6978             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6979         else 
6980             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6981     }
6982 }
6983
6984 /*-----------------------------------------------------------------*/
6985 /* shiftLLong - shift left one long from left to result            */
6986 /* offl = LSB or MSB16                                             */
6987 /*-----------------------------------------------------------------*/
6988 static void shiftLLong (operand *left, operand *result, int offr )
6989 {
6990     char *l;
6991     int size = AOP_SIZE(result);
6992
6993     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6994     if(size >= LSB+offr){
6995         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6996         MOVA(l);
6997         pic14_emitcode("add","a,acc");
6998         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6999             size >= MSB16+offr && offr != LSB )
7000             pic14_emitcode("xch","a,%s",
7001                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7002         else        
7003             aopPut(AOP(result),"a",LSB+offr);
7004     }
7005
7006     if(size >= MSB16+offr){
7007         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7008             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7009             MOVA(l);
7010         }
7011         pic14_emitcode("rlc","a");
7012         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7013             size >= MSB24+offr && offr != LSB)
7014             pic14_emitcode("xch","a,%s",
7015                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7016         else        
7017             aopPut(AOP(result),"a",MSB16+offr);
7018     }
7019
7020     if(size >= MSB24+offr){
7021         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7022             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7023             MOVA(l);
7024         }
7025         pic14_emitcode("rlc","a");
7026         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7027             size >= MSB32+offr && offr != LSB )
7028             pic14_emitcode("xch","a,%s",
7029                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7030         else        
7031             aopPut(AOP(result),"a",MSB24+offr);
7032     }
7033
7034     if(size > MSB32+offr){
7035         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7036             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7037             MOVA(l);    
7038         }
7039         pic14_emitcode("rlc","a");
7040         aopPut(AOP(result),"a",MSB32+offr);
7041     }
7042     if(offr != LSB)
7043         aopPut(AOP(result),zero,LSB);       
7044 }
7045
7046 /*-----------------------------------------------------------------*/
7047 /* genlshFour - shift four byte by a known amount != 0             */
7048 /*-----------------------------------------------------------------*/
7049 static void genlshFour (operand *result, operand *left, int shCount)
7050 {
7051     int size;
7052
7053     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7054     size = AOP_SIZE(result);
7055
7056     /* if shifting more that 3 bytes */
7057     if (shCount >= 24 ) {
7058         shCount -= 24;
7059         if (shCount)
7060             /* lowest order of left goes to the highest
7061             order of the destination */
7062             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7063         else
7064             movLeft2Result(left, LSB, result, MSB32);
7065         aopPut(AOP(result),zero,LSB);
7066         aopPut(AOP(result),zero,MSB16);
7067         aopPut(AOP(result),zero,MSB32);
7068         return;
7069     }
7070
7071     /* more than two bytes */
7072     else if ( shCount >= 16 ) {
7073         /* lower order two bytes goes to higher order two bytes */
7074         shCount -= 16;
7075         /* if some more remaining */
7076         if (shCount)
7077             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7078         else {
7079             movLeft2Result(left, MSB16, result, MSB32);
7080             movLeft2Result(left, LSB, result, MSB24);
7081         }
7082         aopPut(AOP(result),zero,MSB16);
7083         aopPut(AOP(result),zero,LSB);
7084         return;
7085     }    
7086
7087     /* if more than 1 byte */
7088     else if ( shCount >= 8 ) {
7089         /* lower order three bytes goes to higher order  three bytes */
7090         shCount -= 8;
7091         if(size == 2){
7092             if(shCount)
7093                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7094             else
7095                 movLeft2Result(left, LSB, result, MSB16);
7096         }
7097         else{   /* size = 4 */
7098             if(shCount == 0){
7099                 movLeft2Result(left, MSB24, result, MSB32);
7100                 movLeft2Result(left, MSB16, result, MSB24);
7101                 movLeft2Result(left, LSB, result, MSB16);
7102                 aopPut(AOP(result),zero,LSB);
7103             }
7104             else if(shCount == 1)
7105                 shiftLLong(left, result, MSB16);
7106             else{
7107                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7108                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7109                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7110                 aopPut(AOP(result),zero,LSB);
7111             }
7112         }
7113     }
7114
7115     /* 1 <= shCount <= 7 */
7116     else if(shCount <= 2){
7117         shiftLLong(left, result, LSB);
7118         if(shCount == 2)
7119             shiftLLong(result, result, LSB);
7120     }
7121     /* 3 <= shCount <= 7, optimize */
7122     else{
7123         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7124         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7125         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7126     }
7127 }
7128
7129 /*-----------------------------------------------------------------*/
7130 /* genLeftShiftLiteral - left shifting by known count              */
7131 /*-----------------------------------------------------------------*/
7132 static void genLeftShiftLiteral (operand *left,
7133                                  operand *right,
7134                                  operand *result,
7135                                  iCode *ic)
7136 {    
7137     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7138     int size;
7139
7140     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7141     freeAsmop(right,NULL,ic,TRUE);
7142
7143     aopOp(left,ic,FALSE);
7144     aopOp(result,ic,FALSE);
7145
7146     size = getSize(operandType(result));
7147
7148 #if VIEW_SIZE
7149     pic14_emitcode("; shift left ","result %d, left %d",size,
7150              AOP_SIZE(left));
7151 #endif
7152
7153     /* I suppose that the left size >= result size */
7154     if(shCount == 0){
7155         while(size--){
7156             movLeft2Result(left, size, result, size);
7157         }
7158     }
7159
7160     else if(shCount >= (size * 8))
7161         while(size--)
7162             aopPut(AOP(result),zero,size);
7163     else{
7164         switch (size) {
7165             case 1:
7166                 genlshOne (result,left,shCount);
7167                 break;
7168
7169             case 2:
7170             case 3:
7171                 genlshTwo (result,left,shCount);
7172                 break;
7173
7174             case 4:
7175                 genlshFour (result,left,shCount);
7176                 break;
7177         }
7178     }
7179     freeAsmop(left,NULL,ic,TRUE);
7180     freeAsmop(result,NULL,ic,TRUE);
7181 }
7182
7183 /*-----------------------------------------------------------------*
7184  * genMultiAsm - repeat assembly instruction for size of register.
7185  * if endian == 1, then the high byte (i.e base address + size of 
7186  * register) is used first else the low byte is used first;
7187  *-----------------------------------------------------------------*/
7188 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7189 {
7190
7191   int offset = 0;
7192
7193   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7194
7195   if(!reg)
7196     return;
7197
7198   if(!endian) {
7199     endian = 1;
7200   } else {
7201     endian = -1;
7202     offset = size-1;
7203   }
7204
7205   while(size--) {
7206     emitpcode(poc,    popGet(AOP(reg),offset));
7207     offset += endian;
7208   }
7209
7210 }
7211 /*-----------------------------------------------------------------*/
7212 /* genLeftShift - generates code for left shifting                 */
7213 /*-----------------------------------------------------------------*/
7214 static void genLeftShift (iCode *ic)
7215 {
7216   operand *left,*right, *result;
7217   int size, offset;
7218   char *l;
7219   symbol *tlbl , *tlbl1;
7220   pCodeOp *pctemp;
7221
7222   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7223
7224   right = IC_RIGHT(ic);
7225   left  = IC_LEFT(ic);
7226   result = IC_RESULT(ic);
7227
7228   aopOp(right,ic,FALSE);
7229
7230   /* if the shift count is known then do it 
7231      as efficiently as possible */
7232   if (AOP_TYPE(right) == AOP_LIT) {
7233     genLeftShiftLiteral (left,right,result,ic);
7234     return ;
7235   }
7236
7237   /* shift count is unknown then we have to form 
7238      a loop get the loop count in B : Note: we take
7239      only the lower order byte since shifting
7240      more that 32 bits make no sense anyway, ( the
7241      largest size of an object can be only 32 bits ) */  
7242
7243     
7244   aopOp(left,ic,FALSE);
7245   aopOp(result,ic,FALSE);
7246
7247   /* now move the left to the result if they are not the
7248      same */
7249   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7250       AOP_SIZE(result) > 1) {
7251
7252     size = AOP_SIZE(result);
7253     offset=0;
7254     while (size--) {
7255       l = aopGet(AOP(left),offset,FALSE,TRUE);
7256       if (*l == '@' && (IS_AOP_PREG(result))) {
7257
7258         pic14_emitcode("mov","a,%s",l);
7259         aopPut(AOP(result),"a",offset);
7260       } else {
7261         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7262         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7263         //aopPut(AOP(result),l,offset);
7264       }
7265       offset++;
7266     }
7267   }
7268
7269   size = AOP_SIZE(result);
7270
7271   /* if it is only one byte then */
7272   if (size == 1) {
7273     if(optimized_for_speed) {
7274       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7275       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7276       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7277       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7278       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7279       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7280       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7281       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7282       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7283       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7284       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7285       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7286     } else {
7287
7288       tlbl = newiTempLabel(NULL);
7289       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7290         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7291         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7292       }
7293
7294       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7295       emitpcode(POC_RRF,    popGet(AOP(result),0));
7296       emitpLabel(tlbl->key);
7297       emitpcode(POC_RLF,    popGet(AOP(result),0));
7298       emitpcode(POC_ADDLW,  popGetLit(1));
7299       emitSKPC;
7300       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7301     }
7302     goto release ;
7303   }
7304     
7305   if (pic14_sameRegs(AOP(left),AOP(result))) {
7306
7307     tlbl = newiTempLabel(NULL);
7308     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7309     genMultiAsm(POC_RRF, result, size,1);
7310     emitpLabel(tlbl->key);
7311     genMultiAsm(POC_RLF, result, size,0);
7312     emitpcode(POC_ADDLW,  popGetLit(1));
7313     emitSKPC;
7314     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7315     goto release;
7316   }
7317
7318   //tlbl = newiTempLabel(NULL);
7319   //offset = 0 ;   
7320   //tlbl1 = newiTempLabel(NULL);
7321
7322   //reAdjustPreg(AOP(result));    
7323     
7324   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7325   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7326   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7327   //MOVA(l);
7328   //pic14_emitcode("add","a,acc");         
7329   //aopPut(AOP(result),"a",offset++);
7330   //while (--size) {
7331   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7332   //  MOVA(l);
7333   //  pic14_emitcode("rlc","a");         
7334   //  aopPut(AOP(result),"a",offset++);
7335   //}
7336   //reAdjustPreg(AOP(result));
7337
7338   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7339   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7340
7341
7342   tlbl = newiTempLabel(NULL);
7343   tlbl1= newiTempLabel(NULL);
7344
7345   size = AOP_SIZE(result);
7346   offset = 1;
7347
7348   pctemp = popGetTempReg();  /* grab a temporary working register. */
7349
7350   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7351
7352   /* offset should be 0, 1 or 3 */
7353   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7354   emitSKPNZ;
7355   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7356
7357   emitpcode(POC_MOVWF, pctemp);
7358
7359
7360   emitpLabel(tlbl->key);
7361
7362   emitCLRC;
7363   emitpcode(POC_RLF,  popGet(AOP(result),0));
7364   while(--size)
7365     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7366
7367   emitpcode(POC_DECFSZ,  pctemp);
7368   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7369   emitpLabel(tlbl1->key);
7370
7371   popReleaseTempReg(pctemp);
7372
7373
7374  release:
7375   freeAsmop (right,NULL,ic,TRUE);
7376   freeAsmop(left,NULL,ic,TRUE);
7377   freeAsmop(result,NULL,ic,TRUE);
7378 }
7379
7380 /*-----------------------------------------------------------------*/
7381 /* genrshOne - right shift a one byte quantity by known count      */
7382 /*-----------------------------------------------------------------*/
7383 static void genrshOne (operand *result, operand *left,
7384                        int shCount, int sign)
7385 {
7386     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7387     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7388 }
7389
7390 /*-----------------------------------------------------------------*/
7391 /* genrshTwo - right shift two bytes by known amount != 0          */
7392 /*-----------------------------------------------------------------*/
7393 static void genrshTwo (operand *result,operand *left,
7394                        int shCount, int sign)
7395 {
7396   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7397   /* if shCount >= 8 */
7398   if (shCount >= 8) {
7399     shCount -= 8 ;
7400     if (shCount)
7401       shiftR1Left2Result(left, MSB16, result, LSB,
7402                          shCount, sign);
7403     else
7404       movLeft2Result(left, MSB16, result, LSB);
7405
7406     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7407
7408     if(sign) {
7409       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7410       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7411     }
7412   }
7413
7414   /*  1 <= shCount <= 7 */
7415   else
7416     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7417 }
7418
7419 /*-----------------------------------------------------------------*/
7420 /* shiftRLong - shift right one long from left to result           */
7421 /* offl = LSB or MSB16                                             */
7422 /*-----------------------------------------------------------------*/
7423 static void shiftRLong (operand *left, int offl,
7424                         operand *result, int sign)
7425 {
7426     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7427     if(!sign)
7428         pic14_emitcode("clr","c");
7429     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7430     if(sign)
7431         pic14_emitcode("mov","c,acc.7");
7432     pic14_emitcode("rrc","a");
7433     aopPut(AOP(result),"a",MSB32-offl);
7434     if(offl == MSB16)
7435         /* add sign of "a" */
7436         addSign(result, MSB32, sign);
7437
7438     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7439     pic14_emitcode("rrc","a");
7440     aopPut(AOP(result),"a",MSB24-offl);
7441
7442     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7443     pic14_emitcode("rrc","a");
7444     aopPut(AOP(result),"a",MSB16-offl);
7445
7446     if(offl == LSB){
7447         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7448         pic14_emitcode("rrc","a");
7449         aopPut(AOP(result),"a",LSB);
7450     }
7451 }
7452
7453 /*-----------------------------------------------------------------*/
7454 /* genrshFour - shift four byte by a known amount != 0             */
7455 /*-----------------------------------------------------------------*/
7456 static void genrshFour (operand *result, operand *left,
7457                         int shCount, int sign)
7458 {
7459   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7460   /* if shifting more that 3 bytes */
7461   if(shCount >= 24 ) {
7462     shCount -= 24;
7463     if(shCount)
7464       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7465     else
7466       movLeft2Result(left, MSB32, result, LSB);
7467
7468     addSign(result, MSB16, sign);
7469   }
7470   else if(shCount >= 16){
7471     shCount -= 16;
7472     if(shCount)
7473       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7474     else{
7475       movLeft2Result(left, MSB24, result, LSB);
7476       movLeft2Result(left, MSB32, result, MSB16);
7477     }
7478     addSign(result, MSB24, sign);
7479   }
7480   else if(shCount >= 8){
7481     shCount -= 8;
7482     if(shCount == 1)
7483       shiftRLong(left, MSB16, result, sign);
7484     else if(shCount == 0){
7485       movLeft2Result(left, MSB16, result, LSB);
7486       movLeft2Result(left, MSB24, result, MSB16);
7487       movLeft2Result(left, MSB32, result, MSB24);
7488       addSign(result, MSB32, sign);
7489     }
7490     else{
7491       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7492       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7493       /* the last shift is signed */
7494       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7495       addSign(result, MSB32, sign);
7496     }
7497   }
7498   else{   /* 1 <= shCount <= 7 */
7499     if(shCount <= 2){
7500       shiftRLong(left, LSB, result, sign);
7501       if(shCount == 2)
7502         shiftRLong(result, LSB, result, sign);
7503     }
7504     else{
7505       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7506       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7507       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7508     }
7509   }
7510 }
7511
7512 /*-----------------------------------------------------------------*/
7513 /* genRightShiftLiteral - right shifting by known count            */
7514 /*-----------------------------------------------------------------*/
7515 static void genRightShiftLiteral (operand *left,
7516                                   operand *right,
7517                                   operand *result,
7518                                   iCode *ic,
7519                                   int sign)
7520 {    
7521   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7522   int lsize,res_size;
7523
7524   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7525   freeAsmop(right,NULL,ic,TRUE);
7526
7527   aopOp(left,ic,FALSE);
7528   aopOp(result,ic,FALSE);
7529
7530 #if VIEW_SIZE
7531   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7532                  AOP_SIZE(left));
7533 #endif
7534
7535   lsize = pic14_getDataSize(left);
7536   res_size = pic14_getDataSize(result);
7537   /* test the LEFT size !!! */
7538
7539   /* I suppose that the left size >= result size */
7540   if(shCount == 0){
7541     while(res_size--)
7542       movLeft2Result(left, lsize, result, res_size);
7543   }
7544
7545   else if(shCount >= (lsize * 8)){
7546
7547     if(res_size == 1) {
7548       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7549       if(sign) {
7550         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7552       }
7553     } else {
7554
7555       if(sign) {
7556         emitpcode(POC_MOVLW, popGetLit(0));
7557         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7558         emitpcode(POC_MOVLW, popGetLit(0xff));
7559         while(res_size--)
7560           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7561
7562       } else {
7563
7564         while(res_size--)
7565           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7566       }
7567     }
7568   } else {
7569
7570     switch (res_size) {
7571     case 1:
7572       genrshOne (result,left,shCount,sign);
7573       break;
7574
7575     case 2:
7576       genrshTwo (result,left,shCount,sign);
7577       break;
7578
7579     case 4:
7580       genrshFour (result,left,shCount,sign);
7581       break;
7582     default :
7583       break;
7584     }
7585
7586   }
7587
7588   freeAsmop(left,NULL,ic,TRUE);
7589   freeAsmop(result,NULL,ic,TRUE);
7590 }
7591
7592 /*-----------------------------------------------------------------*/
7593 /* genSignedRightShift - right shift of signed number              */
7594 /*-----------------------------------------------------------------*/
7595 static void genSignedRightShift (iCode *ic)
7596 {
7597   operand *right, *left, *result;
7598   int size, offset;
7599   //  char *l;
7600   symbol *tlbl, *tlbl1 ;
7601   pCodeOp *pctemp;
7602
7603   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7604
7605   /* we do it the hard way put the shift count in b
7606      and loop thru preserving the sign */
7607   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7608
7609   right = IC_RIGHT(ic);
7610   left  = IC_LEFT(ic);
7611   result = IC_RESULT(ic);
7612
7613   aopOp(right,ic,FALSE);  
7614   aopOp(left,ic,FALSE);
7615   aopOp(result,ic,FALSE);
7616
7617
7618   if ( AOP_TYPE(right) == AOP_LIT) {
7619     genRightShiftLiteral (left,right,result,ic,1);
7620     return ;
7621   }
7622   /* shift count is unknown then we have to form 
7623      a loop get the loop count in B : Note: we take
7624      only the lower order byte since shifting
7625      more that 32 bits make no sense anyway, ( the
7626      largest size of an object can be only 32 bits ) */  
7627
7628   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7629   //pic14_emitcode("inc","b");
7630   //freeAsmop (right,NULL,ic,TRUE);
7631   //aopOp(left,ic,FALSE);
7632   //aopOp(result,ic,FALSE);
7633
7634   /* now move the left to the result if they are not the
7635      same */
7636   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7637       AOP_SIZE(result) > 1) {
7638
7639     size = AOP_SIZE(result);
7640     offset=0;
7641     while (size--) { 
7642       /*
7643         l = aopGet(AOP(left),offset,FALSE,TRUE);
7644         if (*l == '@' && IS_AOP_PREG(result)) {
7645
7646         pic14_emitcode("mov","a,%s",l);
7647         aopPut(AOP(result),"a",offset);
7648         } else
7649         aopPut(AOP(result),l,offset);
7650       */
7651       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7652       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7653
7654       offset++;
7655     }
7656   }
7657
7658   /* mov the highest order bit to OVR */    
7659   tlbl = newiTempLabel(NULL);
7660   tlbl1= newiTempLabel(NULL);
7661
7662   size = AOP_SIZE(result);
7663   offset = size - 1;
7664
7665   pctemp = popGetTempReg();  /* grab a temporary working register. */
7666
7667   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7668
7669   /* offset should be 0, 1 or 3 */
7670   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7671   emitSKPNZ;
7672   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7673
7674   emitpcode(POC_MOVWF, pctemp);
7675
7676
7677   emitpLabel(tlbl->key);
7678
7679   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7680   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7681
7682   while(--size) {
7683     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7684   }
7685
7686   emitpcode(POC_DECFSZ,  pctemp);
7687   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7688   emitpLabel(tlbl1->key);
7689
7690   popReleaseTempReg(pctemp);
7691 #if 0
7692   size = AOP_SIZE(result);
7693   offset = size - 1;
7694   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7695   pic14_emitcode("rlc","a");
7696   pic14_emitcode("mov","ov,c");
7697   /* if it is only one byte then */
7698   if (size == 1) {
7699     l = aopGet(AOP(left),0,FALSE,FALSE);
7700     MOVA(l);
7701     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7702     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7703     pic14_emitcode("mov","c,ov");
7704     pic14_emitcode("rrc","a");
7705     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7706     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7707     aopPut(AOP(result),"a",0);
7708     goto release ;
7709   }
7710
7711   reAdjustPreg(AOP(result));
7712   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7713   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7714   pic14_emitcode("mov","c,ov");
7715   while (size--) {
7716     l = aopGet(AOP(result),offset,FALSE,FALSE);
7717     MOVA(l);
7718     pic14_emitcode("rrc","a");         
7719     aopPut(AOP(result),"a",offset--);
7720   }
7721   reAdjustPreg(AOP(result));
7722   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7723   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7724
7725  release:
7726 #endif
7727
7728   freeAsmop(left,NULL,ic,TRUE);
7729   freeAsmop(result,NULL,ic,TRUE);
7730   freeAsmop(right,NULL,ic,TRUE);
7731 }
7732
7733 /*-----------------------------------------------------------------*/
7734 /* genRightShift - generate code for right shifting                */
7735 /*-----------------------------------------------------------------*/
7736 static void genRightShift (iCode *ic)
7737 {
7738     operand *right, *left, *result;
7739     sym_link *retype ;
7740     int size, offset;
7741     char *l;
7742     symbol *tlbl, *tlbl1 ;
7743
7744     /* if signed then we do it the hard way preserve the
7745     sign bit moving it inwards */
7746     retype = getSpec(operandType(IC_RESULT(ic)));
7747     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7748
7749     if (!SPEC_USIGN(retype)) {
7750         genSignedRightShift (ic);
7751         return ;
7752     }
7753
7754     /* signed & unsigned types are treated the same : i.e. the
7755     signed is NOT propagated inwards : quoting from the
7756     ANSI - standard : "for E1 >> E2, is equivalent to division
7757     by 2**E2 if unsigned or if it has a non-negative value,
7758     otherwise the result is implementation defined ", MY definition
7759     is that the sign does not get propagated */
7760
7761     right = IC_RIGHT(ic);
7762     left  = IC_LEFT(ic);
7763     result = IC_RESULT(ic);
7764
7765     aopOp(right,ic,FALSE);
7766
7767     /* if the shift count is known then do it 
7768     as efficiently as possible */
7769     if (AOP_TYPE(right) == AOP_LIT) {
7770         genRightShiftLiteral (left,right,result,ic, 0);
7771         return ;
7772     }
7773
7774     /* shift count is unknown then we have to form 
7775     a loop get the loop count in B : Note: we take
7776     only the lower order byte since shifting
7777     more that 32 bits make no sense anyway, ( the
7778     largest size of an object can be only 32 bits ) */  
7779
7780     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7781     pic14_emitcode("inc","b");
7782     aopOp(left,ic,FALSE);
7783     aopOp(result,ic,FALSE);
7784
7785     /* now move the left to the result if they are not the
7786     same */
7787     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7788         AOP_SIZE(result) > 1) {
7789
7790         size = AOP_SIZE(result);
7791         offset=0;
7792         while (size--) {
7793             l = aopGet(AOP(left),offset,FALSE,TRUE);
7794             if (*l == '@' && IS_AOP_PREG(result)) {
7795
7796                 pic14_emitcode("mov","a,%s",l);
7797                 aopPut(AOP(result),"a",offset);
7798             } else
7799                 aopPut(AOP(result),l,offset);
7800             offset++;
7801         }
7802     }
7803
7804     tlbl = newiTempLabel(NULL);
7805     tlbl1= newiTempLabel(NULL);
7806     size = AOP_SIZE(result);
7807     offset = size - 1;
7808
7809     /* if it is only one byte then */
7810     if (size == 1) {
7811
7812       tlbl = newiTempLabel(NULL);
7813       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7814         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7815         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7816       }
7817
7818       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7819       emitpcode(POC_RLF,    popGet(AOP(result),0));
7820       emitpLabel(tlbl->key);
7821       emitpcode(POC_RRF,    popGet(AOP(result),0));
7822       emitpcode(POC_ADDLW,  popGetLit(1));
7823       emitSKPC;
7824       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7825
7826       goto release ;
7827     }
7828
7829     reAdjustPreg(AOP(result));
7830     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7831     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7832     CLRC;
7833     while (size--) {
7834         l = aopGet(AOP(result),offset,FALSE,FALSE);
7835         MOVA(l);
7836         pic14_emitcode("rrc","a");         
7837         aopPut(AOP(result),"a",offset--);
7838     }
7839     reAdjustPreg(AOP(result));
7840
7841     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7842     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7843
7844 release:
7845     freeAsmop(left,NULL,ic,TRUE);
7846     freeAsmop (right,NULL,ic,TRUE);
7847     freeAsmop(result,NULL,ic,TRUE);
7848 }
7849
7850 /*-----------------------------------------------------------------*/
7851 /* genUnpackBits - generates code for unpacking bits               */
7852 /*-----------------------------------------------------------------*/
7853 static void genUnpackBits (operand *result, char *rname, int ptype)
7854 {    
7855     int shCnt ;
7856     int rlen = 0 ;
7857     sym_link *etype;
7858     int offset = 0 ;
7859
7860     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7861     etype = getSpec(operandType(result));
7862
7863     /* read the first byte  */
7864     switch (ptype) {
7865
7866     case POINTER:
7867     case IPOINTER:
7868         pic14_emitcode("mov","a,@%s",rname);
7869         break;
7870         
7871     case PPOINTER:
7872         pic14_emitcode("movx","a,@%s",rname);
7873         break;
7874         
7875     case FPOINTER:
7876         pic14_emitcode("movx","a,@dptr");
7877         break;
7878
7879     case CPOINTER:
7880         pic14_emitcode("clr","a");
7881         pic14_emitcode("movc","a","@a+dptr");
7882         break;
7883
7884     case GPOINTER:
7885         pic14_emitcode("lcall","__gptrget");
7886         break;
7887     }
7888
7889     /* if we have bitdisplacement then it fits   */
7890     /* into this byte completely or if length is */
7891     /* less than a byte                          */
7892     if ((shCnt = SPEC_BSTR(etype)) || 
7893         (SPEC_BLEN(etype) <= 8))  {
7894
7895         /* shift right acc */
7896         AccRsh(shCnt);
7897
7898         pic14_emitcode("anl","a,#0x%02x",
7899                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7900         aopPut(AOP(result),"a",offset);
7901         return ;
7902     }
7903
7904     /* bit field did not fit in a byte  */
7905     rlen = SPEC_BLEN(etype) - 8;
7906     aopPut(AOP(result),"a",offset++);
7907
7908     while (1)  {
7909
7910         switch (ptype) {
7911         case POINTER:
7912         case IPOINTER:
7913             pic14_emitcode("inc","%s",rname);
7914             pic14_emitcode("mov","a,@%s",rname);
7915             break;
7916             
7917         case PPOINTER:
7918             pic14_emitcode("inc","%s",rname);
7919             pic14_emitcode("movx","a,@%s",rname);
7920             break;
7921
7922         case FPOINTER:
7923             pic14_emitcode("inc","dptr");
7924             pic14_emitcode("movx","a,@dptr");
7925             break;
7926             
7927         case CPOINTER:
7928             pic14_emitcode("clr","a");
7929             pic14_emitcode("inc","dptr");
7930             pic14_emitcode("movc","a","@a+dptr");
7931             break;
7932             
7933         case GPOINTER:
7934             pic14_emitcode("inc","dptr");
7935             pic14_emitcode("lcall","__gptrget");
7936             break;
7937         }
7938
7939         rlen -= 8;            
7940         /* if we are done */
7941         if ( rlen <= 0 )
7942             break ;
7943         
7944         aopPut(AOP(result),"a",offset++);
7945                               
7946     }
7947     
7948     if (rlen) {
7949         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7950         aopPut(AOP(result),"a",offset);        
7951     }
7952     
7953     return ;
7954 }
7955
7956 #if 0
7957 /*-----------------------------------------------------------------*/
7958 /* genDataPointerGet - generates code when ptr offset is known     */
7959 /*-----------------------------------------------------------------*/
7960 static void genDataPointerGet (operand *left, 
7961                                operand *result, 
7962                                iCode *ic)
7963 {
7964   int size , offset = 0;
7965
7966
7967   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7968
7969
7970   /* optimization - most of the time, left and result are the same
7971    * address, but different types. for the pic code, we could omit
7972    * the following
7973    */
7974
7975   aopOp(result,ic,TRUE);
7976
7977   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7978
7979   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7980
7981   size = AOP_SIZE(result);
7982
7983   while (size--) {
7984     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7985     offset++;
7986   }
7987
7988   freeAsmop(left,NULL,ic,TRUE);
7989   freeAsmop(result,NULL,ic,TRUE);
7990 }
7991 #endif
7992 /*-----------------------------------------------------------------*/
7993 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7994 /*-----------------------------------------------------------------*/
7995 static void genNearPointerGet (operand *left, 
7996                                operand *result, 
7997                                iCode *ic)
7998 {
7999     asmop *aop = NULL;
8000     //regs *preg = NULL ;
8001     char *rname ;
8002     sym_link *rtype, *retype;
8003     sym_link *ltype = operandType(left);    
8004     //char buffer[80];
8005
8006     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8007
8008     rtype = operandType(result);
8009     retype= getSpec(rtype);
8010     
8011     aopOp(left,ic,FALSE);
8012     
8013     /* if left is rematerialisable and
8014        result is not bit variable type and
8015        the left is pointer to data space i.e
8016        lower 128 bytes of space */
8017     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8018         !IS_BITVAR(retype)         &&
8019         DCL_TYPE(ltype) == POINTER) {
8020       //genDataPointerGet (left,result,ic);
8021         return ;
8022     }
8023     
8024     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8025
8026         /* if the value is already in a pointer register
8027        then don't need anything more */
8028     if (!AOP_INPREG(AOP(left))) {
8029         /* otherwise get a free pointer register */
8030     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8031 /*
8032         aop = newAsmop(0);
8033         preg = getFreePtr(ic,&aop,FALSE);
8034         pic14_emitcode("mov","%s,%s",
8035                 preg->name,
8036                 aopGet(AOP(left),0,FALSE,TRUE));
8037         rname = preg->name ;
8038 */
8039     rname ="BAD";
8040     } else
8041         rname = aopGet(AOP(left),0,FALSE,FALSE);
8042     
8043     aopOp (result,ic,FALSE);
8044     
8045       /* if bitfield then unpack the bits */
8046     if (IS_BITVAR(retype)) 
8047         genUnpackBits (result,rname,POINTER);
8048     else {
8049         /* we have can just get the values */
8050       int size = AOP_SIZE(result);
8051       int offset = 0 ;  
8052         
8053       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8054
8055       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8056       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8057       while(size--) {
8058         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8059         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8060         if(size)
8061           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8062       }
8063 /*
8064         while (size--) {
8065             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8066
8067                 pic14_emitcode("mov","a,@%s",rname);
8068                 aopPut(AOP(result),"a",offset);
8069             } else {
8070                 sprintf(buffer,"@%s",rname);
8071                 aopPut(AOP(result),buffer,offset);
8072             }
8073             offset++ ;
8074             if (size)
8075                 pic14_emitcode("inc","%s",rname);
8076         }
8077 */
8078     }
8079
8080     /* now some housekeeping stuff */
8081     if (aop) {
8082         /* we had to allocate for this iCode */
8083     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8084         freeAsmop(NULL,aop,ic,TRUE);
8085     } else { 
8086         /* we did not allocate which means left
8087            already in a pointer register, then
8088            if size > 0 && this could be used again
8089            we have to point it back to where it 
8090            belongs */
8091     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8092         if (AOP_SIZE(result) > 1 &&
8093             !OP_SYMBOL(left)->remat &&
8094             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8095               ic->depth )) {
8096             int size = AOP_SIZE(result) - 1;
8097             while (size--)
8098                 pic14_emitcode("dec","%s",rname);
8099         }
8100     }
8101
8102     /* done */
8103     freeAsmop(left,NULL,ic,TRUE);
8104     freeAsmop(result,NULL,ic,TRUE);
8105      
8106 }
8107
8108 /*-----------------------------------------------------------------*/
8109 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8110 /*-----------------------------------------------------------------*/
8111 static void genPagedPointerGet (operand *left, 
8112                                operand *result, 
8113                                iCode *ic)
8114 {
8115     asmop *aop = NULL;
8116     regs *preg = NULL ;
8117     char *rname ;
8118     sym_link *rtype, *retype;    
8119
8120     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8121
8122     rtype = operandType(result);
8123     retype= getSpec(rtype);
8124     
8125     aopOp(left,ic,FALSE);
8126
8127   /* if the value is already in a pointer register
8128        then don't need anything more */
8129     if (!AOP_INPREG(AOP(left))) {
8130         /* otherwise get a free pointer register */
8131         aop = newAsmop(0);
8132         preg = getFreePtr(ic,&aop,FALSE);
8133         pic14_emitcode("mov","%s,%s",
8134                 preg->name,
8135                 aopGet(AOP(left),0,FALSE,TRUE));
8136         rname = preg->name ;
8137     } else
8138         rname = aopGet(AOP(left),0,FALSE,FALSE);
8139     
8140     freeAsmop(left,NULL,ic,TRUE);
8141     aopOp (result,ic,FALSE);
8142
8143     /* if bitfield then unpack the bits */
8144     if (IS_BITVAR(retype)) 
8145         genUnpackBits (result,rname,PPOINTER);
8146     else {
8147         /* we have can just get the values */
8148         int size = AOP_SIZE(result);
8149         int offset = 0 ;        
8150         
8151         while (size--) {
8152             
8153             pic14_emitcode("movx","a,@%s",rname);
8154             aopPut(AOP(result),"a",offset);
8155             
8156             offset++ ;
8157             
8158             if (size)
8159                 pic14_emitcode("inc","%s",rname);
8160         }
8161     }
8162
8163     /* now some housekeeping stuff */
8164     if (aop) {
8165         /* we had to allocate for this iCode */
8166         freeAsmop(NULL,aop,ic,TRUE);
8167     } else { 
8168         /* we did not allocate which means left
8169            already in a pointer register, then
8170            if size > 0 && this could be used again
8171            we have to point it back to where it 
8172            belongs */
8173         if (AOP_SIZE(result) > 1 &&
8174             !OP_SYMBOL(left)->remat &&
8175             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8176               ic->depth )) {
8177             int size = AOP_SIZE(result) - 1;
8178             while (size--)
8179                 pic14_emitcode("dec","%s",rname);
8180         }
8181     }
8182
8183     /* done */
8184     freeAsmop(result,NULL,ic,TRUE);
8185     
8186         
8187 }
8188
8189 /*-----------------------------------------------------------------*/
8190 /* genFarPointerGet - gget value from far space                    */
8191 /*-----------------------------------------------------------------*/
8192 static void genFarPointerGet (operand *left,
8193                               operand *result, iCode *ic)
8194 {
8195     int size, offset ;
8196     sym_link *retype = getSpec(operandType(result));
8197
8198     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8199
8200     aopOp(left,ic,FALSE);
8201
8202     /* if the operand is already in dptr 
8203     then we do nothing else we move the value to dptr */
8204     if (AOP_TYPE(left) != AOP_STR) {
8205         /* if this is remateriazable */
8206         if (AOP_TYPE(left) == AOP_IMMD)
8207             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8208         else { /* we need to get it byte by byte */
8209             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8210             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8211             if (options.model == MODEL_FLAT24)
8212             {
8213                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8214             }
8215         }
8216     }
8217     /* so dptr know contains the address */
8218     freeAsmop(left,NULL,ic,TRUE);
8219     aopOp(result,ic,FALSE);
8220
8221     /* if bit then unpack */
8222     if (IS_BITVAR(retype)) 
8223         genUnpackBits(result,"dptr",FPOINTER);
8224     else {
8225         size = AOP_SIZE(result);
8226         offset = 0 ;
8227
8228         while (size--) {
8229             pic14_emitcode("movx","a,@dptr");
8230             aopPut(AOP(result),"a",offset++);
8231             if (size)
8232                 pic14_emitcode("inc","dptr");
8233         }
8234     }
8235
8236     freeAsmop(result,NULL,ic,TRUE);
8237 }
8238 #if 0
8239 /*-----------------------------------------------------------------*/
8240 /* genCodePointerGet - get value from code space                  */
8241 /*-----------------------------------------------------------------*/
8242 static void genCodePointerGet (operand *left,
8243                                 operand *result, iCode *ic)
8244 {
8245     int size, offset ;
8246     sym_link *retype = getSpec(operandType(result));
8247
8248     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8249
8250     aopOp(left,ic,FALSE);
8251
8252     /* if the operand is already in dptr 
8253     then we do nothing else we move the value to dptr */
8254     if (AOP_TYPE(left) != AOP_STR) {
8255         /* if this is remateriazable */
8256         if (AOP_TYPE(left) == AOP_IMMD)
8257             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8258         else { /* we need to get it byte by byte */
8259             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8260             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8261             if (options.model == MODEL_FLAT24)
8262             {
8263                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8264             }
8265         }
8266     }
8267     /* so dptr know contains the address */
8268     freeAsmop(left,NULL,ic,TRUE);
8269     aopOp(result,ic,FALSE);
8270
8271     /* if bit then unpack */
8272     if (IS_BITVAR(retype)) 
8273         genUnpackBits(result,"dptr",CPOINTER);
8274     else {
8275         size = AOP_SIZE(result);
8276         offset = 0 ;
8277
8278         while (size--) {
8279             pic14_emitcode("clr","a");
8280             pic14_emitcode("movc","a,@a+dptr");
8281             aopPut(AOP(result),"a",offset++);
8282             if (size)
8283                 pic14_emitcode("inc","dptr");
8284         }
8285     }
8286
8287     freeAsmop(result,NULL,ic,TRUE);
8288 }
8289 #endif
8290 /*-----------------------------------------------------------------*/
8291 /* genGenPointerGet - gget value from generic pointer space        */
8292 /*-----------------------------------------------------------------*/
8293 static void genGenPointerGet (operand *left,
8294                               operand *result, iCode *ic)
8295 {
8296   int size, offset ;
8297   sym_link *retype = getSpec(operandType(result));
8298
8299   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8300   aopOp(left,ic,FALSE);
8301   aopOp(result,ic,FALSE);
8302
8303
8304   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8305
8306   /* if the operand is already in dptr 
8307      then we do nothing else we move the value to dptr */
8308   //  if (AOP_TYPE(left) != AOP_STR) {
8309     /* if this is remateriazable */
8310     if (AOP_TYPE(left) == AOP_IMMD) {
8311       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8312       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8313     }
8314     else { /* we need to get it byte by byte */
8315
8316       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8317       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8318
8319       size = AOP_SIZE(result);
8320       offset = 0 ;
8321
8322       while(size--) {
8323         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8324         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8325         if(size)
8326           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8327       }
8328       goto release;
8329     }
8330     //}
8331   /* so dptr know contains the address */
8332
8333   /* if bit then unpack */
8334   //if (IS_BITVAR(retype)) 
8335   //  genUnpackBits(result,"dptr",GPOINTER);
8336
8337  release:
8338   freeAsmop(left,NULL,ic,TRUE);
8339   freeAsmop(result,NULL,ic,TRUE);
8340
8341 }
8342
8343 /*-----------------------------------------------------------------*/
8344 /* genConstPointerGet - get value from const generic pointer space */
8345 /*-----------------------------------------------------------------*/
8346 static void genConstPointerGet (operand *left,
8347                                 operand *result, iCode *ic)
8348 {
8349   //sym_link *retype = getSpec(operandType(result));
8350   symbol *albl = newiTempLabel(NULL);
8351   symbol *blbl = newiTempLabel(NULL);
8352   PIC_OPCODE poc;
8353
8354   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8355   aopOp(left,ic,FALSE);
8356   aopOp(result,ic,FALSE);
8357
8358
8359   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8360
8361   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8362
8363   emitpcode(POC_CALL,popGetLabel(albl->key));
8364   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8365   emitpLabel(albl->key);
8366
8367   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8368     
8369   emitpcode(poc,popGet(AOP(left),1));
8370   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8371   emitpcode(poc,popGet(AOP(left),0));
8372   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8373
8374   emitpLabel(blbl->key);
8375
8376   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8377
8378
8379   freeAsmop(left,NULL,ic,TRUE);
8380   freeAsmop(result,NULL,ic,TRUE);
8381
8382 }
8383 /*-----------------------------------------------------------------*/
8384 /* genPointerGet - generate code for pointer get                   */
8385 /*-----------------------------------------------------------------*/
8386 static void genPointerGet (iCode *ic)
8387 {
8388     operand *left, *result ;
8389     sym_link *type, *etype;
8390     int p_type;
8391
8392     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8393
8394     left = IC_LEFT(ic);
8395     result = IC_RESULT(ic) ;
8396
8397     /* depending on the type of pointer we need to
8398     move it to the correct pointer register */
8399     type = operandType(left);
8400     etype = getSpec(type);
8401
8402     if (IS_PTR_CONST(type))
8403       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8404
8405     /* if left is of type of pointer then it is simple */
8406     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8407         p_type = DCL_TYPE(type);
8408     else {
8409         /* we have to go by the storage class */
8410         p_type = PTR_TYPE(SPEC_OCLS(etype));
8411
8412         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8413
8414         if (SPEC_OCLS(etype)->codesp ) {
8415           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8416           //p_type = CPOINTER ; 
8417         }
8418         else
8419             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8420               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8421                /*p_type = FPOINTER ;*/ 
8422             else
8423                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8424                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8425 /*                  p_type = PPOINTER; */
8426                 else
8427                     if (SPEC_OCLS(etype) == idata )
8428                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8429 /*                      p_type = IPOINTER; */
8430                     else
8431                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8432 /*                      p_type = POINTER ; */
8433     }
8434
8435     /* now that we have the pointer type we assign
8436     the pointer values */
8437     switch (p_type) {
8438
8439     case POINTER:       
8440     case IPOINTER:
8441         genNearPointerGet (left,result,ic);
8442         break;
8443
8444     case PPOINTER:
8445         genPagedPointerGet(left,result,ic);
8446         break;
8447
8448     case FPOINTER:
8449         genFarPointerGet (left,result,ic);
8450         break;
8451
8452     case CPOINTER:
8453         genConstPointerGet (left,result,ic);
8454         //pic14_emitcodePointerGet (left,result,ic);
8455         break;
8456
8457     case GPOINTER:
8458       if (IS_PTR_CONST(type))
8459         genConstPointerGet (left,result,ic);
8460       else
8461         genGenPointerGet (left,result,ic);
8462       break;
8463     }
8464
8465 }
8466
8467 /*-----------------------------------------------------------------*/
8468 /* genPackBits - generates code for packed bit storage             */
8469 /*-----------------------------------------------------------------*/
8470 static void genPackBits (sym_link    *etype ,
8471                          operand *right ,
8472                          char *rname, int p_type)
8473 {
8474     int shCount = 0 ;
8475     int offset = 0  ;
8476     int rLen = 0 ;
8477     int blen, bstr ;   
8478     char *l ;
8479
8480     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8481     blen = SPEC_BLEN(etype);
8482     bstr = SPEC_BSTR(etype);
8483
8484     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8485     MOVA(l);   
8486
8487     /* if the bit lenth is less than or    */
8488     /* it exactly fits a byte then         */
8489     if (SPEC_BLEN(etype) <= 8 )  {
8490         shCount = SPEC_BSTR(etype) ;
8491
8492         /* shift left acc */
8493         AccLsh(shCount);
8494
8495         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8496
8497
8498             switch (p_type) {
8499                 case POINTER:
8500                     pic14_emitcode ("mov","b,a");
8501                     pic14_emitcode("mov","a,@%s",rname);
8502                     break;
8503
8504                 case FPOINTER:
8505                     pic14_emitcode ("mov","b,a");
8506                     pic14_emitcode("movx","a,@dptr");
8507                     break;
8508
8509                 case GPOINTER:
8510                     pic14_emitcode ("push","b");
8511                     pic14_emitcode ("push","acc");
8512                     pic14_emitcode ("lcall","__gptrget");
8513                     pic14_emitcode ("pop","b");
8514                     break;
8515             }
8516
8517             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8518                       ((unsigned char)(0xFF << (blen+bstr)) | 
8519                        (unsigned char)(0xFF >> (8-bstr)) ) );
8520             pic14_emitcode ("orl","a,b");
8521             if (p_type == GPOINTER)
8522                 pic14_emitcode("pop","b");
8523         }
8524     }
8525
8526     switch (p_type) {
8527         case POINTER:
8528             pic14_emitcode("mov","@%s,a",rname);
8529             break;
8530
8531         case FPOINTER:
8532             pic14_emitcode("movx","@dptr,a");
8533             break;
8534
8535         case GPOINTER:
8536             DEBUGpic14_emitcode(";lcall","__gptrput");
8537             break;
8538     }
8539
8540     /* if we r done */
8541     if ( SPEC_BLEN(etype) <= 8 )
8542         return ;
8543
8544     pic14_emitcode("inc","%s",rname);
8545     rLen = SPEC_BLEN(etype) ;     
8546
8547     /* now generate for lengths greater than one byte */
8548     while (1) {
8549
8550         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8551
8552         rLen -= 8 ;
8553         if (rLen <= 0 )
8554             break ;
8555
8556         switch (p_type) {
8557             case POINTER:
8558                 if (*l == '@') {
8559                     MOVA(l);
8560                     pic14_emitcode("mov","@%s,a",rname);
8561                 } else
8562                     pic14_emitcode("mov","@%s,%s",rname,l);
8563                 break;
8564
8565             case FPOINTER:
8566                 MOVA(l);
8567                 pic14_emitcode("movx","@dptr,a");
8568                 break;
8569
8570             case GPOINTER:
8571                 MOVA(l);
8572                 DEBUGpic14_emitcode(";lcall","__gptrput");
8573                 break;  
8574         }   
8575         pic14_emitcode ("inc","%s",rname);
8576     }
8577
8578     MOVA(l);
8579
8580     /* last last was not complete */
8581     if (rLen)   {
8582         /* save the byte & read byte */
8583         switch (p_type) {
8584             case POINTER:
8585                 pic14_emitcode ("mov","b,a");
8586                 pic14_emitcode("mov","a,@%s",rname);
8587                 break;
8588
8589             case FPOINTER:
8590                 pic14_emitcode ("mov","b,a");
8591                 pic14_emitcode("movx","a,@dptr");
8592                 break;
8593
8594             case GPOINTER:
8595                 pic14_emitcode ("push","b");
8596                 pic14_emitcode ("push","acc");
8597                 pic14_emitcode ("lcall","__gptrget");
8598                 pic14_emitcode ("pop","b");
8599                 break;
8600         }
8601
8602         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8603         pic14_emitcode ("orl","a,b");
8604     }
8605
8606     if (p_type == GPOINTER)
8607         pic14_emitcode("pop","b");
8608
8609     switch (p_type) {
8610
8611     case POINTER:
8612         pic14_emitcode("mov","@%s,a",rname);
8613         break;
8614         
8615     case FPOINTER:
8616         pic14_emitcode("movx","@dptr,a");
8617         break;
8618         
8619     case GPOINTER:
8620         DEBUGpic14_emitcode(";lcall","__gptrput");
8621         break;                  
8622     }
8623 }
8624 /*-----------------------------------------------------------------*/
8625 /* genDataPointerSet - remat pointer to data space                 */
8626 /*-----------------------------------------------------------------*/
8627 static void genDataPointerSet(operand *right,
8628                               operand *result,
8629                               iCode *ic)
8630 {
8631     int size, offset = 0 ;
8632     char *l, buffer[256];
8633
8634     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8635     aopOp(right,ic,FALSE);
8636     
8637     l = aopGet(AOP(result),0,FALSE,TRUE);
8638     size = AOP_SIZE(right);
8639 /*
8640     if ( AOP_TYPE(result) == AOP_PCODE) {
8641       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8642               AOP(result)->aopu.pcop->name,
8643               PCOI(AOP(result)->aopu.pcop)->offset);
8644     }
8645 */
8646
8647     // tsd, was l+1 - the underline `_' prefix was being stripped
8648     while (size--) {
8649       if (offset) {
8650         sprintf(buffer,"(%s + %d)",l,offset);
8651         fprintf(stderr,"oops  %s\n",buffer);
8652       } else
8653         sprintf(buffer,"%s",l);
8654
8655         if (AOP_TYPE(right) == AOP_LIT) {
8656           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8657           lit = lit >> (8*offset);
8658           if(lit&0xff) {
8659             pic14_emitcode("movlw","%d",lit);
8660             pic14_emitcode("movwf","%s",buffer);
8661
8662             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8663             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8664             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8665
8666           } else {
8667             pic14_emitcode("clrf","%s",buffer);
8668             //emitpcode(POC_CLRF, popRegFromString(buffer));
8669             emitpcode(POC_CLRF, popGet(AOP(result),0));
8670           }
8671         }else {
8672           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8673           pic14_emitcode("movwf","%s",buffer);
8674
8675           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8676           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8677           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8678
8679         }
8680
8681         offset++;
8682     }
8683
8684     freeAsmop(right,NULL,ic,TRUE);
8685     freeAsmop(result,NULL,ic,TRUE);
8686 }
8687
8688 /*-----------------------------------------------------------------*/
8689 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8690 /*-----------------------------------------------------------------*/
8691 static void genNearPointerSet (operand *right,
8692                                operand *result, 
8693                                iCode *ic)
8694 {
8695   asmop *aop = NULL;
8696   char *l;
8697   sym_link *retype;
8698   sym_link *ptype = operandType(result);
8699
8700     
8701   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8702   retype= getSpec(operandType(right));
8703
8704   aopOp(result,ic,FALSE);
8705
8706     
8707   /* if the result is rematerializable &
8708      in data space & not a bit variable */
8709   //if (AOP_TYPE(result) == AOP_IMMD &&
8710   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8711       DCL_TYPE(ptype) == POINTER   &&
8712       !IS_BITVAR(retype)) {
8713     genDataPointerSet (right,result,ic);
8714     freeAsmop(result,NULL,ic,TRUE);
8715     return;
8716   }
8717
8718   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8719   aopOp(right,ic,FALSE);
8720   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8721
8722   /* if the value is already in a pointer register
8723      then don't need anything more */
8724   if (!AOP_INPREG(AOP(result))) {
8725     /* otherwise get a free pointer register */
8726     //aop = newAsmop(0);
8727     //preg = getFreePtr(ic,&aop,FALSE);
8728     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8729     //pic14_emitcode("mov","%s,%s",
8730     //         preg->name,
8731     //         aopGet(AOP(result),0,FALSE,TRUE));
8732     //rname = preg->name ;
8733     //pic14_emitcode("movwf","fsr");
8734     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8735     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8736     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8737     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8738     goto release;
8739
8740   }// else
8741   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8742
8743
8744   /* if bitfield then unpack the bits */
8745   if (IS_BITVAR(retype)) {
8746     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8747            "The programmer is obviously confused");
8748     //genPackBits (retype,right,rname,POINTER);
8749     exit(1);
8750   }
8751   else {
8752     /* we have can just get the values */
8753     int size = AOP_SIZE(right);
8754     int offset = 0 ;    
8755
8756     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8757     while (size--) {
8758       l = aopGet(AOP(right),offset,FALSE,TRUE);
8759       if (*l == '@' ) {
8760         //MOVA(l);
8761         //pic14_emitcode("mov","@%s,a",rname);
8762         pic14_emitcode("movf","indf,w ;1");
8763       } else {
8764
8765         if (AOP_TYPE(right) == AOP_LIT) {
8766           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8767           if(lit) {
8768             pic14_emitcode("movlw","%s",l);
8769             pic14_emitcode("movwf","indf ;2");
8770           } else 
8771             pic14_emitcode("clrf","indf");
8772         }else {
8773           pic14_emitcode("movf","%s,w",l);
8774           pic14_emitcode("movwf","indf ;2");
8775         }
8776         //pic14_emitcode("mov","@%s,%s",rname,l);
8777       }
8778       if (size)
8779         pic14_emitcode("incf","fsr,f ;3");
8780       //pic14_emitcode("inc","%s",rname);
8781       offset++;
8782     }
8783   }
8784
8785   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8786   /* now some housekeeping stuff */
8787   if (aop) {
8788     /* we had to allocate for this iCode */
8789     freeAsmop(NULL,aop,ic,TRUE);
8790   } else { 
8791     /* we did not allocate which means left
8792        already in a pointer register, then
8793        if size > 0 && this could be used again
8794        we have to point it back to where it 
8795        belongs */
8796     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8797     if (AOP_SIZE(right) > 1 &&
8798         !OP_SYMBOL(result)->remat &&
8799         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8800           ic->depth )) {
8801       int size = AOP_SIZE(right) - 1;
8802       while (size--)
8803         pic14_emitcode("decf","fsr,f");
8804       //pic14_emitcode("dec","%s",rname);
8805     }
8806   }
8807
8808   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8809   /* done */
8810  release:
8811   freeAsmop(right,NULL,ic,TRUE);
8812   freeAsmop(result,NULL,ic,TRUE);
8813 }
8814
8815 /*-----------------------------------------------------------------*/
8816 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8817 /*-----------------------------------------------------------------*/
8818 static void genPagedPointerSet (operand *right,
8819                                operand *result, 
8820                                iCode *ic)
8821 {
8822     asmop *aop = NULL;
8823     regs *preg = NULL ;
8824     char *rname , *l;
8825     sym_link *retype;
8826        
8827     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8828
8829     retype= getSpec(operandType(right));
8830     
8831     aopOp(result,ic,FALSE);
8832     
8833     /* if the value is already in a pointer register
8834        then don't need anything more */
8835     if (!AOP_INPREG(AOP(result))) {
8836         /* otherwise get a free pointer register */
8837         aop = newAsmop(0);
8838         preg = getFreePtr(ic,&aop,FALSE);
8839         pic14_emitcode("mov","%s,%s",
8840                 preg->name,
8841                 aopGet(AOP(result),0,FALSE,TRUE));
8842         rname = preg->name ;
8843     } else
8844         rname = aopGet(AOP(result),0,FALSE,FALSE);
8845     
8846     freeAsmop(result,NULL,ic,TRUE);
8847     aopOp (right,ic,FALSE);
8848
8849     /* if bitfield then unpack the bits */
8850     if (IS_BITVAR(retype)) 
8851         genPackBits (retype,right,rname,PPOINTER);
8852     else {
8853         /* we have can just get the values */
8854         int size = AOP_SIZE(right);
8855         int offset = 0 ;        
8856         
8857         while (size--) {
8858             l = aopGet(AOP(right),offset,FALSE,TRUE);
8859             
8860             MOVA(l);
8861             pic14_emitcode("movx","@%s,a",rname);
8862
8863             if (size)
8864                 pic14_emitcode("inc","%s",rname);
8865
8866             offset++;
8867         }
8868     }
8869     
8870     /* now some housekeeping stuff */
8871     if (aop) {
8872         /* we had to allocate for this iCode */
8873         freeAsmop(NULL,aop,ic,TRUE);
8874     } else { 
8875         /* we did not allocate which means left
8876            already in a pointer register, then
8877            if size > 0 && this could be used again
8878            we have to point it back to where it 
8879            belongs */
8880         if (AOP_SIZE(right) > 1 &&
8881             !OP_SYMBOL(result)->remat &&
8882             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8883               ic->depth )) {
8884             int size = AOP_SIZE(right) - 1;
8885             while (size--)
8886                 pic14_emitcode("dec","%s",rname);
8887         }
8888     }
8889
8890     /* done */
8891     freeAsmop(right,NULL,ic,TRUE);
8892     
8893         
8894 }
8895
8896 /*-----------------------------------------------------------------*/
8897 /* genFarPointerSet - set value from far space                     */
8898 /*-----------------------------------------------------------------*/
8899 static void genFarPointerSet (operand *right,
8900                               operand *result, iCode *ic)
8901 {
8902     int size, offset ;
8903     sym_link *retype = getSpec(operandType(right));
8904
8905     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8906     aopOp(result,ic,FALSE);
8907
8908     /* if the operand is already in dptr 
8909     then we do nothing else we move the value to dptr */
8910     if (AOP_TYPE(result) != AOP_STR) {
8911         /* if this is remateriazable */
8912         if (AOP_TYPE(result) == AOP_IMMD)
8913             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8914         else { /* we need to get it byte by byte */
8915             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8916             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8917             if (options.model == MODEL_FLAT24)
8918             {
8919                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8920             }
8921         }
8922     }
8923     /* so dptr know contains the address */
8924     freeAsmop(result,NULL,ic,TRUE);
8925     aopOp(right,ic,FALSE);
8926
8927     /* if bit then unpack */
8928     if (IS_BITVAR(retype)) 
8929         genPackBits(retype,right,"dptr",FPOINTER);
8930     else {
8931         size = AOP_SIZE(right);
8932         offset = 0 ;
8933
8934         while (size--) {
8935             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8936             MOVA(l);
8937             pic14_emitcode("movx","@dptr,a");
8938             if (size)
8939                 pic14_emitcode("inc","dptr");
8940         }
8941     }
8942
8943     freeAsmop(right,NULL,ic,TRUE);
8944 }
8945
8946 /*-----------------------------------------------------------------*/
8947 /* genGenPointerSet - set value from generic pointer space         */
8948 /*-----------------------------------------------------------------*/
8949 static void genGenPointerSet (operand *right,
8950                               operand *result, iCode *ic)
8951 {
8952   int size, offset ;
8953   sym_link *retype = getSpec(operandType(right));
8954
8955   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8956
8957   aopOp(result,ic,FALSE);
8958   aopOp(right,ic,FALSE);
8959   size = AOP_SIZE(right);
8960
8961   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8962
8963   /* if the operand is already in dptr 
8964      then we do nothing else we move the value to dptr */
8965   if (AOP_TYPE(result) != AOP_STR) {
8966     /* if this is remateriazable */
8967     if (AOP_TYPE(result) == AOP_IMMD) {
8968       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8969       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8970     }
8971     else { /* we need to get it byte by byte */
8972       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8973       size = AOP_SIZE(right);
8974       offset = 0 ;
8975
8976       /* hack hack! see if this the FSR. If so don't load W */
8977       if(AOP_TYPE(right) != AOP_ACC) {
8978
8979
8980         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8981         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8982
8983         if(AOP_SIZE(result) > 1) {
8984           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8985           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8986           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8987
8988         }
8989
8990         //if(size==2)
8991         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8992         //if(size==4) {
8993         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8994         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8995         //}
8996
8997         while(size--) {
8998           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8999           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9000           
9001           if(size)
9002             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9003         }
9004
9005
9006         goto release;
9007       } 
9008
9009       if(aopIdx(AOP(result),0) != 4) {
9010
9011         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9012         goto release;
9013       }
9014
9015       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9016       goto release;
9017
9018     }
9019   }
9020   /* so dptr know contains the address */
9021
9022
9023   /* if bit then unpack */
9024   if (IS_BITVAR(retype)) 
9025     genPackBits(retype,right,"dptr",GPOINTER);
9026   else {
9027     size = AOP_SIZE(right);
9028     offset = 0 ;
9029
9030   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9031
9032     while (size--) {
9033
9034       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9035       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9036
9037       if (AOP_TYPE(right) == AOP_LIT) 
9038         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9039       else
9040         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9041
9042       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9043
9044       offset++;
9045     }
9046   }
9047
9048  release:
9049   freeAsmop(right,NULL,ic,TRUE);
9050   freeAsmop(result,NULL,ic,TRUE);
9051 }
9052
9053 /*-----------------------------------------------------------------*/
9054 /* genPointerSet - stores the value into a pointer location        */
9055 /*-----------------------------------------------------------------*/
9056 static void genPointerSet (iCode *ic)
9057 {    
9058     operand *right, *result ;
9059     sym_link *type, *etype;
9060     int p_type;
9061
9062     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9063
9064     right = IC_RIGHT(ic);
9065     result = IC_RESULT(ic) ;
9066
9067     /* depending on the type of pointer we need to
9068     move it to the correct pointer register */
9069     type = operandType(result);
9070     etype = getSpec(type);
9071     /* if left is of type of pointer then it is simple */
9072     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9073         p_type = DCL_TYPE(type);
9074     }
9075     else {
9076         /* we have to go by the storage class */
9077         p_type = PTR_TYPE(SPEC_OCLS(etype));
9078
9079 /*      if (SPEC_OCLS(etype)->codesp ) { */
9080 /*          p_type = CPOINTER ;  */
9081 /*      } */
9082 /*      else */
9083 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9084 /*              p_type = FPOINTER ; */
9085 /*          else */
9086 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9087 /*                  p_type = PPOINTER ; */
9088 /*              else */
9089 /*                  if (SPEC_OCLS(etype) == idata ) */
9090 /*                      p_type = IPOINTER ; */
9091 /*                  else */
9092 /*                      p_type = POINTER ; */
9093     }
9094
9095     /* now that we have the pointer type we assign
9096     the pointer values */
9097     switch (p_type) {
9098
9099     case POINTER:
9100     case IPOINTER:
9101         genNearPointerSet (right,result,ic);
9102         break;
9103
9104     case PPOINTER:
9105         genPagedPointerSet (right,result,ic);
9106         break;
9107
9108     case FPOINTER:
9109         genFarPointerSet (right,result,ic);
9110         break;
9111
9112     case GPOINTER:
9113         genGenPointerSet (right,result,ic);
9114         break;
9115
9116     default:
9117       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9118               "genPointerSet: illegal pointer type");
9119     }
9120 }
9121
9122 /*-----------------------------------------------------------------*/
9123 /* genIfx - generate code for Ifx statement                        */
9124 /*-----------------------------------------------------------------*/
9125 static void genIfx (iCode *ic, iCode *popIc)
9126 {
9127   operand *cond = IC_COND(ic);
9128   int isbit =0;
9129
9130   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9131
9132   aopOp(cond,ic,FALSE);
9133
9134   /* get the value into acc */
9135   if (AOP_TYPE(cond) != AOP_CRY)
9136     pic14_toBoolean(cond);
9137   else
9138     isbit = 1;
9139   /* the result is now in the accumulator */
9140   freeAsmop(cond,NULL,ic,TRUE);
9141
9142   /* if there was something to be popped then do it */
9143   if (popIc)
9144     genIpop(popIc);
9145
9146   /* if the condition is  a bit variable */
9147   if (isbit && IS_ITEMP(cond) && 
9148       SPIL_LOC(cond)) {
9149     genIfxJump(ic,SPIL_LOC(cond)->rname);
9150     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9151   }
9152   else {
9153     if (isbit && !IS_ITEMP(cond))
9154       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9155     else
9156       genIfxJump(ic,"a");
9157   }
9158   ic->generated = 1;
9159
9160 }
9161
9162 /*-----------------------------------------------------------------*/
9163 /* genAddrOf - generates code for address of                       */
9164 /*-----------------------------------------------------------------*/
9165 static void genAddrOf (iCode *ic)
9166 {
9167   operand *right, *result, *left;
9168   int size, offset ;
9169
9170   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9171
9172
9173   //aopOp(IC_RESULT(ic),ic,FALSE);
9174
9175   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9176   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9177   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9178
9179   DEBUGpic14_AopType(__LINE__,left,right,result);
9180
9181   size = AOP_SIZE(IC_RESULT(ic));
9182   offset = 0;
9183
9184   while (size--) {
9185     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9186     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9187     offset++;
9188   }
9189
9190   freeAsmop(left,NULL,ic,FALSE);
9191   freeAsmop(result,NULL,ic,TRUE);
9192
9193 }
9194
9195 #if 0
9196 /*-----------------------------------------------------------------*/
9197 /* genFarFarAssign - assignment when both are in far space         */
9198 /*-----------------------------------------------------------------*/
9199 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9200 {
9201     int size = AOP_SIZE(right);
9202     int offset = 0;
9203     char *l ;
9204     /* first push the right side on to the stack */
9205     while (size--) {
9206         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9207         MOVA(l);
9208         pic14_emitcode ("push","acc");
9209     }
9210     
9211     freeAsmop(right,NULL,ic,FALSE);
9212     /* now assign DPTR to result */
9213     aopOp(result,ic,FALSE);
9214     size = AOP_SIZE(result);
9215     while (size--) {
9216         pic14_emitcode ("pop","acc");
9217         aopPut(AOP(result),"a",--offset);
9218     }
9219     freeAsmop(result,NULL,ic,FALSE);
9220         
9221 }
9222 #endif
9223
9224 /*-----------------------------------------------------------------*/
9225 /* genAssign - generate code for assignment                        */
9226 /*-----------------------------------------------------------------*/
9227 static void genAssign (iCode *ic)
9228 {
9229   operand *result, *right;
9230   int size, offset,know_W;
9231   unsigned long lit = 0L;
9232
9233   result = IC_RESULT(ic);
9234   right  = IC_RIGHT(ic) ;
9235
9236   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9237
9238   /* if they are the same */
9239   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9240     return ;
9241
9242   aopOp(right,ic,FALSE);
9243   aopOp(result,ic,TRUE);
9244
9245   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9246
9247   /* if they are the same registers */
9248   if (pic14_sameRegs(AOP(right),AOP(result)))
9249     goto release;
9250
9251   /* if the result is a bit */
9252   if (AOP_TYPE(result) == AOP_CRY) {
9253
9254     /* if the right size is a literal then
9255        we know what the value is */
9256     if (AOP_TYPE(right) == AOP_LIT) {
9257           
9258       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9259                   popGet(AOP(result),0));
9260
9261       if (((int) operandLitValue(right))) 
9262         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9263                        AOP(result)->aopu.aop_dir,
9264                        AOP(result)->aopu.aop_dir);
9265       else
9266         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9267                        AOP(result)->aopu.aop_dir,
9268                        AOP(result)->aopu.aop_dir);
9269       goto release;
9270     }
9271
9272     /* the right is also a bit variable */
9273     if (AOP_TYPE(right) == AOP_CRY) {
9274       emitpcode(POC_BCF,    popGet(AOP(result),0));
9275       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9276       emitpcode(POC_BSF,    popGet(AOP(result),0));
9277
9278       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9279                      AOP(result)->aopu.aop_dir,
9280                      AOP(result)->aopu.aop_dir);
9281       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9282                      AOP(right)->aopu.aop_dir,
9283                      AOP(right)->aopu.aop_dir);
9284       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9285                      AOP(result)->aopu.aop_dir,
9286                      AOP(result)->aopu.aop_dir);
9287       goto release ;
9288     }
9289
9290     /* we need to or */
9291     emitpcode(POC_BCF,    popGet(AOP(result),0));
9292     pic14_toBoolean(right);
9293     emitSKPZ;
9294     emitpcode(POC_BSF,    popGet(AOP(result),0));
9295     //aopPut(AOP(result),"a",0);
9296     goto release ;
9297   }
9298
9299   /* bit variables done */
9300   /* general case */
9301   size = AOP_SIZE(result);
9302   offset = 0 ;
9303   if(AOP_TYPE(right) == AOP_LIT)
9304     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9305
9306   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9307   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9308     if(aopIdx(AOP(result),0) == 4) {
9309   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9310       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9311       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9312       goto release;
9313     } else
9314       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9315   }
9316
9317   know_W=-1;
9318   while (size--) {
9319   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9320     if(AOP_TYPE(right) == AOP_LIT) {
9321       if(lit&0xff) {
9322         if(know_W != (lit&0xff))
9323           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9324         know_W = lit&0xff;
9325         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9326       } else
9327         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9328
9329       lit >>= 8;
9330
9331     } else if (AOP_TYPE(right) == AOP_CRY) {
9332       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9333       if(offset == 0) {
9334         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9335         emitpcode(POC_INCF, popGet(AOP(result),0));
9336       }
9337     } else {
9338   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9339       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9340       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9341     }
9342             
9343     offset++;
9344   }
9345
9346     
9347  release:
9348   freeAsmop (right,NULL,ic,FALSE);
9349   freeAsmop (result,NULL,ic,TRUE);
9350 }   
9351
9352 /*-----------------------------------------------------------------*/
9353 /* genJumpTab - genrates code for jump table                       */
9354 /*-----------------------------------------------------------------*/
9355 static void genJumpTab (iCode *ic)
9356 {
9357     symbol *jtab;
9358     char *l;
9359
9360     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9361
9362     aopOp(IC_JTCOND(ic),ic,FALSE);
9363     /* get the condition into accumulator */
9364     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9365     MOVA(l);
9366     /* multiply by three */
9367     pic14_emitcode("add","a,acc");
9368     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9369
9370     jtab = newiTempLabel(NULL);
9371     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9372     pic14_emitcode("jmp","@a+dptr");
9373     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9374
9375     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9376     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9377     emitSKPNC;
9378     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9379     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9380     emitpLabel(jtab->key);
9381
9382     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9383
9384     /* now generate the jump labels */
9385     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9386          jtab = setNextItem(IC_JTLABELS(ic))) {
9387         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9388         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9389         
9390     }
9391
9392 }
9393
9394 /*-----------------------------------------------------------------*/
9395 /* genMixedOperation - gen code for operators between mixed types  */
9396 /*-----------------------------------------------------------------*/
9397 /*
9398   TSD - Written for the PIC port - but this unfortunately is buggy.
9399   This routine is good in that it is able to efficiently promote 
9400   types to different (larger) sizes. Unfortunately, the temporary
9401   variables that are optimized out by this routine are sometimes
9402   used in other places. So until I know how to really parse the 
9403   iCode tree, I'm going to not be using this routine :(.
9404 */
9405 static int genMixedOperation (iCode *ic)
9406 {
9407 #if 0
9408   operand *result = IC_RESULT(ic);
9409   sym_link *ctype = operandType(IC_LEFT(ic));
9410   operand *right = IC_RIGHT(ic);
9411   int ret = 0;
9412   int big,small;
9413   int offset;
9414
9415   iCode *nextic;
9416   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9417
9418   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9419
9420   nextic = ic->next;
9421   if(!nextic)
9422     return 0;
9423
9424   nextright = IC_RIGHT(nextic);
9425   nextleft  = IC_LEFT(nextic);
9426   nextresult = IC_RESULT(nextic);
9427
9428   aopOp(right,ic,FALSE);
9429   aopOp(result,ic,FALSE);
9430   aopOp(nextright,  nextic, FALSE);
9431   aopOp(nextleft,   nextic, FALSE);
9432   aopOp(nextresult, nextic, FALSE);
9433
9434   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9435
9436     operand *t = right;
9437     right = nextright;
9438     nextright = t; 
9439
9440     pic14_emitcode(";remove right +","");
9441
9442   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9443 /*
9444     operand *t = right;
9445     right = nextleft;
9446     nextleft = t; 
9447 */
9448     pic14_emitcode(";remove left +","");
9449   } else
9450     return 0;
9451
9452   big = AOP_SIZE(nextleft);
9453   small = AOP_SIZE(nextright);
9454
9455   switch(nextic->op) {
9456
9457   case '+':
9458     pic14_emitcode(";optimize a +","");
9459     /* if unsigned or not an integral type */
9460     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9461       pic14_emitcode(";add a bit to something","");
9462     } else {
9463
9464       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9465
9466       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9467         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9468         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9469       } else
9470         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9471
9472       offset = 0;
9473       while(--big) {
9474
9475         offset++;
9476
9477         if(--small) {
9478           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9479             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9480             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9481           }
9482
9483           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9484           emitSKPNC;
9485           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9486                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9487                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9488           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9489           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9490
9491         } else {
9492           pic14_emitcode("rlf","known_zero,w");
9493
9494           /*
9495             if right is signed
9496               btfsc  right,7
9497                addlw ff
9498           */
9499           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9500             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9501             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9502           } else {
9503             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9504           }
9505         }
9506       }
9507       ret = 1;
9508     }
9509   }
9510   ret = 1;
9511
9512 release:
9513   freeAsmop(right,NULL,ic,TRUE);
9514   freeAsmop(result,NULL,ic,TRUE);
9515   freeAsmop(nextright,NULL,ic,TRUE);
9516   freeAsmop(nextleft,NULL,ic,TRUE);
9517   if(ret)
9518     nextic->generated = 1;
9519
9520   return ret;
9521 #else
9522   return 0;
9523 #endif
9524 }
9525 /*-----------------------------------------------------------------*/
9526 /* genCast - gen code for casting                                  */
9527 /*-----------------------------------------------------------------*/
9528 static void genCast (iCode *ic)
9529 {
9530     operand *result = IC_RESULT(ic);
9531     sym_link *ctype = operandType(IC_LEFT(ic));
9532     sym_link *rtype = operandType(IC_RIGHT(ic));
9533     operand *right = IC_RIGHT(ic);
9534     int size, offset ;
9535
9536     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9537     /* if they are equivalent then do nothing */
9538     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9539         return ;
9540
9541     aopOp(right,ic,FALSE) ;
9542     aopOp(result,ic,FALSE);
9543
9544     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9545
9546     /* if the result is a bit */
9547     if (AOP_TYPE(result) == AOP_CRY) {
9548         /* if the right size is a literal then
9549         we know what the value is */
9550       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9551         if (AOP_TYPE(right) == AOP_LIT) {
9552
9553           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9554                       popGet(AOP(result),0));
9555
9556             if (((int) operandLitValue(right))) 
9557               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9558                        AOP(result)->aopu.aop_dir,
9559                        AOP(result)->aopu.aop_dir);
9560             else
9561               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9562                        AOP(result)->aopu.aop_dir,
9563                        AOP(result)->aopu.aop_dir);
9564
9565             goto release;
9566         }
9567
9568         /* the right is also a bit variable */
9569         if (AOP_TYPE(right) == AOP_CRY) {
9570
9571           emitCLRC;
9572           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9573
9574           pic14_emitcode("clrc","");
9575           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9576                    AOP(right)->aopu.aop_dir,
9577                    AOP(right)->aopu.aop_dir);
9578             aopPut(AOP(result),"c",0);
9579             goto release ;
9580         }
9581
9582         /* we need to or */
9583         if (AOP_TYPE(right) == AOP_REG) {
9584           emitpcode(POC_BCF,    popGet(AOP(result),0));
9585           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9586           emitpcode(POC_BSF,    popGet(AOP(result),0));
9587         }
9588         pic14_toBoolean(right);
9589         aopPut(AOP(result),"a",0);
9590         goto release ;
9591     }
9592
9593     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9594       int offset = 1;
9595       size = AOP_SIZE(result);
9596
9597       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9598
9599       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9600       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9601       emitpcode(POC_INCF,   popGet(AOP(result),0));
9602
9603       while (size--)
9604         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9605
9606       goto release;
9607     }
9608
9609     /* if they are the same size : or less */
9610     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9611
9612         /* if they are in the same place */
9613       if (pic14_sameRegs(AOP(right),AOP(result)))
9614         goto release;
9615
9616       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9617       if (IS_PTR_CONST(rtype))
9618         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9619       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9620         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9621
9622       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9623         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9624         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9625         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9626         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9627         if(AOP_SIZE(result) <2)
9628           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9629
9630       } else {
9631
9632         /* if they in different places then copy */
9633         size = AOP_SIZE(result);
9634         offset = 0 ;
9635         while (size--) {
9636           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9637           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9638
9639           //aopPut(AOP(result),
9640           // aopGet(AOP(right),offset,FALSE,FALSE),
9641           // offset);
9642
9643           offset++;
9644         }
9645       }
9646       goto release;
9647     }
9648
9649
9650     /* if the result is of type pointer */
9651     if (IS_PTR(ctype)) {
9652
9653         int p_type;
9654         sym_link *type = operandType(right);
9655         sym_link *etype = getSpec(type);
9656       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9657
9658         /* pointer to generic pointer */
9659         if (IS_GENPTR(ctype)) {
9660             char *l = zero;
9661             
9662             if (IS_PTR(type)) 
9663                 p_type = DCL_TYPE(type);
9664             else {
9665                 /* we have to go by the storage class */
9666                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9667
9668 /*              if (SPEC_OCLS(etype)->codesp )  */
9669 /*                  p_type = CPOINTER ;  */
9670 /*              else */
9671 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9672 /*                      p_type = FPOINTER ; */
9673 /*                  else */
9674 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9675 /*                          p_type = PPOINTER; */
9676 /*                      else */
9677 /*                          if (SPEC_OCLS(etype) == idata ) */
9678 /*                              p_type = IPOINTER ; */
9679 /*                          else */
9680 /*                              p_type = POINTER ; */
9681             }
9682                 
9683             /* the first two bytes are known */
9684       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9685             size = GPTRSIZE - 1; 
9686             offset = 0 ;
9687             while (size--) {
9688               if(offset < AOP_SIZE(right)) {
9689       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9690                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9691                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9692                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9693                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9694                 } else { 
9695                   aopPut(AOP(result),
9696                          aopGet(AOP(right),offset,FALSE,FALSE),
9697                          offset);
9698                 }
9699               } else 
9700                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9701               offset++;
9702             }
9703             /* the last byte depending on type */
9704             switch (p_type) {
9705             case IPOINTER:
9706             case POINTER:
9707                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9708                 break;
9709             case FPOINTER:
9710               pic14_emitcode(";BUG!? ","%d",__LINE__);
9711                 l = one;
9712                 break;
9713             case CPOINTER:
9714               pic14_emitcode(";BUG!? ","%d",__LINE__);
9715                 l = "#0x02";
9716                 break;                          
9717             case PPOINTER:
9718               pic14_emitcode(";BUG!? ","%d",__LINE__);
9719                 l = "#0x03";
9720                 break;
9721                 
9722             default:
9723                 /* this should never happen */
9724                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9725                        "got unknown pointer type");
9726                 exit(1);
9727             }
9728             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9729             goto release ;
9730         }
9731         
9732         /* just copy the pointers */
9733         size = AOP_SIZE(result);
9734         offset = 0 ;
9735         while (size--) {
9736             aopPut(AOP(result),
9737                    aopGet(AOP(right),offset,FALSE,FALSE),
9738                    offset);
9739             offset++;
9740         }
9741         goto release ;
9742     }
9743     
9744
9745
9746     /* so we now know that the size of destination is greater
9747     than the size of the source.
9748     Now, if the next iCode is an operator then we might be
9749     able to optimize the operation without performing a cast.
9750     */
9751     if(genMixedOperation(ic))
9752       goto release;
9753
9754     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9755     
9756     /* we move to result for the size of source */
9757     size = AOP_SIZE(right);
9758     offset = 0 ;
9759     while (size--) {
9760       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9761       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9762       offset++;
9763     }
9764
9765     /* now depending on the sign of the destination */
9766     size = AOP_SIZE(result) - AOP_SIZE(right);
9767     /* if unsigned or not an integral type */
9768     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9769       while (size--)
9770         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9771     } else {
9772       /* we need to extend the sign :{ */
9773
9774       if(size == 1) {
9775         /* Save one instruction of casting char to int */
9776         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9777         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9778         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9779       } else {
9780         emitpcodeNULLop(POC_CLRW);
9781
9782         if(offset)
9783           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9784         else
9785           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9786         
9787         emitpcode(POC_MOVLW,   popGetLit(0xff));
9788
9789         while (size--)
9790           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9791       }
9792     }
9793
9794 release:
9795     freeAsmop(right,NULL,ic,TRUE);
9796     freeAsmop(result,NULL,ic,TRUE);
9797
9798 }
9799
9800 /*-----------------------------------------------------------------*/
9801 /* genDjnz - generate decrement & jump if not zero instrucion      */
9802 /*-----------------------------------------------------------------*/
9803 static int genDjnz (iCode *ic, iCode *ifx)
9804 {
9805     symbol *lbl, *lbl1;
9806     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9807
9808     if (!ifx)
9809         return 0;
9810     
9811     /* if the if condition has a false label
9812        then we cannot save */
9813     if (IC_FALSE(ifx))
9814         return 0;
9815
9816     /* if the minus is not of the form 
9817        a = a - 1 */
9818     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9819         !IS_OP_LITERAL(IC_RIGHT(ic)))
9820         return 0;
9821
9822     if (operandLitValue(IC_RIGHT(ic)) != 1)
9823         return 0;
9824
9825     /* if the size of this greater than one then no
9826        saving */
9827     if (getSize(operandType(IC_RESULT(ic))) > 1)
9828         return 0;
9829
9830     /* otherwise we can save BIG */
9831     lbl = newiTempLabel(NULL);
9832     lbl1= newiTempLabel(NULL);
9833
9834     aopOp(IC_RESULT(ic),ic,FALSE);
9835     
9836     if (IS_AOP_PREG(IC_RESULT(ic))) {
9837         pic14_emitcode("dec","%s",
9838                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9839         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9840         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9841     } else {    
9842
9843
9844       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9845       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9846
9847       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9848       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9849
9850     }
9851 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9852 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9853 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9854 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9855
9856     
9857     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9858     ifx->generated = 1;
9859     return 1;
9860 }
9861
9862 /*-----------------------------------------------------------------*/
9863 /* genReceive - generate code for a receive iCode                  */
9864 /*-----------------------------------------------------------------*/
9865 static void genReceive (iCode *ic)
9866 {    
9867   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9868
9869   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9870       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9871         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9872
9873     int size = getSize(operandType(IC_RESULT(ic)));
9874     int offset =  fReturnSizePic - size;
9875     while (size--) {
9876       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9877                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9878       offset++;
9879     }
9880     aopOp(IC_RESULT(ic),ic,FALSE);  
9881     size = AOP_SIZE(IC_RESULT(ic));
9882     offset = 0;
9883     while (size--) {
9884       pic14_emitcode ("pop","acc");
9885       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9886     }
9887         
9888   } else {
9889     _G.accInUse++;
9890     aopOp(IC_RESULT(ic),ic,FALSE);  
9891     _G.accInUse--;
9892     assignResultValue(IC_RESULT(ic));   
9893   }
9894
9895   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9896 }
9897
9898 /*-----------------------------------------------------------------*/
9899 /* genpic14Code - generate code for pic14 based controllers        */
9900 /*-----------------------------------------------------------------*/
9901 /*
9902  * At this point, ralloc.c has gone through the iCode and attempted
9903  * to optimize in a way suitable for a PIC. Now we've got to generate
9904  * PIC instructions that correspond to the iCode.
9905  *
9906  * Once the instructions are generated, we'll pass through both the
9907  * peep hole optimizer and the pCode optimizer.
9908  *-----------------------------------------------------------------*/
9909
9910 void genpic14Code (iCode *lic)
9911 {
9912     iCode *ic;
9913     int cln = 0;
9914
9915     lineHead = lineCurr = NULL;
9916
9917     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9918     addpBlock(pb);
9919
9920     /* if debug information required */
9921     if (options.debug && currFunc) { 
9922       if (currFunc) {
9923         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9924         _G.debugLine = 1;
9925         if (IS_STATIC(currFunc->etype)) {
9926           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9927           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9928         } else {
9929           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9930           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9931         }
9932         _G.debugLine = 0;
9933       }
9934     }
9935
9936
9937     for (ic = lic ; ic ; ic = ic->next ) {
9938
9939       DEBUGpic14_emitcode(";ic","");
9940         if ( cln != ic->lineno ) {
9941             if ( options.debug ) {
9942                 _G.debugLine = 1;
9943                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9944                          FileBaseName(ic->filename),ic->lineno,
9945                          ic->level,ic->block);
9946                 _G.debugLine = 0;
9947             }
9948             /*
9949               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9950               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9951               printCLine(ic->filename, ic->lineno));
9952             */
9953             addpCode2pBlock(pb,
9954                             newpCodeCSource(ic->lineno, 
9955                                             ic->filename, 
9956                                             printCLine(ic->filename, ic->lineno)));
9957
9958             cln = ic->lineno ;
9959         }
9960         /* if the result is marked as
9961            spilt and rematerializable or code for
9962            this has already been generated then
9963            do nothing */
9964         if (resultRemat(ic) || ic->generated ) 
9965             continue ;
9966         
9967         /* depending on the operation */
9968         switch (ic->op) {
9969         case '!' :
9970             genNot(ic);
9971             break;
9972             
9973         case '~' :
9974             genCpl(ic);
9975             break;
9976             
9977         case UNARYMINUS:
9978             genUminus (ic);
9979             break;
9980             
9981         case IPUSH:
9982             genIpush (ic);
9983             break;
9984             
9985         case IPOP:
9986             /* IPOP happens only when trying to restore a 
9987                spilt live range, if there is an ifx statement
9988                following this pop then the if statement might
9989                be using some of the registers being popped which
9990                would destory the contents of the register so
9991                we need to check for this condition and handle it */
9992             if (ic->next            && 
9993                 ic->next->op == IFX &&
9994                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9995                 genIfx (ic->next,ic);
9996             else
9997                 genIpop (ic);
9998             break; 
9999             
10000         case CALL:
10001             genCall (ic);
10002             break;
10003             
10004         case PCALL:
10005             genPcall (ic);
10006             break;
10007             
10008         case FUNCTION:
10009             genFunction (ic);
10010             break;
10011             
10012         case ENDFUNCTION:
10013             genEndFunction (ic);
10014             break;
10015             
10016         case RETURN:
10017             genRet (ic);
10018             break;
10019             
10020         case LABEL:
10021             genLabel (ic);
10022             break;
10023             
10024         case GOTO:
10025             genGoto (ic);
10026             break;
10027             
10028         case '+' :
10029             genPlus (ic) ;
10030             break;
10031             
10032         case '-' :
10033             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10034                 genMinus (ic);
10035             break;
10036             
10037         case '*' :
10038             genMult (ic);
10039             break;
10040             
10041         case '/' :
10042             genDiv (ic) ;
10043             break;
10044             
10045         case '%' :
10046             genMod (ic);
10047             break;
10048             
10049         case '>' :
10050             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10051             break;
10052             
10053         case '<' :
10054             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10055             break;
10056             
10057         case LE_OP:
10058         case GE_OP:
10059         case NE_OP:
10060             
10061             /* note these two are xlated by algebraic equivalence
10062                during parsing SDCC.y */
10063             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10064                    "got '>=' or '<=' shouldn't have come here");
10065             break;      
10066             
10067         case EQ_OP:
10068             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10069             break;          
10070             
10071         case AND_OP:
10072             genAndOp (ic);
10073             break;
10074             
10075         case OR_OP:
10076             genOrOp (ic);
10077             break;
10078             
10079         case '^' :
10080             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10081             break;
10082             
10083         case '|' :
10084                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10085             break;
10086             
10087         case BITWISEAND:
10088             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10089             break;
10090             
10091         case INLINEASM:
10092             genInline (ic);
10093             break;
10094             
10095         case RRC:
10096             genRRC (ic);
10097             break;
10098             
10099         case RLC:
10100             genRLC (ic);
10101             break;
10102             
10103         case GETHBIT:
10104             genGetHbit (ic);
10105             break;
10106             
10107         case LEFT_OP:
10108             genLeftShift (ic);
10109             break;
10110             
10111         case RIGHT_OP:
10112             genRightShift (ic);
10113             break;
10114             
10115         case GET_VALUE_AT_ADDRESS:
10116             genPointerGet(ic);
10117             break;
10118             
10119         case '=' :
10120             if (POINTER_SET(ic))
10121                 genPointerSet(ic);
10122             else
10123                 genAssign(ic);
10124             break;
10125             
10126         case IFX:
10127             genIfx (ic,NULL);
10128             break;
10129             
10130         case ADDRESS_OF:
10131             genAddrOf (ic);
10132             break;
10133             
10134         case JUMPTABLE:
10135             genJumpTab (ic);
10136             break;
10137             
10138         case CAST:
10139             genCast (ic);
10140             break;
10141             
10142         case RECEIVE:
10143             genReceive(ic);
10144             break;
10145             
10146         case SEND:
10147             addSet(&_G.sendSet,ic);
10148             break;
10149
10150         default :
10151             ic = ic;
10152         }
10153     }
10154     
10155
10156     /* now we are ready to call the 
10157        peep hole optimizer */
10158     if (!options.nopeep) {
10159       peepHole (&lineHead);
10160     }
10161     /* now do the actual printing */
10162     printLine (lineHead,codeOutFile);
10163
10164 #ifdef PCODE_DEBUG
10165     DFPRINTF((stderr,"printing pBlock\n\n"));
10166     printpBlock(stdout,pb);
10167 #endif
10168
10169     return;
10170 }