varA = (varB > CONSTANT); Was not compiling correctly.
[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(";"," rname %s, val %d, const = %d",
562                         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(";"," rname %s, val %d, const = %d",
617                       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         DEBUGpic14_emitcode(";","%d",__LINE__);
1116         aop->coff = offset ;
1117         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1118             dname)
1119             return "acc";
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   if ( aop->type == AOP_PCODE ||
1658        aop->type == AOP_LIT )
1659     emitpcode(POC_MOVLW,popGet(aop,offset));
1660   else
1661     emitpcode(POC_MOVFW,popGet(aop,offset));
1662
1663 }
1664
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should        */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1669 {
1670     int size ;
1671
1672     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1673     aop->coff = 0;
1674     if ((size = aop->size) <= 1)
1675         return ;
1676     size-- ;
1677     switch (aop->type) {
1678         case AOP_R0 :
1679         case AOP_R1 :
1680             while (size--)
1681                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1682             break;          
1683         case AOP_DPTR :
1684         case AOP_DPTR2:
1685             if (aop->type == AOP_DPTR2)
1686             {
1687                 genSetDPTR(1);
1688             } 
1689             while (size--)
1690             {
1691                 pic14_emitcode("lcall","__decdptr");
1692             }
1693                 
1694             if (aop->type == AOP_DPTR2)
1695             {
1696                 genSetDPTR(0);
1697             }                
1698             break;  
1699
1700     }   
1701
1702 }
1703
1704 /*-----------------------------------------------------------------*/
1705 /* genNotFloat - generates not for float operations              */
1706 /*-----------------------------------------------------------------*/
1707 static void genNotFloat (operand *op, operand *res)
1708 {
1709     int size, offset;
1710     char *l;
1711     symbol *tlbl ;
1712
1713     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1714     /* we will put 127 in the first byte of 
1715     the result */
1716     aopPut(AOP(res),"#127",0);
1717     size = AOP_SIZE(op) - 1;
1718     offset = 1;
1719
1720     l = aopGet(op->aop,offset++,FALSE,FALSE);
1721     MOVA(l);    
1722
1723     while(size--) {
1724         pic14_emitcode("orl","a,%s",
1725                  aopGet(op->aop,
1726                         offset++,FALSE,FALSE));
1727     }
1728     tlbl = newiTempLabel(NULL);
1729
1730     tlbl = newiTempLabel(NULL);
1731     aopPut(res->aop,one,1);
1732     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1733     aopPut(res->aop,zero,1);
1734     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1735
1736     size = res->aop->size - 2;
1737     offset = 2;    
1738     /* put zeros in the rest */
1739     while (size--) 
1740         aopPut(res->aop,zero,offset++);
1741 }
1742
1743 #if 0
1744 /*-----------------------------------------------------------------*/
1745 /* opIsGptr: returns non-zero if the passed operand is             */   
1746 /* a generic pointer type.                                         */
1747 /*-----------------------------------------------------------------*/ 
1748 static int opIsGptr(operand *op)
1749 {
1750     sym_link *type = operandType(op);
1751     
1752     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1753     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1754     {
1755         return 1;
1756     }
1757     return 0;        
1758 }
1759 #endif
1760
1761 /*-----------------------------------------------------------------*/
1762 /* pic14_getDataSize - get the operand data size                         */
1763 /*-----------------------------------------------------------------*/
1764 int pic14_getDataSize(operand *op)
1765 {
1766     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1767
1768
1769     return AOP_SIZE(op);
1770
1771     // tsd- in the pic port, the genptr size is 1, so this code here
1772     // fails. ( in the 8051 port, the size was 4).
1773 #if 0
1774     int size;
1775     size = AOP_SIZE(op);
1776     if (size == GPTRSIZE)
1777     {
1778         sym_link *type = operandType(op);
1779         if (IS_GENPTR(type))
1780         {
1781             /* generic pointer; arithmetic operations
1782              * should ignore the high byte (pointer type).
1783              */
1784             size--;
1785     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1786         }
1787     }
1788     return size;
1789 #endif
1790 }
1791
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_outAcc - output Acc                                             */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_outAcc(operand *result)
1796 {
1797   int size,offset;
1798   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1799   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1800
1801
1802   size = pic14_getDataSize(result);
1803   if(size){
1804     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1805     size--;
1806     offset = 1;
1807     /* unsigned or positive */
1808     while(size--)
1809       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1810   }
1811
1812 }
1813
1814 /*-----------------------------------------------------------------*/
1815 /* pic14_outBitC - output a bit C                                        */
1816 /*-----------------------------------------------------------------*/
1817 void pic14_outBitC(operand *result)
1818 {
1819
1820     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1821     /* if the result is bit */
1822     if (AOP_TYPE(result) == AOP_CRY) 
1823         aopPut(AOP(result),"c",0);
1824     else {
1825         pic14_emitcode("clr","a  ; %d", __LINE__);
1826         pic14_emitcode("rlc","a");
1827         pic14_outAcc(result);
1828     }
1829 }
1830
1831 /*-----------------------------------------------------------------*/
1832 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1833 /*-----------------------------------------------------------------*/
1834 void pic14_toBoolean(operand *oper)
1835 {
1836     int size = AOP_SIZE(oper) - 1;
1837     int offset = 1;
1838
1839     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1840
1841     if ( AOP_TYPE(oper) != AOP_ACC) {
1842       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1843     }
1844     while (size--) {
1845       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1846     }
1847 }
1848
1849
1850 /*-----------------------------------------------------------------*/
1851 /* genNot - generate code for ! operation                          */
1852 /*-----------------------------------------------------------------*/
1853 static void genNot (iCode *ic)
1854 {
1855   symbol *tlbl;
1856   sym_link *optype = operandType(IC_LEFT(ic));
1857   int size;
1858
1859   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1860   /* assign asmOps to operand & result */
1861   aopOp (IC_LEFT(ic),ic,FALSE);
1862   aopOp (IC_RESULT(ic),ic,TRUE);
1863
1864   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1865   /* if in bit space then a special case */
1866   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1867     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1868       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1869       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1870     } else {
1871       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1872       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1873       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1874     }
1875     goto release;
1876   }
1877
1878   /* if type float then do float */
1879   if (IS_FLOAT(optype)) {
1880     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1881     goto release;
1882   }
1883
1884   size = AOP_SIZE(IC_RESULT(ic));
1885   if(size == 1) {
1886     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1887     emitpcode(POC_ANDLW,popGetLit(1));
1888     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1889     goto release;
1890   }
1891   pic14_toBoolean(IC_LEFT(ic));
1892
1893   tlbl = newiTempLabel(NULL);
1894   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1895   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1896   pic14_outBitC(IC_RESULT(ic));
1897
1898  release:    
1899   /* release the aops */
1900   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1901   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1902 }
1903
1904
1905 /*-----------------------------------------------------------------*/
1906 /* genCpl - generate code for complement                           */
1907 /*-----------------------------------------------------------------*/
1908 static void genCpl (iCode *ic)
1909 {
1910     int offset = 0;
1911     int size ;
1912
1913
1914     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1915     /* assign asmOps to operand & result */
1916     aopOp (IC_LEFT(ic),ic,FALSE);
1917     aopOp (IC_RESULT(ic),ic,TRUE);
1918
1919     /* if both are in bit space then 
1920     a special case */
1921     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1922         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1923
1924         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1925         pic14_emitcode("cpl","c"); 
1926         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1927         goto release; 
1928     } 
1929
1930     size = AOP_SIZE(IC_RESULT(ic));
1931     while (size--) {
1932         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1933         MOVA(l);       
1934         pic14_emitcode("cpl","a");
1935         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1936     }
1937
1938
1939 release:
1940     /* release the aops */
1941     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1942     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1943 }
1944
1945 /*-----------------------------------------------------------------*/
1946 /* genUminusFloat - unary minus for floating points                */
1947 /*-----------------------------------------------------------------*/
1948 static void genUminusFloat(operand *op,operand *result)
1949 {
1950     int size ,offset =0 ;
1951     char *l;
1952
1953     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1954     /* for this we just need to flip the 
1955     first it then copy the rest in place */
1956     size = AOP_SIZE(op) - 1;
1957     l = aopGet(AOP(op),3,FALSE,FALSE);
1958
1959     MOVA(l);    
1960
1961     pic14_emitcode("cpl","acc.7");
1962     aopPut(AOP(result),"a",3);    
1963
1964     while(size--) {
1965         aopPut(AOP(result),
1966                aopGet(AOP(op),offset,FALSE,FALSE),
1967                offset);
1968         offset++;
1969     }          
1970 }
1971
1972 /*-----------------------------------------------------------------*/
1973 /* genUminus - unary minus code generation                         */
1974 /*-----------------------------------------------------------------*/
1975 static void genUminus (iCode *ic)
1976 {
1977   int size, i;
1978   sym_link *optype, *rtype;
1979
1980
1981   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1982   /* assign asmops */
1983   aopOp(IC_LEFT(ic),ic,FALSE);
1984   aopOp(IC_RESULT(ic),ic,TRUE);
1985
1986   /* if both in bit space then special
1987      case */
1988   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1989       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1990
1991     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1992     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1993     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1994
1995     goto release; 
1996   } 
1997
1998   optype = operandType(IC_LEFT(ic));
1999   rtype = operandType(IC_RESULT(ic));
2000
2001   /* if float then do float stuff */
2002   if (IS_FLOAT(optype)) {
2003     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2004     goto release;
2005   }
2006
2007   /* otherwise subtract from zero by taking the 2's complement */
2008   size = AOP_SIZE(IC_LEFT(ic));
2009
2010   for(i=0; i<size; i++) {
2011     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2012       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2013     else {
2014       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2015       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2016     }
2017   }
2018
2019   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2020   for(i=1; i<size; i++) {
2021     emitSKPNZ;
2022     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2023   }
2024
2025  release:
2026   /* release the aops */
2027   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2028   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2029 }
2030
2031 /*-----------------------------------------------------------------*/
2032 /* saveRegisters - will look for a call and save the registers     */
2033 /*-----------------------------------------------------------------*/
2034 static void saveRegisters(iCode *lic) 
2035 {
2036     int i;
2037     iCode *ic;
2038     bitVect *rsave;
2039     sym_link *dtype;
2040
2041     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2042     /* look for call */
2043     for (ic = lic ; ic ; ic = ic->next) 
2044         if (ic->op == CALL || ic->op == PCALL)
2045             break;
2046
2047     if (!ic) {
2048         fprintf(stderr,"found parameter push with no function call\n");
2049         return ;
2050     }
2051
2052     /* if the registers have been saved already then
2053     do nothing */
2054     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2055         return ;
2056
2057     /* find the registers in use at this time 
2058     and push them away to safety */
2059     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2060                           ic->rUsed);
2061
2062     ic->regsSaved = 1;
2063     if (options.useXstack) {
2064         if (bitVectBitValue(rsave,R0_IDX))
2065             pic14_emitcode("mov","b,r0");
2066         pic14_emitcode("mov","r0,%s",spname);
2067         for (i = 0 ; i < pic14_nRegs ; i++) {
2068             if (bitVectBitValue(rsave,i)) {
2069                 if (i == R0_IDX)
2070                     pic14_emitcode("mov","a,b");
2071                 else
2072                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2073                 pic14_emitcode("movx","@r0,a");
2074                 pic14_emitcode("inc","r0");
2075             }
2076         }
2077         pic14_emitcode("mov","%s,r0",spname);
2078         if (bitVectBitValue(rsave,R0_IDX))
2079             pic14_emitcode("mov","r0,b");           
2080     }// else
2081     //for (i = 0 ; i < pic14_nRegs ; i++) {
2082     //    if (bitVectBitValue(rsave,i))
2083     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2084     //}
2085
2086     dtype = operandType(IC_LEFT(ic));
2087     if (currFunc && dtype && 
2088         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2089         IFFUNC_ISISR(currFunc->type) &&
2090         !ic->bankSaved) 
2091
2092         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2093
2094 }
2095 /*-----------------------------------------------------------------*/
2096 /* unsaveRegisters - pop the pushed registers                      */
2097 /*-----------------------------------------------------------------*/
2098 static void unsaveRegisters (iCode *ic)
2099 {
2100     int i;
2101     bitVect *rsave;
2102
2103     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2104     /* find the registers in use at this time 
2105     and push them away to safety */
2106     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2107                           ic->rUsed);
2108     
2109     if (options.useXstack) {
2110         pic14_emitcode("mov","r0,%s",spname);   
2111         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2112             if (bitVectBitValue(rsave,i)) {
2113                 pic14_emitcode("dec","r0");
2114                 pic14_emitcode("movx","a,@r0");
2115                 if (i == R0_IDX)
2116                     pic14_emitcode("mov","b,a");
2117                 else
2118                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2119             }       
2120
2121         }
2122         pic14_emitcode("mov","%s,r0",spname);
2123         if (bitVectBitValue(rsave,R0_IDX))
2124             pic14_emitcode("mov","r0,b");
2125     } //else
2126     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2127     //    if (bitVectBitValue(rsave,i))
2128     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2129     //}
2130
2131 }  
2132
2133
2134 /*-----------------------------------------------------------------*/
2135 /* pushSide -                                                      */
2136 /*-----------------------------------------------------------------*/
2137 static void pushSide(operand * oper, int size)
2138 {
2139 #if 0
2140         int offset = 0;
2141     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2142         while (size--) {
2143                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2144                 if (AOP_TYPE(oper) != AOP_REG &&
2145                     AOP_TYPE(oper) != AOP_DIR &&
2146                     strcmp(l,"a") ) {
2147                         pic14_emitcode("mov","a,%s",l);
2148                         pic14_emitcode("push","acc");
2149                 } else
2150                         pic14_emitcode("push","%s",l);
2151         }
2152 #endif
2153 }
2154
2155 /*-----------------------------------------------------------------*/
2156 /* assignResultValue -                                             */
2157 /*-----------------------------------------------------------------*/
2158 static void assignResultValue(operand * oper)
2159 {
2160   int size = AOP_SIZE(oper);
2161
2162   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2163
2164   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2165
2166   if(!GpsuedoStkPtr) {
2167     /* The last byte in the assignment is in W */
2168     size--;
2169     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2170     GpsuedoStkPtr++;
2171   }
2172
2173   while (size--) {
2174     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2175     GpsuedoStkPtr++;
2176     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2177   }
2178 }
2179
2180
2181 /*-----------------------------------------------------------------*/
2182 /* genIpush - genrate code for pushing this gets a little complex  */
2183 /*-----------------------------------------------------------------*/
2184 static void genIpush (iCode *ic)
2185 {
2186
2187   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2188 #if 0
2189     int size, offset = 0 ;
2190     char *l;
2191
2192
2193     /* if this is not a parm push : ie. it is spill push 
2194     and spill push is always done on the local stack */
2195     if (!ic->parmPush) {
2196
2197         /* and the item is spilt then do nothing */
2198         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2199             return ;
2200
2201         aopOp(IC_LEFT(ic),ic,FALSE);
2202         size = AOP_SIZE(IC_LEFT(ic));
2203         /* push it on the stack */
2204         while(size--) {
2205             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2206             if (*l == '#') {
2207                 MOVA(l);
2208                 l = "acc";
2209             }
2210             pic14_emitcode("push","%s",l);
2211         }
2212         return ;        
2213     }
2214
2215     /* this is a paramter push: in this case we call
2216     the routine to find the call and save those
2217     registers that need to be saved */   
2218     saveRegisters(ic);
2219
2220     /* then do the push */
2221     aopOp(IC_LEFT(ic),ic,FALSE);
2222
2223
2224         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2225     size = AOP_SIZE(IC_LEFT(ic));
2226
2227     while (size--) {
2228         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2229         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2230             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2231             strcmp(l,"a") ) {
2232             pic14_emitcode("mov","a,%s",l);
2233             pic14_emitcode("push","acc");
2234         } else
2235             pic14_emitcode("push","%s",l);
2236     }       
2237
2238     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2239 #endif
2240 }
2241
2242 /*-----------------------------------------------------------------*/
2243 /* genIpop - recover the registers: can happen only for spilling   */
2244 /*-----------------------------------------------------------------*/
2245 static void genIpop (iCode *ic)
2246 {
2247   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2248 #if 0
2249     int size,offset ;
2250
2251
2252     /* if the temp was not pushed then */
2253     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2254         return ;
2255
2256     aopOp(IC_LEFT(ic),ic,FALSE);
2257     size = AOP_SIZE(IC_LEFT(ic));
2258     offset = (size-1);
2259     while (size--) 
2260         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2261                                    FALSE,TRUE));
2262
2263     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2264 #endif
2265 }
2266
2267 /*-----------------------------------------------------------------*/
2268 /* unsaverbank - restores the resgister bank from stack            */
2269 /*-----------------------------------------------------------------*/
2270 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2271 {
2272   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2273 #if 0
2274     int i;
2275     asmop *aop ;
2276     regs *r = NULL;
2277
2278     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2279     if (popPsw) {
2280         if (options.useXstack) {
2281             aop = newAsmop(0);
2282             r = getFreePtr(ic,&aop,FALSE);
2283             
2284             
2285             pic14_emitcode("mov","%s,_spx",r->name);
2286             pic14_emitcode("movx","a,@%s",r->name);
2287             pic14_emitcode("mov","psw,a");
2288             pic14_emitcode("dec","%s",r->name);
2289             
2290         }else
2291             pic14_emitcode ("pop","psw");
2292     }
2293
2294     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2295         if (options.useXstack) {       
2296             pic14_emitcode("movx","a,@%s",r->name);
2297             //pic14_emitcode("mov","(%s+%d),a",
2298             //       regspic14[i].base,8*bank+regspic14[i].offset);
2299             pic14_emitcode("dec","%s",r->name);
2300
2301         } else 
2302           pic14_emitcode("pop",""); //"(%s+%d)",
2303         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2304     }
2305
2306     if (options.useXstack) {
2307
2308         pic14_emitcode("mov","_spx,%s",r->name);
2309         freeAsmop(NULL,aop,ic,TRUE);
2310
2311     }
2312 #endif 
2313 }
2314
2315 /*-----------------------------------------------------------------*/
2316 /* saverbank - saves an entire register bank on the stack          */
2317 /*-----------------------------------------------------------------*/
2318 static void saverbank (int bank, iCode *ic, bool pushPsw)
2319 {
2320   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2321 #if 0
2322     int i;
2323     asmop *aop ;
2324     regs *r = NULL;
2325
2326     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2327     if (options.useXstack) {
2328
2329         aop = newAsmop(0);
2330         r = getFreePtr(ic,&aop,FALSE);  
2331         pic14_emitcode("mov","%s,_spx",r->name);
2332
2333     }
2334
2335     for (i = 0 ; i < pic14_nRegs ;i++) {
2336         if (options.useXstack) {
2337             pic14_emitcode("inc","%s",r->name);
2338             //pic14_emitcode("mov","a,(%s+%d)",
2339             //         regspic14[i].base,8*bank+regspic14[i].offset);
2340             pic14_emitcode("movx","@%s,a",r->name);           
2341         } else 
2342           pic14_emitcode("push","");// "(%s+%d)",
2343                      //regspic14[i].base,8*bank+regspic14[i].offset);
2344     }
2345     
2346     if (pushPsw) {
2347         if (options.useXstack) {
2348             pic14_emitcode("mov","a,psw");
2349             pic14_emitcode("movx","@%s,a",r->name);     
2350             pic14_emitcode("inc","%s",r->name);
2351             pic14_emitcode("mov","_spx,%s",r->name);       
2352             freeAsmop (NULL,aop,ic,TRUE);
2353             
2354         } else
2355             pic14_emitcode("push","psw");
2356         
2357         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2358     }
2359     ic->bankSaved = 1;
2360 #endif
2361 }
2362
2363 /*-----------------------------------------------------------------*/
2364 /* genCall - generates a call statement                            */
2365 /*-----------------------------------------------------------------*/
2366 static void genCall (iCode *ic)
2367 {
2368   sym_link *dtype;   
2369
2370   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2371
2372   /* if caller saves & we have not saved then */
2373   if (!ic->regsSaved)
2374     saveRegisters(ic);
2375
2376   /* if we are calling a function that is not using
2377      the same register bank then we need to save the
2378      destination registers on the stack */
2379   dtype = operandType(IC_LEFT(ic));
2380   if (currFunc && dtype && 
2381       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2382       IFFUNC_ISISR(currFunc->type) &&
2383       !ic->bankSaved) 
2384
2385     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2386
2387   /* if send set is not empty the assign */
2388   if (_G.sendSet) {
2389     iCode *sic;
2390     /* For the Pic port, there is no data stack.
2391      * So parameters passed to functions are stored
2392      * in registers. (The pCode optimizer will get
2393      * rid of most of these :).
2394      */
2395     int psuedoStkPtr=-1; 
2396     int firstTimeThruLoop = 1;
2397
2398     _G.sendSet = reverseSet(_G.sendSet);
2399
2400     /* First figure how many parameters are getting passed */
2401     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2402          sic = setNextItem(_G.sendSet)) {
2403
2404       aopOp(IC_LEFT(sic),sic,FALSE);
2405       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2406       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2407     }
2408
2409     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2410          sic = setNextItem(_G.sendSet)) {
2411       int size, offset = 0;
2412
2413       aopOp(IC_LEFT(sic),sic,FALSE);
2414       size = AOP_SIZE(IC_LEFT(sic));
2415
2416       while (size--) {
2417         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2418                              AopType(AOP_TYPE(IC_LEFT(sic))));
2419
2420         if(!firstTimeThruLoop) {
2421           /* If this is not the first time we've been through the loop
2422            * then we need to save the parameter in a temporary
2423            * register. The last byte of the last parameter is
2424            * passed in W. */
2425           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2426
2427         }
2428         firstTimeThruLoop=0;
2429
2430         //if (strcmp(l,fReturn[offset])) {
2431         mov2w (AOP(IC_LEFT(sic)),  offset);
2432 /*
2433         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2434              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2435           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2436         else
2437           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2438 */
2439         //}
2440         offset++;
2441       }
2442       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2443     }
2444     _G.sendSet = NULL;
2445   }
2446   /* make the call */
2447   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2448                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2449                                       OP_SYMBOL(IC_LEFT(ic))->name));
2450
2451   GpsuedoStkPtr=0;
2452   /* if we need assign a result value */
2453   if ((IS_ITEMP(IC_RESULT(ic)) && 
2454        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2455         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2456       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2457
2458     _G.accInUse++;
2459     aopOp(IC_RESULT(ic),ic,FALSE);
2460     _G.accInUse--;
2461
2462     assignResultValue(IC_RESULT(ic));
2463
2464     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2465                          AopType(AOP_TYPE(IC_RESULT(ic))));
2466                 
2467     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2468   }
2469
2470   /* adjust the stack for parameters if 
2471      required */
2472   if (ic->parmBytes) {
2473     int i;
2474     if (ic->parmBytes > 3) {
2475       pic14_emitcode("mov","a,%s",spname);
2476       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2477       pic14_emitcode("mov","%s,a",spname);
2478     } else 
2479       for ( i = 0 ; i <  ic->parmBytes ;i++)
2480         pic14_emitcode("dec","%s",spname);
2481
2482   }
2483
2484   /* if register bank was saved then pop them */
2485   if (ic->bankSaved)
2486     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2487
2488   /* if we hade saved some registers then unsave them */
2489   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2490     unsaveRegisters (ic);
2491
2492
2493 }
2494
2495 /*-----------------------------------------------------------------*/
2496 /* genPcall - generates a call by pointer statement                */
2497 /*-----------------------------------------------------------------*/
2498 static void genPcall (iCode *ic)
2499 {
2500     sym_link *dtype;
2501     symbol *rlbl = newiTempLabel(NULL);
2502
2503
2504     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2505     /* if caller saves & we have not saved then */
2506     if (!ic->regsSaved)
2507         saveRegisters(ic);
2508
2509     /* if we are calling a function that is not using
2510     the same register bank then we need to save the
2511     destination registers on the stack */
2512     dtype = operandType(IC_LEFT(ic));
2513     if (currFunc && dtype && 
2514         IFFUNC_ISISR(currFunc->type) &&
2515         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2516         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2517
2518
2519     /* push the return address on to the stack */
2520     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2521     pic14_emitcode("push","acc");    
2522     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2523     pic14_emitcode("push","acc");
2524     
2525     if (options.model == MODEL_FLAT24)
2526     {
2527         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2528         pic14_emitcode("push","acc");    
2529     }
2530
2531     /* now push the calling address */
2532     aopOp(IC_LEFT(ic),ic,FALSE);
2533
2534     pushSide(IC_LEFT(ic), FPTRSIZE);
2535
2536     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2537
2538     /* if send set is not empty the assign */
2539     if (_G.sendSet) {
2540         iCode *sic ;
2541
2542         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2543              sic = setNextItem(_G.sendSet)) {
2544             int size, offset = 0;
2545             aopOp(IC_LEFT(sic),sic,FALSE);
2546             size = AOP_SIZE(IC_LEFT(sic));
2547             while (size--) {
2548                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2549                                 FALSE,FALSE);
2550                 if (strcmp(l,fReturn[offset]))
2551                     pic14_emitcode("mov","%s,%s",
2552                              fReturn[offset],
2553                              l);
2554                 offset++;
2555             }
2556             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2557         }
2558         _G.sendSet = NULL;
2559     }
2560
2561     pic14_emitcode("ret","");
2562     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2563
2564
2565     /* if we need assign a result value */
2566     if ((IS_ITEMP(IC_RESULT(ic)) &&
2567          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2568           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2569         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2570
2571         _G.accInUse++;
2572         aopOp(IC_RESULT(ic),ic,FALSE);
2573         _G.accInUse--;
2574         
2575         assignResultValue(IC_RESULT(ic));
2576
2577         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2578     }
2579
2580     /* adjust the stack for parameters if 
2581     required */
2582     if (ic->parmBytes) {
2583         int i;
2584         if (ic->parmBytes > 3) {
2585             pic14_emitcode("mov","a,%s",spname);
2586             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2587             pic14_emitcode("mov","%s,a",spname);
2588         } else 
2589             for ( i = 0 ; i <  ic->parmBytes ;i++)
2590                 pic14_emitcode("dec","%s",spname);
2591
2592     }
2593
2594     /* if register bank was saved then unsave them */
2595     if (currFunc && dtype && 
2596         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2597         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2598
2599     /* if we hade saved some registers then
2600     unsave them */
2601     if (ic->regsSaved)
2602         unsaveRegisters (ic);
2603
2604 }
2605
2606 /*-----------------------------------------------------------------*/
2607 /* resultRemat - result  is rematerializable                       */
2608 /*-----------------------------------------------------------------*/
2609 static int resultRemat (iCode *ic)
2610 {
2611   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2612   if (SKIP_IC(ic) || ic->op == IFX)
2613     return 0;
2614
2615   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2616     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2617     if (sym->remat && !POINTER_SET(ic)) 
2618       return 1;
2619   }
2620
2621   return 0;
2622 }
2623
2624 #if defined(__BORLANDC__) || defined(_MSC_VER)
2625 #define STRCASECMP stricmp
2626 #else
2627 #define STRCASECMP strcasecmp
2628 #endif
2629
2630 #if 0
2631 /*-----------------------------------------------------------------*/
2632 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2633 /*-----------------------------------------------------------------*/
2634 static bool inExcludeList(char *s)
2635 {
2636   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2637     int i =0;
2638     
2639     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2640     if (options.excludeRegs[i] &&
2641     STRCASECMP(options.excludeRegs[i],"none") == 0)
2642         return FALSE ;
2643
2644     for ( i = 0 ; options.excludeRegs[i]; i++) {
2645         if (options.excludeRegs[i] &&
2646         STRCASECMP(s,options.excludeRegs[i]) == 0)
2647             return TRUE;
2648     }
2649     return FALSE ;
2650 }
2651 #endif
2652
2653 /*-----------------------------------------------------------------*/
2654 /* genFunction - generated code for function entry                 */
2655 /*-----------------------------------------------------------------*/
2656 static void genFunction (iCode *ic)
2657 {
2658     symbol *sym;
2659     sym_link *ftype;
2660
2661     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2662
2663     labelOffset += (max_key+4);
2664     max_key=0;
2665     GpsuedoStkPtr=0;
2666     _G.nRegsSaved = 0;
2667     /* create the function header */
2668     pic14_emitcode(";","-----------------------------------------");
2669     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2670     pic14_emitcode(";","-----------------------------------------");
2671
2672     pic14_emitcode("","%s:",sym->rname);
2673     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2674
2675     ftype = operandType(IC_LEFT(ic));
2676
2677     /* if critical function then turn interrupts off */
2678     if (IFFUNC_ISCRITICAL(ftype))
2679         pic14_emitcode("clr","ea");
2680
2681     /* here we need to generate the equates for the
2682        register bank if required */
2683 #if 0
2684     if (FUNC_REGBANK(ftype) != rbank) {
2685         int i ;
2686
2687         rbank = FUNC_REGBANK(ftype);
2688         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2689             if (strcmp(regspic14[i].base,"0") == 0)
2690                 pic14_emitcode("","%s = 0x%02x",
2691                          regspic14[i].dname,
2692                          8*rbank+regspic14[i].offset);
2693             else
2694                 pic14_emitcode ("","%s = %s + 0x%02x",
2695                           regspic14[i].dname,
2696                           regspic14[i].base,
2697                           8*rbank+regspic14[i].offset);
2698         }
2699     }
2700 #endif
2701
2702     /* if this is an interrupt service routine then
2703     save acc, b, dpl, dph  */
2704     if (IFFUNC_ISISR(sym->type)) {
2705       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2706       emitpcodeNULLop(POC_NOP);
2707       emitpcodeNULLop(POC_NOP);
2708       emitpcodeNULLop(POC_NOP);
2709       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2710       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2711       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2712       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2713
2714       pBlockConvert2ISR(pb);
2715 #if 0  
2716         if (!inExcludeList("acc"))          
2717             pic14_emitcode ("push","acc");      
2718         if (!inExcludeList("b"))
2719             pic14_emitcode ("push","b");
2720         if (!inExcludeList("dpl"))
2721             pic14_emitcode ("push","dpl");
2722         if (!inExcludeList("dph"))
2723             pic14_emitcode ("push","dph");
2724         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2725         {
2726             pic14_emitcode ("push", "dpx");
2727             /* Make sure we're using standard DPTR */
2728             pic14_emitcode ("push", "dps");
2729             pic14_emitcode ("mov", "dps, #0x00");
2730             if (options.stack10bit)
2731             {   
2732                 /* This ISR could conceivably use DPTR2. Better save it. */
2733                 pic14_emitcode ("push", "dpl1");
2734                 pic14_emitcode ("push", "dph1");
2735                 pic14_emitcode ("push", "dpx1");
2736             }
2737         }
2738         /* if this isr has no bank i.e. is going to
2739            run with bank 0 , then we need to save more
2740            registers :-) */
2741         if (!FUNC_REGBANK(sym->type)) {
2742
2743             /* if this function does not call any other
2744                function then we can be economical and
2745                save only those registers that are used */
2746             if (! IFFUNC_HASFCALL(sym->type)) {
2747                 int i;
2748
2749                 /* if any registers used */
2750                 if (sym->regsUsed) {
2751                     /* save the registers used */
2752                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2753                         if (bitVectBitValue(sym->regsUsed,i) ||
2754                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2755                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2756                     }
2757                 }
2758                 
2759             } else {
2760                 /* this function has  a function call cannot
2761                    determines register usage so we will have the
2762                    entire bank */
2763                 saverbank(0,ic,FALSE);
2764             }       
2765         }
2766 #endif
2767     } else {
2768         /* if callee-save to be used for this function
2769            then save the registers being used in this function */
2770         if (IFFUNC_CALLEESAVES(sym->type)) {
2771             int i;
2772             
2773             /* if any registers used */
2774             if (sym->regsUsed) {
2775                 /* save the registers used */
2776                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2777                     if (bitVectBitValue(sym->regsUsed,i) ||
2778                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2779                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2780                         _G.nRegsSaved++;
2781                     }
2782                 }
2783             }
2784         }
2785     }
2786
2787     /* set the register bank to the desired value */
2788     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2789         pic14_emitcode("push","psw");
2790         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2791     }
2792
2793     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2794
2795         if (options.useXstack) {
2796             pic14_emitcode("mov","r0,%s",spname);
2797             pic14_emitcode("mov","a,_bp");
2798             pic14_emitcode("movx","@r0,a");
2799             pic14_emitcode("inc","%s",spname);
2800         }
2801         else
2802         {
2803             /* set up the stack */
2804             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2805         }
2806         pic14_emitcode ("mov","_bp,%s",spname);
2807     }
2808
2809     /* adjust the stack for the function */
2810     if (sym->stack) {
2811
2812         int i = sym->stack;
2813         if (i > 256 ) 
2814             werror(W_STACK_OVERFLOW,sym->name);
2815
2816         if (i > 3 && sym->recvSize < 4) {              
2817
2818             pic14_emitcode ("mov","a,sp");
2819             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2820             pic14_emitcode ("mov","sp,a");
2821            
2822         }
2823         else
2824             while(i--)
2825                 pic14_emitcode("inc","sp");
2826     }
2827
2828      if (sym->xstack) {
2829
2830         pic14_emitcode ("mov","a,_spx");
2831         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2832         pic14_emitcode ("mov","_spx,a");
2833     }    
2834
2835 }
2836
2837 /*-----------------------------------------------------------------*/
2838 /* genEndFunction - generates epilogue for functions               */
2839 /*-----------------------------------------------------------------*/
2840 static void genEndFunction (iCode *ic)
2841 {
2842     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2843
2844     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2845
2846     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2847     {
2848         pic14_emitcode ("mov","%s,_bp",spname);
2849     }
2850
2851     /* if use external stack but some variables were
2852     added to the local stack then decrement the
2853     local stack */
2854     if (options.useXstack && sym->stack) {      
2855         pic14_emitcode("mov","a,sp");
2856         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2857         pic14_emitcode("mov","sp,a");
2858     }
2859
2860
2861     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2862         if (options.useXstack) {
2863             pic14_emitcode("mov","r0,%s",spname);
2864             pic14_emitcode("movx","a,@r0");
2865             pic14_emitcode("mov","_bp,a");
2866             pic14_emitcode("dec","%s",spname);
2867         }
2868         else
2869         {
2870             pic14_emitcode ("pop","_bp");
2871         }
2872     }
2873
2874     /* restore the register bank  */    
2875     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2876         pic14_emitcode ("pop","psw");
2877
2878     if (IFFUNC_ISISR(sym->type)) {
2879
2880         /* now we need to restore the registers */
2881         /* if this isr has no bank i.e. is going to
2882            run with bank 0 , then we need to save more
2883            registers :-) */
2884         if (!FUNC_REGBANK(sym->type)) {
2885             
2886             /* if this function does not call any other
2887                function then we can be economical and
2888                save only those registers that are used */
2889             if (! IFFUNC_HASFCALL(sym->type)) {
2890                 int i;
2891                 
2892                 /* if any registers used */
2893                 if (sym->regsUsed) {
2894                     /* save the registers used */
2895                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2896                         if (bitVectBitValue(sym->regsUsed,i) ||
2897                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2898                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2899                     }
2900                 }
2901                 
2902             } else {
2903                 /* this function has  a function call cannot
2904                    determines register usage so we will have the
2905                    entire bank */
2906                 unsaverbank(0,ic,FALSE);
2907             }       
2908         }
2909 #if 0
2910         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2911         {
2912             if (options.stack10bit)
2913             {
2914                 pic14_emitcode ("pop", "dpx1");
2915                 pic14_emitcode ("pop", "dph1");
2916                 pic14_emitcode ("pop", "dpl1");
2917             }   
2918             pic14_emitcode ("pop", "dps");
2919             pic14_emitcode ("pop", "dpx");
2920         }
2921         if (!inExcludeList("dph"))
2922             pic14_emitcode ("pop","dph");
2923         if (!inExcludeList("dpl"))
2924             pic14_emitcode ("pop","dpl");
2925         if (!inExcludeList("b"))
2926             pic14_emitcode ("pop","b");
2927         if (!inExcludeList("acc"))
2928             pic14_emitcode ("pop","acc");
2929
2930         if (IFFUNC_ISCRITICAL(sym->type))
2931             pic14_emitcode("setb","ea");
2932 #endif
2933
2934         /* if debug then send end of function */
2935 /*      if (options.debug && currFunc) { */
2936         if (currFunc) {
2937             _G.debugLine = 1;
2938             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2939                      FileBaseName(ic->filename),currFunc->lastLine,
2940                      ic->level,ic->block); 
2941             if (IS_STATIC(currFunc->etype))         
2942                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2943             else
2944                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2945             _G.debugLine = 0;
2946         }
2947         
2948         pic14_emitcode ("reti","");
2949
2950         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2951         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2952         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2953         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2954         emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
2955         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2956
2957         emitpcodeNULLop(POC_RETFIE);
2958
2959     }
2960     else {
2961         if (IFFUNC_ISCRITICAL(sym->type))
2962             pic14_emitcode("setb","ea");
2963         
2964         if (IFFUNC_CALLEESAVES(sym->type)) {
2965             int i;
2966             
2967             /* if any registers used */
2968             if (sym->regsUsed) {
2969                 /* save the registers used */
2970                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2971                     if (bitVectBitValue(sym->regsUsed,i) ||
2972                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2973                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2974                 }
2975             }
2976             
2977         }
2978
2979         /* if debug then send end of function */
2980         if (currFunc) {
2981             _G.debugLine = 1;
2982             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2983                      FileBaseName(ic->filename),currFunc->lastLine,
2984                      ic->level,ic->block); 
2985             if (IS_STATIC(currFunc->etype))         
2986                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2987             else
2988                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2989             _G.debugLine = 0;
2990         }
2991
2992         pic14_emitcode ("return","");
2993         emitpcodeNULLop(POC_RETURN);
2994
2995         /* Mark the end of a function */
2996         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2997     }
2998
2999 }
3000
3001 /*-----------------------------------------------------------------*/
3002 /* genRet - generate code for return statement                     */
3003 /*-----------------------------------------------------------------*/
3004 static void genRet (iCode *ic)
3005 {
3006   int size,offset = 0 , pushed = 0;
3007     
3008   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3009   /* if we have no return value then
3010      just generate the "ret" */
3011   if (!IC_LEFT(ic)) 
3012     goto jumpret;       
3013     
3014   /* we have something to return then
3015      move the return value into place */
3016   aopOp(IC_LEFT(ic),ic,FALSE);
3017   size = AOP_SIZE(IC_LEFT(ic));
3018     
3019   while (size--) {
3020     char *l ;
3021     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3022       /* #NOCHANGE */
3023       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3024                  FALSE,TRUE);
3025       pic14_emitcode("push","%s",l);
3026       pushed++;
3027     } else {
3028       l = aopGet(AOP(IC_LEFT(ic)),offset,
3029                  FALSE,FALSE);
3030       if (strcmp(fReturn[offset],l)) {
3031         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3032             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3033           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3034         }else {
3035           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3036         }
3037         if(size) {
3038           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3039         }
3040         offset++;
3041       }
3042     }
3043   }    
3044
3045   if (pushed) {
3046     while(pushed) {
3047       pushed--;
3048       if (strcmp(fReturn[pushed],"a"))
3049         pic14_emitcode("pop",fReturn[pushed]);
3050       else
3051         pic14_emitcode("pop","acc");
3052     }
3053   }
3054   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3055     
3056  jumpret:
3057   /* generate a jump to the return label
3058      if the next is not the return statement */
3059   if (!(ic->next && ic->next->op == LABEL &&
3060         IC_LABEL(ic->next) == returnLabel)) {
3061         
3062     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3063     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3064   }
3065     
3066 }
3067
3068 /*-----------------------------------------------------------------*/
3069 /* genLabel - generates a label                                    */
3070 /*-----------------------------------------------------------------*/
3071 static void genLabel (iCode *ic)
3072 {
3073     /* special case never generate */
3074     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3075     if (IC_LABEL(ic) == entryLabel)
3076         return ;
3077
3078     emitpLabel(IC_LABEL(ic)->key);
3079     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3080 }
3081
3082 /*-----------------------------------------------------------------*/
3083 /* genGoto - generates a goto                                      */
3084 /*-----------------------------------------------------------------*/
3085 //tsd
3086 static void genGoto (iCode *ic)
3087 {
3088   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3089   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3090 }
3091
3092
3093 /*-----------------------------------------------------------------*/
3094 /* genMultbits :- multiplication of bits                           */
3095 /*-----------------------------------------------------------------*/
3096 static void genMultbits (operand *left, 
3097                          operand *right, 
3098                          operand *result)
3099 {
3100   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3101
3102   if(!pic14_sameRegs(AOP(result),AOP(right)))
3103     emitpcode(POC_BSF,  popGet(AOP(result),0));
3104
3105   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3106   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3107   emitpcode(POC_BCF,  popGet(AOP(result),0));
3108
3109 }
3110
3111
3112 /*-----------------------------------------------------------------*/
3113 /* genMultOneByte : 8 bit multiplication & division                */
3114 /*-----------------------------------------------------------------*/
3115 static void genMultOneByte (operand *left,
3116                             operand *right,
3117                             operand *result)
3118 {
3119   sym_link *opetype = operandType(result);
3120
3121   // symbol *lbl ;
3122   int size,offset;
3123
3124   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3125   DEBUGpic14_AopType(__LINE__,left,right,result);
3126   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3127
3128   /* (if two literals, the value is computed before) */
3129   /* if one literal, literal on the right */
3130   if (AOP_TYPE(left) == AOP_LIT){
3131     operand *t = right;
3132     right = left;
3133     left = t;
3134   }
3135
3136   size = AOP_SIZE(result);
3137   if(size == 1) {
3138
3139     if (AOP_TYPE(right) == AOP_LIT){
3140       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3141                      aopGet(AOP(right),0,FALSE,FALSE), 
3142                      aopGet(AOP(left),0,FALSE,FALSE), 
3143                      aopGet(AOP(result),0,FALSE,FALSE));
3144       pic14_emitcode("call","genMultLit");
3145     } else {
3146       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3147                      aopGet(AOP(right),0,FALSE,FALSE), 
3148                      aopGet(AOP(left),0,FALSE,FALSE), 
3149                      aopGet(AOP(result),0,FALSE,FALSE));
3150       pic14_emitcode("call","genMult8X8_8");
3151
3152     }
3153     genMult8X8_8 (left, right,result);
3154
3155
3156     /* signed or unsigned */
3157     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3158     //l = aopGet(AOP(left),0,FALSE,FALSE);
3159     //MOVA(l);       
3160     //pic14_emitcode("mul","ab");
3161     /* if result size = 1, mul signed = mul unsigned */
3162     //aopPut(AOP(result),"a",0);
3163
3164   } else {  // (size > 1)
3165
3166     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3167                    aopGet(AOP(right),0,FALSE,FALSE), 
3168                    aopGet(AOP(left),0,FALSE,FALSE), 
3169                    aopGet(AOP(result),0,FALSE,FALSE));
3170
3171     if (SPEC_USIGN(opetype)){
3172       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3173       genUMult8X8_16 (left, right, result, NULL);
3174
3175       if (size > 2) {
3176         /* for filling the MSBs */
3177         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3178         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3179       }
3180     }
3181     else{
3182       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3183
3184       pic14_emitcode("mov","a,b");
3185
3186       /* adjust the MSB if left or right neg */
3187
3188       /* if one literal */
3189       if (AOP_TYPE(right) == AOP_LIT){
3190         pic14_emitcode("multiply ","right is a lit");
3191         /* AND literal negative */
3192         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3193           /* adjust MSB (c==0 after mul) */
3194           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3195         }
3196       }
3197       else{
3198         genSMult8X8_16 (left, right, result, NULL);
3199       }
3200
3201       if(size > 2){
3202         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3203         /* get the sign */
3204         pic14_emitcode("rlc","a");
3205         pic14_emitcode("subb","a,acc");
3206       }
3207     }
3208
3209     size -= 2;   
3210     offset = 2;
3211     if (size > 0)
3212       while (size--)
3213         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3214     //aopPut(AOP(result),"a",offset++);
3215   }
3216 }
3217
3218 /*-----------------------------------------------------------------*/
3219 /* genMult - generates code for multiplication                     */
3220 /*-----------------------------------------------------------------*/
3221 static void genMult (iCode *ic)
3222 {
3223     operand *left = IC_LEFT(ic);
3224     operand *right = IC_RIGHT(ic);
3225     operand *result= IC_RESULT(ic);   
3226
3227     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3228     /* assign the amsops */
3229     aopOp (left,ic,FALSE);
3230     aopOp (right,ic,FALSE);
3231     aopOp (result,ic,TRUE);
3232
3233   DEBUGpic14_AopType(__LINE__,left,right,result);
3234
3235     /* special cases first */
3236     /* both are bits */
3237     if (AOP_TYPE(left) == AOP_CRY &&
3238         AOP_TYPE(right)== AOP_CRY) {
3239         genMultbits(left,right,result);
3240         goto release ;
3241     }
3242
3243     /* if both are of size == 1 */
3244     if (AOP_SIZE(left) == 1 &&
3245         AOP_SIZE(right) == 1 ) {
3246         genMultOneByte(left,right,result);
3247         goto release ;
3248     }
3249
3250     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3251
3252     /* should have been converted to function call */
3253     //assert(0) ;
3254
3255 release :
3256     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3257     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258     freeAsmop(result,NULL,ic,TRUE); 
3259 }
3260
3261 /*-----------------------------------------------------------------*/
3262 /* genDivbits :- division of bits                                  */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivbits (operand *left, 
3265                         operand *right, 
3266                         operand *result)
3267 {
3268
3269     char *l;
3270
3271     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3272     /* the result must be bit */    
3273     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3274     l = aopGet(AOP(left),0,FALSE,FALSE);
3275
3276     MOVA(l);    
3277
3278     pic14_emitcode("div","ab");
3279     pic14_emitcode("rrc","a");
3280     aopPut(AOP(result),"c",0);
3281 }
3282
3283 /*-----------------------------------------------------------------*/
3284 /* genDivOneByte : 8 bit division                                  */
3285 /*-----------------------------------------------------------------*/
3286 static void genDivOneByte (operand *left,
3287                            operand *right,
3288                            operand *result)
3289 {
3290     sym_link *opetype = operandType(result);
3291     char *l ;
3292     symbol *lbl ;
3293     int size,offset;
3294
3295     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3296     size = AOP_SIZE(result) - 1;
3297     offset = 1;
3298     /* signed or unsigned */
3299     if (SPEC_USIGN(opetype)) {
3300         /* unsigned is easy */
3301         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3302         l = aopGet(AOP(left),0,FALSE,FALSE);
3303         MOVA(l);        
3304         pic14_emitcode("div","ab");
3305         aopPut(AOP(result),"a",0);
3306         while (size--)
3307             aopPut(AOP(result),zero,offset++);
3308         return ;
3309     }
3310
3311     /* signed is a little bit more difficult */
3312
3313     /* save the signs of the operands */
3314     l = aopGet(AOP(left),0,FALSE,FALSE);    
3315     MOVA(l);    
3316     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3317     pic14_emitcode("push","acc"); /* save it on the stack */
3318
3319     /* now sign adjust for both left & right */
3320     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3321     MOVA(l);       
3322     lbl = newiTempLabel(NULL);
3323     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3324     pic14_emitcode("cpl","a");   
3325     pic14_emitcode("inc","a");
3326     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3327     pic14_emitcode("mov","b,a");
3328
3329     /* sign adjust left side */
3330     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3331     MOVA(l);
3332
3333     lbl = newiTempLabel(NULL);
3334     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3335     pic14_emitcode("cpl","a");
3336     pic14_emitcode("inc","a");
3337     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3338
3339     /* now the division */
3340     pic14_emitcode("div","ab");
3341     /* we are interested in the lower order
3342     only */
3343     pic14_emitcode("mov","b,a");
3344     lbl = newiTempLabel(NULL);
3345     pic14_emitcode("pop","acc");   
3346     /* if there was an over flow we don't 
3347     adjust the sign of the result */
3348     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3349     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3350     CLRC;
3351     pic14_emitcode("clr","a");
3352     pic14_emitcode("subb","a,b");
3353     pic14_emitcode("mov","b,a");
3354     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3355
3356     /* now we are done */
3357     aopPut(AOP(result),"b",0);
3358     if(size > 0){
3359         pic14_emitcode("mov","c,b.7");
3360         pic14_emitcode("subb","a,acc");   
3361     }
3362     while (size--)
3363         aopPut(AOP(result),"a",offset++);
3364
3365 }
3366
3367 /*-----------------------------------------------------------------*/
3368 /* genDiv - generates code for division                            */
3369 /*-----------------------------------------------------------------*/
3370 static void genDiv (iCode *ic)
3371 {
3372     operand *left = IC_LEFT(ic);
3373     operand *right = IC_RIGHT(ic);
3374     operand *result= IC_RESULT(ic);   
3375
3376     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3377     /* assign the amsops */
3378     aopOp (left,ic,FALSE);
3379     aopOp (right,ic,FALSE);
3380     aopOp (result,ic,TRUE);
3381
3382     /* special cases first */
3383     /* both are bits */
3384     if (AOP_TYPE(left) == AOP_CRY &&
3385         AOP_TYPE(right)== AOP_CRY) {
3386         genDivbits(left,right,result);
3387         goto release ;
3388     }
3389
3390     /* if both are of size == 1 */
3391     if (AOP_SIZE(left) == 1 &&
3392         AOP_SIZE(right) == 1 ) {
3393         genDivOneByte(left,right,result);
3394         goto release ;
3395     }
3396
3397     /* should have been converted to function call */
3398     assert(0);
3399 release :
3400     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3401     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402     freeAsmop(result,NULL,ic,TRUE); 
3403 }
3404
3405 /*-----------------------------------------------------------------*/
3406 /* genModbits :- modulus of bits                                   */
3407 /*-----------------------------------------------------------------*/
3408 static void genModbits (operand *left, 
3409                         operand *right, 
3410                         operand *result)
3411 {
3412
3413     char *l;
3414
3415     /* the result must be bit */    
3416     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3417     l = aopGet(AOP(left),0,FALSE,FALSE);
3418
3419     MOVA(l);       
3420
3421     pic14_emitcode("div","ab");
3422     pic14_emitcode("mov","a,b");
3423     pic14_emitcode("rrc","a");
3424     aopPut(AOP(result),"c",0);
3425 }
3426
3427 /*-----------------------------------------------------------------*/
3428 /* genModOneByte : 8 bit modulus                                   */
3429 /*-----------------------------------------------------------------*/
3430 static void genModOneByte (operand *left,
3431                            operand *right,
3432                            operand *result)
3433 {
3434     sym_link *opetype = operandType(result);
3435     char *l ;
3436     symbol *lbl ;
3437
3438     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3439     /* signed or unsigned */
3440     if (SPEC_USIGN(opetype)) {
3441         /* unsigned is easy */
3442         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3443         l = aopGet(AOP(left),0,FALSE,FALSE);
3444         MOVA(l);    
3445         pic14_emitcode("div","ab");
3446         aopPut(AOP(result),"b",0);
3447         return ;
3448     }
3449
3450     /* signed is a little bit more difficult */
3451
3452     /* save the signs of the operands */
3453     l = aopGet(AOP(left),0,FALSE,FALSE);    
3454     MOVA(l);
3455
3456     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3457     pic14_emitcode("push","acc"); /* save it on the stack */
3458
3459     /* now sign adjust for both left & right */
3460     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3461     MOVA(l);
3462
3463     lbl = newiTempLabel(NULL);
3464     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3465     pic14_emitcode("cpl","a");   
3466     pic14_emitcode("inc","a");
3467     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3468     pic14_emitcode("mov","b,a"); 
3469
3470     /* sign adjust left side */
3471     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3472     MOVA(l);
3473
3474     lbl = newiTempLabel(NULL);
3475     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476     pic14_emitcode("cpl","a");   
3477     pic14_emitcode("inc","a");
3478     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3479
3480     /* now the multiplication */
3481     pic14_emitcode("div","ab");
3482     /* we are interested in the lower order
3483     only */
3484     lbl = newiTempLabel(NULL);
3485     pic14_emitcode("pop","acc");   
3486     /* if there was an over flow we don't 
3487     adjust the sign of the result */
3488     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3489     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3490     CLRC ;
3491     pic14_emitcode("clr","a");
3492     pic14_emitcode("subb","a,b");
3493     pic14_emitcode("mov","b,a");
3494     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3495
3496     /* now we are done */
3497     aopPut(AOP(result),"b",0);
3498
3499 }
3500
3501 /*-----------------------------------------------------------------*/
3502 /* genMod - generates code for division                            */
3503 /*-----------------------------------------------------------------*/
3504 static void genMod (iCode *ic)
3505 {
3506     operand *left = IC_LEFT(ic);
3507     operand *right = IC_RIGHT(ic);
3508     operand *result= IC_RESULT(ic);  
3509
3510     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3511     /* assign the amsops */
3512     aopOp (left,ic,FALSE);
3513     aopOp (right,ic,FALSE);
3514     aopOp (result,ic,TRUE);
3515
3516     /* special cases first */
3517     /* both are bits */
3518     if (AOP_TYPE(left) == AOP_CRY &&
3519         AOP_TYPE(right)== AOP_CRY) {
3520         genModbits(left,right,result);
3521         goto release ;
3522     }
3523
3524     /* if both are of size == 1 */
3525     if (AOP_SIZE(left) == 1 &&
3526         AOP_SIZE(right) == 1 ) {
3527         genModOneByte(left,right,result);
3528         goto release ;
3529     }
3530
3531     /* should have been converted to function call */
3532     assert(0);
3533
3534 release :
3535     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3536     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537     freeAsmop(result,NULL,ic,TRUE); 
3538 }
3539
3540 /*-----------------------------------------------------------------*/
3541 /* genIfxJump :- will create a jump depending on the ifx           */
3542 /*-----------------------------------------------------------------*/
3543 /*
3544   note: May need to add parameter to indicate when a variable is in bit space.
3545 */
3546 static void genIfxJump (iCode *ic, char *jval)
3547 {
3548
3549     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3550     /* if true label then we jump if condition
3551     supplied is true */
3552     if ( IC_TRUE(ic) ) {
3553
3554         if(strcmp(jval,"a") == 0)
3555           emitSKPZ;
3556         else if (strcmp(jval,"c") == 0)
3557           emitSKPC;
3558         else {
3559           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3560           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3561         }
3562
3563         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3564         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3565
3566     }
3567     else {
3568         /* false label is present */
3569         if(strcmp(jval,"a") == 0)
3570           emitSKPNZ;
3571         else if (strcmp(jval,"c") == 0)
3572           emitSKPNC;
3573         else {
3574           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3575           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3576         }
3577
3578         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3579         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3580
3581     }
3582
3583
3584     /* mark the icode as generated */
3585     ic->generated = 1;
3586 }
3587
3588 /*-----------------------------------------------------------------*/
3589 /* genSkip                                                         */
3590 /*-----------------------------------------------------------------*/
3591 static void genSkip(iCode *ifx,int status_bit)
3592 {
3593   if(!ifx)
3594     return;
3595
3596   if ( IC_TRUE(ifx) ) {
3597     switch(status_bit) {
3598     case 'z':
3599       emitSKPNZ;
3600       break;
3601
3602     case 'c':
3603       emitSKPNC;
3604       break;
3605
3606     case 'd':
3607       emitSKPDC;
3608       break;
3609
3610     }
3611
3612     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3613     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3614
3615   } else {
3616
3617     switch(status_bit) {
3618
3619     case 'z':
3620       emitSKPZ;
3621       break;
3622
3623     case 'c':
3624       emitSKPC;
3625       break;
3626
3627     case 'd':
3628       emitSKPDC;
3629       break;
3630     }
3631     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3632     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3633
3634   }
3635
3636 }
3637
3638 /*-----------------------------------------------------------------*/
3639 /* genSkipc                                                        */
3640 /*-----------------------------------------------------------------*/
3641 static void genSkipc(resolvedIfx *rifx)
3642 {
3643   if(!rifx)
3644     return;
3645
3646   if(rifx->condition)
3647     emitSKPC;
3648   else
3649     emitSKPNC;
3650
3651   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3652   rifx->generated = 1;
3653 }
3654
3655 /*-----------------------------------------------------------------*/
3656 /* genSkipz2                                                       */
3657 /*-----------------------------------------------------------------*/
3658 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3659 {
3660   if(!rifx)
3661     return;
3662
3663   if( (rifx->condition ^ invert_condition) & 1)
3664     emitSKPZ;
3665   else
3666     emitSKPNZ;
3667
3668   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3669   rifx->generated = 1;
3670 }
3671
3672 /*-----------------------------------------------------------------*/
3673 /* genSkipz                                                        */
3674 /*-----------------------------------------------------------------*/
3675 static void genSkipz(iCode *ifx, int condition)
3676 {
3677   if(!ifx)
3678     return;
3679
3680   if(condition)
3681     emitSKPNZ;
3682   else
3683     emitSKPZ;
3684
3685   if ( IC_TRUE(ifx) )
3686     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3687   else
3688     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3689
3690   if ( IC_TRUE(ifx) )
3691     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3692   else
3693     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3694
3695 }
3696 /*-----------------------------------------------------------------*/
3697 /* genSkipCond                                                     */
3698 /*-----------------------------------------------------------------*/
3699 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3700 {
3701   if(!rifx)
3702     return;
3703
3704   if(rifx->condition)
3705     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3706   else
3707     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3708
3709
3710   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3711   rifx->generated = 1;
3712 }
3713
3714 #if 0
3715 /*-----------------------------------------------------------------*/
3716 /* genChkZeroes :- greater or less than comparison                 */
3717 /*     For each byte in a literal that is zero, inclusive or the   */
3718 /*     the corresponding byte in the operand with W                */
3719 /*     returns true if any of the bytes are zero                   */
3720 /*-----------------------------------------------------------------*/
3721 static int genChkZeroes(operand *op, int lit,  int size)
3722 {
3723
3724   int i;
3725   int flag =1;
3726
3727   while(size--) {
3728     i = (lit >> (size*8)) & 0xff;
3729
3730     if(i==0) {
3731       if(flag) 
3732         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3733       else
3734         emitpcode(POC_IORFW, popGet(AOP(op),size));
3735       flag = 0;
3736     }
3737   }
3738
3739   return (flag==0);
3740 }
3741 #endif
3742
3743 /*-----------------------------------------------------------------*/
3744 /* genCmp :- greater or less than comparison                       */
3745 /*-----------------------------------------------------------------*/
3746 static void genCmp (operand *left,operand *right,
3747                     operand *result, iCode *ifx, int sign)
3748 {
3749   int size; //, offset = 0 ;
3750   unsigned long lit = 0L,i = 0;
3751   resolvedIfx rFalseIfx;
3752   //  resolvedIfx rTrueIfx;
3753   symbol *truelbl;
3754   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3755 /*
3756   if(ifx) {
3757     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3758     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3759   }
3760 */
3761
3762   resolveIfx(&rFalseIfx,ifx);
3763   truelbl  = newiTempLabel(NULL);
3764   size = max(AOP_SIZE(left),AOP_SIZE(right));
3765
3766   DEBUGpic14_AopType(__LINE__,left,right,result);
3767
3768 #define _swapp
3769
3770   /* if literal is on the right then swap with left */
3771   if ((AOP_TYPE(right) == AOP_LIT)) {
3772     operand *tmp = right ;
3773     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3774     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3775 #ifdef _swapp
3776
3777     lit = (lit - 1) & mask;
3778     right = left;
3779     left = tmp;
3780     rFalseIfx.condition ^= 1;
3781 #endif
3782
3783   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3784     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3785   }
3786
3787
3788   //if(IC_TRUE(ifx) == NULL)
3789   /* if left & right are bit variables */
3790   if (AOP_TYPE(left) == AOP_CRY &&
3791       AOP_TYPE(right) == AOP_CRY ) {
3792     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3793     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3794   } else {
3795     /* subtract right from left if at the
3796        end the carry flag is set then we know that
3797        left is greater than right */
3798
3799     //    {
3800
3801     symbol *lbl  = newiTempLabel(NULL);
3802
3803 #ifndef _swapp
3804     if(AOP_TYPE(right) == AOP_LIT) {
3805
3806       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3807
3808       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3809
3810       /* special cases */
3811
3812       if(lit == 0) {
3813
3814         if(sign != 0) 
3815           genSkipCond(&rFalseIfx,left,size-1,7);
3816         else 
3817           /* no need to compare to 0...*/
3818           /* NOTE: this is a de-generate compare that most certainly 
3819            *       creates some dead code. */
3820           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3821
3822         if(ifx) ifx->generated = 1;
3823         return;
3824
3825       }
3826       size--;
3827
3828       if(size == 0) {
3829         //i = (lit >> (size*8)) & 0xff;
3830         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3831         
3832         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3833
3834         i = ((0-lit) & 0xff);
3835         if(sign) {
3836           if( i == 0x81) { 
3837             /* lit is 0x7f, all signed chars are less than
3838              * this except for 0x7f itself */
3839             emitpcode(POC_XORLW, popGetLit(0x7f));
3840             genSkipz2(&rFalseIfx,0);
3841           } else {
3842             emitpcode(POC_ADDLW, popGetLit(0x80));
3843             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3844             genSkipc(&rFalseIfx);
3845           }
3846
3847         } else {
3848           if(lit == 1) {
3849             genSkipz2(&rFalseIfx,1);
3850           } else {
3851             emitpcode(POC_ADDLW, popGetLit(i));
3852             genSkipc(&rFalseIfx);
3853           }
3854         }
3855
3856         if(ifx) ifx->generated = 1;
3857         return;
3858       }
3859
3860       /* chars are out of the way. now do ints and longs */
3861
3862
3863       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3864         
3865       /* special cases */
3866
3867       if(sign) {
3868
3869         if(lit == 0) {
3870           genSkipCond(&rFalseIfx,left,size,7);
3871           if(ifx) ifx->generated = 1;
3872           return;
3873         }
3874
3875         if(lit <0x100) {
3876           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3877
3878           //rFalseIfx.condition ^= 1;
3879           //genSkipCond(&rFalseIfx,left,size,7);
3880           //rFalseIfx.condition ^= 1;
3881
3882           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3883           if(rFalseIfx.condition)
3884             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3885           else
3886             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3887
3888           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3889           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3890           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3891
3892           while(size > 1)
3893             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3894
3895           if(rFalseIfx.condition) {
3896             emitSKPZ;
3897             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3898
3899           } else {
3900             emitSKPNZ;
3901           }
3902
3903           genSkipc(&rFalseIfx);
3904           emitpLabel(truelbl->key);
3905           if(ifx) ifx->generated = 1;
3906           return;
3907
3908         }
3909
3910         if(size == 1) {
3911
3912           if( (lit & 0xff) == 0) {
3913             /* lower byte is zero */
3914             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3915             i = ((lit >> 8) & 0xff) ^0x80;
3916             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3917             emitpcode(POC_ADDLW, popGetLit( 0x80));
3918             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3919             genSkipc(&rFalseIfx);
3920
3921
3922             if(ifx) ifx->generated = 1;
3923             return;
3924
3925           }
3926         } else {
3927           /* Special cases for signed longs */
3928           if( (lit & 0xffffff) == 0) {
3929             /* lower byte is zero */
3930             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3931             i = ((lit >> 8*3) & 0xff) ^0x80;
3932             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3933             emitpcode(POC_ADDLW, popGetLit( 0x80));
3934             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3935             genSkipc(&rFalseIfx);
3936
3937
3938             if(ifx) ifx->generated = 1;
3939             return;
3940
3941           }
3942
3943         }
3944
3945
3946         if(lit & (0x80 << (size*8))) {
3947           /* lit is negative */
3948           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3949
3950           //genSkipCond(&rFalseIfx,left,size,7);
3951
3952           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3953
3954           if(rFalseIfx.condition)
3955             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3956           else
3957             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3958
3959
3960         } else {
3961           /* lit is positive */
3962           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3963           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3964           if(rFalseIfx.condition)
3965             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3966           else
3967             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3968
3969         }
3970
3971         /*
3972           This works, but is only good for ints.
3973           It also requires a "known zero" register.
3974           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3975           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3976           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3977           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3978           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3979           genSkipc(&rFalseIfx);
3980
3981           emitpLabel(truelbl->key);
3982           if(ifx) ifx->generated = 1;
3983           return;
3984         **/
3985           
3986         /* There are no more special cases, so perform a general compare */
3987   
3988         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3989         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3990
3991         while(size--) {
3992
3993           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3994           emitSKPNZ;
3995           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3996         }
3997         //rFalseIfx.condition ^= 1;
3998         genSkipc(&rFalseIfx);
3999
4000         emitpLabel(truelbl->key);
4001
4002         if(ifx) ifx->generated = 1;
4003         return;
4004
4005
4006       }
4007
4008
4009       /* sign is out of the way. So now do an unsigned compare */
4010       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4011
4012
4013       /* General case - compare to an unsigned literal on the right.*/
4014
4015       i = (lit >> (size*8)) & 0xff;
4016       emitpcode(POC_MOVLW, popGetLit(i));
4017       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4018       while(size--) {
4019         i = (lit >> (size*8)) & 0xff;
4020
4021         if(i) {
4022           emitpcode(POC_MOVLW, popGetLit(i));
4023           emitSKPNZ;
4024           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4025         } else {
4026           /* this byte of the lit is zero, 
4027            *if it's not the last then OR in the variable */
4028           if(size)
4029             emitpcode(POC_IORFW, popGet(AOP(left),size));
4030         }
4031       }
4032
4033
4034       emitpLabel(lbl->key);
4035       //if(emitFinalCheck)
4036       genSkipc(&rFalseIfx);
4037       if(sign)
4038         emitpLabel(truelbl->key);
4039
4040       if(ifx) ifx->generated = 1;
4041       return;
4042
4043
4044     }
4045 #endif  // _swapp
4046
4047     if(AOP_TYPE(left) == AOP_LIT) {
4048       //symbol *lbl = newiTempLabel(NULL);
4049
4050       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4051
4052
4053       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4054
4055       /* Special cases */
4056       if((lit == 0) && (sign == 0)){
4057
4058         size--;
4059         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4060         while(size) 
4061           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4062
4063         genSkipz2(&rFalseIfx,0);
4064         if(ifx) ifx->generated = 1;
4065         return;
4066       }
4067
4068       if(size==1) {
4069         /* Special cases */
4070         lit &= 0xff;
4071         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4072           /* degenerate compare can never be true */
4073           if(rFalseIfx.condition == 0)
4074             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4075
4076           if(ifx) ifx->generated = 1;
4077           return;
4078         }
4079
4080         if(sign) {
4081           /* signed comparisons to a literal byte */
4082
4083           int lp1 = (lit+1) & 0xff;
4084
4085           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4086           switch (lp1) {
4087           case 0:
4088             rFalseIfx.condition ^= 1;
4089             genSkipCond(&rFalseIfx,right,0,7);
4090             break;
4091           case 0x7f:
4092             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4093             emitpcode(POC_XORLW, popGetLit(0x7f));
4094             genSkipz2(&rFalseIfx,1);
4095             break;
4096           default:
4097             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4098             emitpcode(POC_ADDLW, popGetLit(0x80));
4099             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4100             rFalseIfx.condition ^= 1;
4101             genSkipc(&rFalseIfx);
4102             break;
4103           }
4104         } else {
4105           /* unsigned comparisons to a literal byte */
4106
4107           switch(lit & 0xff ) {
4108           case 0:
4109             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4110             genSkipz2(&rFalseIfx,0);
4111             break;
4112           case 0x7f:
4113             rFalseIfx.condition ^= 1;
4114             genSkipCond(&rFalseIfx,right,0,7);
4115             break;
4116
4117           default:
4118             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4119             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4120             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4121             rFalseIfx.condition ^= 1;
4122             if (AOP_TYPE(result) == AOP_CRY)
4123               genSkipc(&rFalseIfx);
4124             else {
4125               emitpcode(POC_CLRF, popGet(AOP(result),0));
4126               emitpcode(POC_RLF, popGet(AOP(result),0));
4127             }         
4128             break;
4129           }
4130         }
4131
4132         if(ifx) ifx->generated = 1;
4133         //goto check_carry;
4134         return;
4135
4136       } else {
4137
4138         /* Size is greater than 1 */
4139
4140         if(sign) {
4141           int lp1 = lit+1;
4142
4143           size--;
4144
4145           if(lp1 == 0) {
4146             /* this means lit = 0xffffffff, or -1 */
4147
4148
4149             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4150             rFalseIfx.condition ^= 1;
4151             genSkipCond(&rFalseIfx,right,size,7);
4152             if(ifx) ifx->generated = 1;
4153             return;
4154           }
4155
4156           if(lit == 0) {
4157             int s = size;
4158
4159             if(rFalseIfx.condition) {
4160               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4161               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4162             }
4163
4164             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4165             while(size--)
4166               emitpcode(POC_IORFW, popGet(AOP(right),size));
4167
4168
4169             emitSKPZ;
4170             if(rFalseIfx.condition) {
4171               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4172               emitpLabel(truelbl->key);
4173             }else {
4174               rFalseIfx.condition ^= 1;
4175               genSkipCond(&rFalseIfx,right,s,7);
4176             }
4177
4178             if(ifx) ifx->generated = 1;
4179             return;
4180           }
4181
4182           if((size == 1) &&  (0 == (lp1&0xff))) {
4183             /* lower byte of signed word is zero */
4184             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4185             i = ((lp1 >> 8) & 0xff) ^0x80;
4186             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4187             emitpcode(POC_ADDLW, popGetLit( 0x80));
4188             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4189             rFalseIfx.condition ^= 1;
4190             genSkipc(&rFalseIfx);
4191
4192
4193             if(ifx) ifx->generated = 1;
4194             return;
4195           }
4196
4197           if(lit & (0x80 << (size*8))) {
4198             /* Lit is less than zero */
4199             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4200             //rFalseIfx.condition ^= 1;
4201             //genSkipCond(&rFalseIfx,left,size,7);
4202             //rFalseIfx.condition ^= 1;
4203             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4205
4206             if(rFalseIfx.condition)
4207               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4208             else
4209               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4210
4211
4212           } else {
4213             /* Lit is greater than or equal to zero */
4214             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4215             //rFalseIfx.condition ^= 1;
4216             //genSkipCond(&rFalseIfx,right,size,7);
4217             //rFalseIfx.condition ^= 1;
4218
4219             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4221
4222             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4223             if(rFalseIfx.condition)
4224               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4225             else
4226               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4227
4228           }
4229
4230
4231           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4233
4234           while(size--) {
4235
4236             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4237             emitSKPNZ;
4238             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4239           }
4240           rFalseIfx.condition ^= 1;
4241           //rFalseIfx.condition = 1;
4242           genSkipc(&rFalseIfx);
4243
4244           emitpLabel(truelbl->key);
4245
4246           if(ifx) ifx->generated = 1;
4247           return;
4248           // end of if (sign)
4249         } else {
4250
4251           /* compare word or long to an unsigned literal on the right.*/
4252
4253
4254           size--;
4255           if(lit < 0xff) {
4256             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4257             switch (lit) {
4258             case 0:
4259               break; /* handled above */
4260 /*
4261             case 0xff:
4262               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4263               while(size--)
4264                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265               genSkipz2(&rFalseIfx,0);
4266               break;
4267 */
4268             default:
4269               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4270               while(--size)
4271                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4272
4273               emitSKPZ;
4274               if(rFalseIfx.condition)
4275                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4276               else
4277                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4278
4279
4280               emitpcode(POC_MOVLW, popGetLit(lit+1));
4281               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4282
4283               rFalseIfx.condition ^= 1;
4284               genSkipc(&rFalseIfx);
4285             }
4286
4287             emitpLabel(truelbl->key);
4288
4289             if(ifx) ifx->generated = 1;
4290             return;
4291           }
4292
4293
4294           lit++;
4295           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4296           i = (lit >> (size*8)) & 0xff;
4297
4298           emitpcode(POC_MOVLW, popGetLit(i));
4299           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4300
4301           while(size--) {
4302             i = (lit >> (size*8)) & 0xff;
4303
4304             if(i) {
4305               emitpcode(POC_MOVLW, popGetLit(i));
4306               emitSKPNZ;
4307               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4308             } else {
4309               /* this byte of the lit is zero, 
4310                *if it's not the last then OR in the variable */
4311               if(size)
4312                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4313             }
4314           }
4315
4316
4317           emitpLabel(lbl->key);
4318
4319           rFalseIfx.condition ^= 1;
4320           genSkipc(&rFalseIfx);
4321         }
4322
4323         if(sign)
4324           emitpLabel(truelbl->key);
4325         if(ifx) ifx->generated = 1;
4326         return;
4327       }
4328     }
4329     /* Compare two variables */
4330
4331     DEBUGpic14_emitcode(";sign","%d",sign);
4332
4333     size--;
4334     if(sign) {
4335       /* Sigh. thus sucks... */
4336       if(size) {
4337         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4338         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4339         emitpcode(POC_MOVLW, popGetLit(0x80));
4340         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4341         emitpcode(POC_XORFW, popGet(AOP(right),size));
4342         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4343       } else {
4344         /* Signed char comparison */
4345         /* Special thanks to Nikolai Golovchenko for this snippet */
4346         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4347         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4348         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4349         emitpcode(POC_XORFW, popGet(AOP(left),0));
4350         emitpcode(POC_XORFW, popGet(AOP(right),0));
4351         emitpcode(POC_ADDLW, popGetLit(0x80));
4352
4353         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4354         genSkipc(&rFalseIfx);
4355           
4356         if(ifx) ifx->generated = 1;
4357         return;
4358       }
4359
4360     } else {
4361
4362       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4363       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4364     }
4365
4366
4367     /* The rest of the bytes of a multi-byte compare */
4368     while (size) {
4369
4370       emitSKPZ;
4371       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4372       size--;
4373
4374       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4375       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4376
4377
4378     }
4379
4380     emitpLabel(lbl->key);
4381
4382     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4383     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4384         (AOP_TYPE(result) == AOP_REG)) {
4385       emitpcode(POC_CLRF, popGet(AOP(result),0));
4386       emitpcode(POC_RLF, popGet(AOP(result),0));
4387     } else {
4388       genSkipc(&rFalseIfx);
4389     }         
4390     //genSkipc(&rFalseIfx);
4391     if(ifx) ifx->generated = 1;
4392
4393     return;
4394
4395   }
4396
4397  check_carry:
4398   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4399     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4400     pic14_outBitC(result);
4401   } else {
4402     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4403     /* if the result is used in the next
4404        ifx conditional branch then generate
4405        code a little differently */
4406     if (ifx )
4407       genIfxJump (ifx,"c");
4408     else
4409       pic14_outBitC(result);
4410     /* leave the result in acc */
4411   }
4412
4413 }
4414
4415 /*-----------------------------------------------------------------*/
4416 /* genCmpGt :- greater than comparison                             */
4417 /*-----------------------------------------------------------------*/
4418 static void genCmpGt (iCode *ic, iCode *ifx)
4419 {
4420     operand *left, *right, *result;
4421     sym_link *letype , *retype;
4422     int sign ;
4423
4424     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4425     left = IC_LEFT(ic);
4426     right= IC_RIGHT(ic);
4427     result = IC_RESULT(ic);
4428
4429     letype = getSpec(operandType(left));
4430     retype =getSpec(operandType(right));
4431     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4432     /* assign the amsops */
4433     aopOp (left,ic,FALSE);
4434     aopOp (right,ic,FALSE);
4435     aopOp (result,ic,TRUE);
4436
4437     genCmp(right, left, result, ifx, sign);
4438
4439     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441     freeAsmop(result,NULL,ic,TRUE); 
4442 }
4443
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpLt - less than comparisons                                */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpLt (iCode *ic, iCode *ifx)
4448 {
4449     operand *left, *right, *result;
4450     sym_link *letype , *retype;
4451     int sign ;
4452
4453     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4454     left = IC_LEFT(ic);
4455     right= IC_RIGHT(ic);
4456     result = IC_RESULT(ic);
4457
4458     letype = getSpec(operandType(left));
4459     retype =getSpec(operandType(right));
4460     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4461
4462     /* assign the amsops */
4463     aopOp (left,ic,FALSE);
4464     aopOp (right,ic,FALSE);
4465     aopOp (result,ic,TRUE);
4466
4467     genCmp(left, right, result, ifx, sign);
4468
4469     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471     freeAsmop(result,NULL,ic,TRUE); 
4472 }
4473
4474 /*-----------------------------------------------------------------*/
4475 /* genc16bit2lit - compare a 16 bit value to a literal             */
4476 /*-----------------------------------------------------------------*/
4477 static void genc16bit2lit(operand *op, int lit, int offset)
4478 {
4479   int i;
4480
4481   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4482   if( (lit&0xff) == 0) 
4483     i=1;
4484   else
4485     i=0;
4486
4487   switch( BYTEofLONG(lit,i)) { 
4488   case 0:
4489     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4490     break;
4491   case 1:
4492     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4493     break;
4494   case 0xff:
4495     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4496     break;
4497   default:
4498     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4499     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4500   }
4501
4502   i ^= 1;
4503
4504   switch( BYTEofLONG(lit,i)) { 
4505   case 0:
4506     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4507     break;
4508   case 1:
4509     emitSKPNZ;
4510     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4511     break;
4512   case 0xff:
4513     emitSKPNZ;
4514     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4515     break;
4516   default:
4517     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4518     emitSKPNZ;
4519     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4520
4521   }
4522
4523 }
4524
4525 /*-----------------------------------------------------------------*/
4526 /* gencjneshort - compare and jump if not equal                    */
4527 /*-----------------------------------------------------------------*/
4528 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4529 {
4530   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4531   int offset = 0;
4532   resolvedIfx rIfx;
4533   symbol *lbl;
4534
4535   unsigned long lit = 0L;
4536   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4537   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4538
4539   resolveIfx(&rIfx,ifx);
4540   lbl =  newiTempLabel(NULL);
4541
4542
4543   /* if the left side is a literal or 
4544      if the right is in a pointer register and left 
4545      is not */
4546   if ((AOP_TYPE(left) == AOP_LIT) || 
4547       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4548     operand *t = right;
4549     right = left;
4550     left = t;
4551   }
4552   if(AOP_TYPE(right) == AOP_LIT)
4553     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4554
4555   /* if the right side is a literal then anything goes */
4556   if (AOP_TYPE(right) == AOP_LIT &&
4557       AOP_TYPE(left) != AOP_DIR ) {
4558     switch(size) {
4559     case 2:
4560       genc16bit2lit(left, lit, 0);
4561       emitSKPNZ;
4562       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4563       break;
4564     default:
4565       while (size--) {
4566         if(lit & 0xff) {
4567           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4568           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4569         } else {
4570           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4571         }
4572
4573         emitSKPNZ;
4574         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4575         offset++;
4576         lit >>= 8;
4577       }
4578       break;
4579     }
4580   }
4581
4582   /* if the right side is in a register or in direct space or
4583      if the left is a pointer register & right is not */    
4584   else if (AOP_TYPE(right) == AOP_REG ||
4585            AOP_TYPE(right) == AOP_DIR || 
4586            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4587            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4588     switch(size) {
4589     case 2:
4590       genc16bit2lit(left, lit, 0);
4591       emitSKPNZ;
4592       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4593       break;
4594     default:
4595       while (size--) {
4596         int emit_skip=1;
4597         if((AOP_TYPE(left) == AOP_DIR) && 
4598            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4599
4600           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4601           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4602
4603         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4604             
4605           switch (lit & 0xff) {
4606           case 0:
4607             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4608             break;
4609           case 1:
4610             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4611             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4612             emit_skip=0;
4613             break;
4614           case 0xff:
4615             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4616             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4617             emit_skip=0;
4618             break;
4619           default:
4620             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4621             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4622           }
4623           lit >>= 8;
4624
4625         } else {
4626           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4627         }
4628         if(emit_skip) {
4629           if(AOP_TYPE(result) == AOP_CRY) {
4630             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4631             if(rIfx.condition)
4632               emitSKPNZ;
4633             else
4634               emitSKPZ;
4635             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4636           } else {
4637             /* fix me. probably need to check result size too */
4638             emitpcode(POC_CLRF,popGet(AOP(result),0));
4639             if(rIfx.condition)
4640               emitSKPNZ;
4641             else
4642               emitSKPZ;
4643             emitpcode(POC_INCF,popGet(AOP(result),0));
4644           }
4645           if(ifx)
4646             ifx->generated=1;
4647         }
4648         emit_skip++;
4649         offset++;
4650       }
4651       break;
4652     }
4653   } else if(AOP_TYPE(right) == AOP_REG &&
4654             AOP_TYPE(left) != AOP_DIR){
4655
4656     while(size--) {
4657       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4658       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4659       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4660       if(rIfx.condition)
4661         emitSKPNZ;
4662       else
4663         emitSKPZ;
4664       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4665       offset++;
4666     }
4667       
4668   }else{
4669     /* right is a pointer reg need both a & b */
4670     while(size--) {
4671       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4672       if(strcmp(l,"b"))
4673         pic14_emitcode("mov","b,%s",l);
4674       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4675       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4676       offset++;
4677     }
4678   }
4679   emitpLabel(lbl->key);
4680
4681   if(ifx)
4682     ifx->generated = 1;
4683 }
4684
4685 #if 0
4686 /*-----------------------------------------------------------------*/
4687 /* gencjne - compare and jump if not equal                         */
4688 /*-----------------------------------------------------------------*/
4689 static void gencjne(operand *left, operand *right, iCode *ifx)
4690 {
4691     symbol *tlbl  = newiTempLabel(NULL);
4692
4693     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4694     gencjneshort(left, right, lbl);
4695
4696     pic14_emitcode("mov","a,%s",one);
4697     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4698     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4699     pic14_emitcode("clr","a");
4700     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4701
4702     emitpLabel(lbl->key);
4703     emitpLabel(tlbl->key);
4704
4705 }
4706 #endif
4707
4708 /*-----------------------------------------------------------------*/
4709 /* genCmpEq - generates code for equal to                          */
4710 /*-----------------------------------------------------------------*/
4711 static void genCmpEq (iCode *ic, iCode *ifx)
4712 {
4713     operand *left, *right, *result;
4714     unsigned long lit = 0L;
4715     int size,offset=0;
4716
4717     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4718
4719     if(ifx)
4720       DEBUGpic14_emitcode ("; ifx is non-null","");
4721     else
4722       DEBUGpic14_emitcode ("; ifx is null","");
4723
4724     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4725     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4726     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4727
4728     size = max(AOP_SIZE(left),AOP_SIZE(right));
4729
4730     DEBUGpic14_AopType(__LINE__,left,right,result);
4731
4732     /* if literal, literal on the right or 
4733     if the right is in a pointer register and left 
4734     is not */
4735     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4736         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4737       operand *tmp = right ;
4738       right = left;
4739       left = tmp;
4740     }
4741
4742
4743     if(ifx && !AOP_SIZE(result)){
4744         symbol *tlbl;
4745         /* if they are both bit variables */
4746         if (AOP_TYPE(left) == AOP_CRY &&
4747             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4748             if(AOP_TYPE(right) == AOP_LIT){
4749                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4750                 if(lit == 0L){
4751                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4752                     pic14_emitcode("cpl","c");
4753                 } else if(lit == 1L) {
4754                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4755                 } else {
4756                     pic14_emitcode("clr","c");
4757                 }
4758                 /* AOP_TYPE(right) == AOP_CRY */
4759             } else {
4760                 symbol *lbl = newiTempLabel(NULL);
4761                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4762                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4763                 pic14_emitcode("cpl","c");
4764                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4765             }
4766             /* if true label then we jump if condition
4767             supplied is true */
4768             tlbl = newiTempLabel(NULL);
4769             if ( IC_TRUE(ifx) ) {
4770                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4771                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4772             } else {
4773                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4774                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4775             }
4776             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4777
4778             {
4779               /* left and right are both bit variables, result is carry */
4780               resolvedIfx rIfx;
4781               
4782               resolveIfx(&rIfx,ifx);
4783
4784               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4785               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4786               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4787               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4788               genSkipz2(&rIfx,0);
4789             }
4790         } else {
4791
4792           /* They're not both bit variables. Is the right a literal? */
4793           if(AOP_TYPE(right) == AOP_LIT) {
4794             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4795             
4796             switch(size) {
4797
4798             case 1:
4799               switch(lit & 0xff) {
4800               case 1:
4801                 if ( IC_TRUE(ifx) ) {
4802                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4803                   emitSKPNZ;
4804                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4805                 } else {
4806                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4807                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4808                 }
4809                 break;
4810               case 0xff:
4811                 if ( IC_TRUE(ifx) ) {
4812                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4813                   emitSKPNZ;
4814                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4815                 } else {
4816                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4817                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4818                 }
4819                 break;
4820               default:
4821                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4822                 if(lit)
4823                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4824                 genSkip(ifx,'z');
4825               }
4826
4827
4828               /* end of size == 1 */
4829               break;
4830               
4831             case 2:
4832               genc16bit2lit(left,lit,offset);
4833               genSkip(ifx,'z');
4834               break;
4835               /* end of size == 2 */
4836
4837             default:
4838               /* size is 4 */
4839               if(lit==0) {
4840                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4841                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4842                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4843                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4844
4845               } else {
4846
4847                 /* search for patterns that can be optimized */
4848
4849                 genc16bit2lit(left,lit,0);
4850                 lit >>= 16;
4851                 if(lit) {
4852                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4853                   //genSkip(ifx,'z');
4854                   genc16bit2lit(left,lit,2);
4855                 } else {
4856                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4857                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4858
4859                 }
4860                 
4861               }
4862
4863               genSkip(ifx,'z');
4864             }
4865           
4866             ifx->generated = 1;
4867             goto release ;
4868             
4869
4870           } else if(AOP_TYPE(right) == AOP_CRY ) {
4871             /* we know the left is not a bit, but that the right is */
4872             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4873             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4874                       popGet(AOP(right),offset));
4875             emitpcode(POC_XORLW,popGetLit(1));
4876
4877             /* if the two are equal, then W will be 0 and the Z bit is set
4878              * we could test Z now, or go ahead and check the high order bytes if
4879              * the variable we're comparing is larger than a byte. */
4880
4881             while(--size)
4882               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4883
4884             if ( IC_TRUE(ifx) ) {
4885               emitSKPNZ;
4886               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4887               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4888             } else {
4889               emitSKPZ;
4890               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4891               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4892             }
4893
4894           } else {
4895             /* They're both variables that are larger than bits */
4896             int s = size;
4897
4898             tlbl = newiTempLabel(NULL);
4899
4900             while(size--) {
4901               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4902               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4903
4904               if ( IC_TRUE(ifx) ) {
4905                 if(size) {
4906                   emitSKPZ;
4907                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4908                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4909                 } else {
4910                   emitSKPNZ;
4911                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4912                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4913                 }
4914               } else {
4915                 emitSKPZ;
4916                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4917                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4918               }
4919               offset++;
4920             }
4921             if(s>1 && IC_TRUE(ifx)) {
4922               emitpLabel(tlbl->key);
4923               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4924             }
4925           }
4926         }
4927         /* mark the icode as generated */
4928         ifx->generated = 1;
4929         goto release ;
4930     }
4931
4932     /* if they are both bit variables */
4933     if (AOP_TYPE(left) == AOP_CRY &&
4934         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4935         if(AOP_TYPE(right) == AOP_LIT){
4936             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4937             if(lit == 0L){
4938                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4939                 pic14_emitcode("cpl","c");
4940             } else if(lit == 1L) {
4941                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4942             } else {
4943                 pic14_emitcode("clr","c");
4944             }
4945             /* AOP_TYPE(right) == AOP_CRY */
4946         } else {
4947             symbol *lbl = newiTempLabel(NULL);
4948             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4949             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4950             pic14_emitcode("cpl","c");
4951             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4952         }
4953         /* c = 1 if egal */
4954         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4955             pic14_outBitC(result);
4956             goto release ;
4957         }
4958         if (ifx) {
4959             genIfxJump (ifx,"c");
4960             goto release ;
4961         }
4962         /* if the result is used in an arithmetic operation
4963         then put the result in place */
4964         pic14_outBitC(result);
4965     } else {
4966       
4967       gencjne(left,right,result,ifx);
4968 /*
4969       if(ifx) 
4970         gencjne(left,right,newiTempLabel(NULL));
4971       else {
4972         if(IC_TRUE(ifx)->key)
4973           gencjne(left,right,IC_TRUE(ifx)->key);
4974         else
4975           gencjne(left,right,IC_FALSE(ifx)->key);
4976         ifx->generated = 1;
4977         goto release ;
4978       }
4979       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4980         aopPut(AOP(result),"a",0);
4981         goto release ;
4982       }
4983
4984       if (ifx) {
4985         genIfxJump (ifx,"a");
4986         goto release ;
4987       }
4988 */
4989       /* if the result is used in an arithmetic operation
4990          then put the result in place */
4991 /*
4992       if (AOP_TYPE(result) != AOP_CRY) 
4993         pic14_outAcc(result);
4994 */
4995       /* leave the result in acc */
4996     }
4997
4998 release:
4999     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5000     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5001     freeAsmop(result,NULL,ic,TRUE);
5002 }
5003
5004 /*-----------------------------------------------------------------*/
5005 /* ifxForOp - returns the icode containing the ifx for operand     */
5006 /*-----------------------------------------------------------------*/
5007 static iCode *ifxForOp ( operand *op, iCode *ic )
5008 {
5009     /* if true symbol then needs to be assigned */
5010     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5011     if (IS_TRUE_SYMOP(op))
5012         return NULL ;
5013
5014     /* if this has register type condition and
5015     the next instruction is ifx with the same operand
5016     and live to of the operand is upto the ifx only then */
5017     if (ic->next &&
5018         ic->next->op == IFX &&
5019         IC_COND(ic->next)->key == op->key &&
5020         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5021         return ic->next;
5022
5023     if (ic->next &&
5024         ic->next->op == IFX &&
5025         IC_COND(ic->next)->key == op->key) {
5026       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5027       return ic->next;
5028     }
5029
5030     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5031     if (ic->next &&
5032         ic->next->op == IFX)
5033       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5034
5035     if (ic->next &&
5036         ic->next->op == IFX &&
5037         IC_COND(ic->next)->key == op->key) {
5038       DEBUGpic14_emitcode ("; "," key is okay");
5039       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5040                            OP_SYMBOL(op)->liveTo,
5041                            ic->next->seq);
5042     }
5043
5044
5045     return NULL;
5046 }
5047 /*-----------------------------------------------------------------*/
5048 /* genAndOp - for && operation                                     */
5049 /*-----------------------------------------------------------------*/
5050 static void genAndOp (iCode *ic)
5051 {
5052     operand *left,*right, *result;
5053     symbol *tlbl;
5054
5055     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5056     /* note here that && operations that are in an
5057     if statement are taken away by backPatchLabels
5058     only those used in arthmetic operations remain */
5059     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5060     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5061     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5062
5063     /* if both are bit variables */
5064     if (AOP_TYPE(left) == AOP_CRY &&
5065         AOP_TYPE(right) == AOP_CRY ) {
5066         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5067         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5068         pic14_outBitC(result);
5069     } else {
5070         tlbl = newiTempLabel(NULL);
5071         pic14_toBoolean(left);    
5072         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5073         pic14_toBoolean(right);
5074         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5075         pic14_outBitAcc(result);
5076     }
5077
5078     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5079     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080     freeAsmop(result,NULL,ic,TRUE);
5081 }
5082
5083
5084 /*-----------------------------------------------------------------*/
5085 /* genOrOp - for || operation                                      */
5086 /*-----------------------------------------------------------------*/
5087 /*
5088   tsd pic port -
5089   modified this code, but it doesn't appear to ever get called
5090 */
5091
5092 static void genOrOp (iCode *ic)
5093 {
5094     operand *left,*right, *result;
5095     symbol *tlbl;
5096
5097     /* note here that || operations that are in an
5098     if statement are taken away by backPatchLabels
5099     only those used in arthmetic operations remain */
5100     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5101     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5102     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5103     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5104
5105     DEBUGpic14_AopType(__LINE__,left,right,result);
5106
5107     /* if both are bit variables */
5108     if (AOP_TYPE(left) == AOP_CRY &&
5109         AOP_TYPE(right) == AOP_CRY ) {
5110       pic14_emitcode("clrc","");
5111       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5112                AOP(left)->aopu.aop_dir,
5113                AOP(left)->aopu.aop_dir);
5114       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5115                AOP(right)->aopu.aop_dir,
5116                AOP(right)->aopu.aop_dir);
5117       pic14_emitcode("setc","");
5118
5119     } else {
5120         tlbl = newiTempLabel(NULL);
5121         pic14_toBoolean(left);
5122         emitSKPZ;
5123         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5124         pic14_toBoolean(right);
5125         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5126
5127         pic14_outBitAcc(result);
5128     }
5129
5130     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5131     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5132     freeAsmop(result,NULL,ic,TRUE);            
5133 }
5134
5135 /*-----------------------------------------------------------------*/
5136 /* isLiteralBit - test if lit == 2^n                               */
5137 /*-----------------------------------------------------------------*/
5138 static int isLiteralBit(unsigned long lit)
5139 {
5140     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5141     0x100L,0x200L,0x400L,0x800L,
5142     0x1000L,0x2000L,0x4000L,0x8000L,
5143     0x10000L,0x20000L,0x40000L,0x80000L,
5144     0x100000L,0x200000L,0x400000L,0x800000L,
5145     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5146     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5147     int idx;
5148     
5149     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5150     for(idx = 0; idx < 32; idx++)
5151         if(lit == pw[idx])
5152             return idx+1;
5153     return 0;
5154 }
5155
5156 /*-----------------------------------------------------------------*/
5157 /* continueIfTrue -                                                */
5158 /*-----------------------------------------------------------------*/
5159 static void continueIfTrue (iCode *ic)
5160 {
5161     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5162     if(IC_TRUE(ic))
5163         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5164     ic->generated = 1;
5165 }
5166
5167 /*-----------------------------------------------------------------*/
5168 /* jmpIfTrue -                                                     */
5169 /*-----------------------------------------------------------------*/
5170 static void jumpIfTrue (iCode *ic)
5171 {
5172     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5173     if(!IC_TRUE(ic))
5174         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5175     ic->generated = 1;
5176 }
5177
5178 /*-----------------------------------------------------------------*/
5179 /* jmpTrueOrFalse -                                                */
5180 /*-----------------------------------------------------------------*/
5181 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5182 {
5183     // ugly but optimized by peephole
5184     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5185     if(IC_TRUE(ic)){
5186         symbol *nlbl = newiTempLabel(NULL);
5187         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5188         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5189         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5190         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5191     }
5192     else{
5193         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5194         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5195     }
5196     ic->generated = 1;
5197 }
5198
5199 /*-----------------------------------------------------------------*/
5200 /* genAnd  - code for and                                          */
5201 /*-----------------------------------------------------------------*/
5202 static void genAnd (iCode *ic, iCode *ifx)
5203 {
5204   operand *left, *right, *result;
5205   int size, offset=0;  
5206   unsigned long lit = 0L;
5207   int bytelit = 0;
5208   resolvedIfx rIfx;
5209
5210
5211   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5212   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5213   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5214   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5215
5216   resolveIfx(&rIfx,ifx);
5217
5218   /* if left is a literal & right is not then exchange them */
5219   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5220       AOP_NEEDSACC(left)) {
5221     operand *tmp = right ;
5222     right = left;
5223     left = tmp;
5224   }
5225
5226   /* if result = right then exchange them */
5227   if(pic14_sameRegs(AOP(result),AOP(right))){
5228     operand *tmp = right ;
5229     right = left;
5230     left = tmp;
5231   }
5232
5233   /* if right is bit then exchange them */
5234   if (AOP_TYPE(right) == AOP_CRY &&
5235       AOP_TYPE(left) != AOP_CRY){
5236     operand *tmp = right ;
5237     right = left;
5238     left = tmp;
5239   }
5240   if(AOP_TYPE(right) == AOP_LIT)
5241     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5242
5243   size = AOP_SIZE(result);
5244
5245   DEBUGpic14_AopType(__LINE__,left,right,result);
5246
5247   // if(bit & yy)
5248   // result = bit & yy;
5249   if (AOP_TYPE(left) == AOP_CRY){
5250     // c = bit & literal;
5251     if(AOP_TYPE(right) == AOP_LIT){
5252       if(lit & 1) {
5253         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5254           // no change
5255           goto release;
5256         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5257       } else {
5258         // bit(result) = 0;
5259         if(size && (AOP_TYPE(result) == AOP_CRY)){
5260           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5261           goto release;
5262         }
5263         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5264           jumpIfTrue(ifx);
5265           goto release;
5266         }
5267         pic14_emitcode("clr","c");
5268       }
5269     } else {
5270       if (AOP_TYPE(right) == AOP_CRY){
5271         // c = bit & bit;
5272         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5273         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5274       } else {
5275         // c = bit & val;
5276         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5277         // c = lsb
5278         pic14_emitcode("rrc","a");
5279         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5280       }
5281     }
5282     // bit = c
5283     // val = c
5284     if(size)
5285       pic14_outBitC(result);
5286     // if(bit & ...)
5287     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5288       genIfxJump(ifx, "c");           
5289     goto release ;
5290   }
5291
5292   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5293   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5294   if((AOP_TYPE(right) == AOP_LIT) &&
5295      (AOP_TYPE(result) == AOP_CRY) &&
5296      (AOP_TYPE(left) != AOP_CRY)){
5297     int posbit = isLiteralBit(lit);
5298     /* left &  2^n */
5299     if(posbit){
5300       posbit--;
5301       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5302       // bit = left & 2^n
5303       if(size)
5304         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5305       // if(left &  2^n)
5306       else{
5307         if(ifx){
5308 /*
5309           if(IC_TRUE(ifx)) {
5310             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5311             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5312           } else {
5313             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5314             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5315           }
5316 */
5317           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5318                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5319           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5320           
5321           ifx->generated = 1;
5322         }
5323         goto release;
5324       }
5325     } else {
5326       symbol *tlbl = newiTempLabel(NULL);
5327       int sizel = AOP_SIZE(left);
5328       if(size)
5329         pic14_emitcode("setb","c");
5330       while(sizel--){
5331         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5332           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5333           // byte ==  2^n ?
5334           if((posbit = isLiteralBit(bytelit)) != 0)
5335             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5336           else{
5337             if(bytelit != 0x0FFL)
5338               pic14_emitcode("anl","a,%s",
5339                              aopGet(AOP(right),offset,FALSE,TRUE));
5340             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5341           }
5342         }
5343         offset++;
5344       }
5345       // bit = left & literal
5346       if(size){
5347         pic14_emitcode("clr","c");
5348         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5349       }
5350       // if(left & literal)
5351       else{
5352         if(ifx)
5353           jmpTrueOrFalse(ifx, tlbl);
5354         goto release ;
5355       }
5356     }
5357     pic14_outBitC(result);
5358     goto release ;
5359   }
5360
5361   /* if left is same as result */
5362   if(pic14_sameRegs(AOP(result),AOP(left))){
5363     int know_W = -1;
5364     for(;size--; offset++,lit>>=8) {
5365       if(AOP_TYPE(right) == AOP_LIT){
5366         switch(lit & 0xff) {
5367         case 0x00:
5368           /*  and'ing with 0 has clears the result */
5369           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5370           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5371           break;
5372         case 0xff:
5373           /* and'ing with 0xff is a nop when the result and left are the same */
5374           break;
5375
5376         default:
5377           {
5378             int p = my_powof2( (~lit) & 0xff );
5379             if(p>=0) {
5380               /* only one bit is set in the literal, so use a bcf instruction */
5381               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5382               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5383
5384             } else {
5385               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5386               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5387               if(know_W != (lit&0xff))
5388                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5389               know_W = lit &0xff;
5390               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5391             }
5392           }    
5393         }
5394       } else {
5395         if (AOP_TYPE(left) == AOP_ACC) {
5396           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5397         } else {                    
5398           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5399           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5400
5401         }
5402       }
5403     }
5404
5405   } else {
5406     // left & result in different registers
5407     if(AOP_TYPE(result) == AOP_CRY){
5408       // result = bit
5409       // if(size), result in bit
5410       // if(!size && ifx), conditional oper: if(left & right)
5411       symbol *tlbl = newiTempLabel(NULL);
5412       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5413       if(size)
5414         pic14_emitcode("setb","c");
5415       while(sizer--){
5416         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5417         pic14_emitcode("anl","a,%s",
5418                        aopGet(AOP(left),offset,FALSE,FALSE));
5419         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5420         offset++;
5421       }
5422       if(size){
5423         CLRC;
5424         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5425         pic14_outBitC(result);
5426       } else if(ifx)
5427         jmpTrueOrFalse(ifx, tlbl);
5428     } else {
5429       for(;(size--);offset++) {
5430         // normal case
5431         // result = left & right
5432         if(AOP_TYPE(right) == AOP_LIT){
5433           int t = (lit >> (offset*8)) & 0x0FFL;
5434           switch(t) { 
5435           case 0x00:
5436             pic14_emitcode("clrf","%s",
5437                            aopGet(AOP(result),offset,FALSE,FALSE));
5438             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5439             break;
5440           case 0xff:
5441             pic14_emitcode("movf","%s,w",
5442                            aopGet(AOP(left),offset,FALSE,FALSE));
5443             pic14_emitcode("movwf","%s",
5444                            aopGet(AOP(result),offset,FALSE,FALSE));
5445             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5446             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5447             break;
5448           default:
5449             pic14_emitcode("movlw","0x%x",t);
5450             pic14_emitcode("andwf","%s,w",
5451                            aopGet(AOP(left),offset,FALSE,FALSE));
5452             pic14_emitcode("movwf","%s",
5453                            aopGet(AOP(result),offset,FALSE,FALSE));
5454               
5455             emitpcode(POC_MOVLW, popGetLit(t));
5456             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5457             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5458           }
5459           continue;
5460         }
5461
5462         if (AOP_TYPE(left) == AOP_ACC) {
5463           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5464           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5465         } else {
5466           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5467           pic14_emitcode("andwf","%s,w",
5468                          aopGet(AOP(left),offset,FALSE,FALSE));
5469           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5470           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5471         }
5472         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5473         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5474       }
5475     }
5476   }
5477
5478   release :
5479     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5480   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5481   freeAsmop(result,NULL,ic,TRUE);     
5482 }
5483
5484 /*-----------------------------------------------------------------*/
5485 /* genOr  - code for or                                            */
5486 /*-----------------------------------------------------------------*/
5487 static void genOr (iCode *ic, iCode *ifx)
5488 {
5489     operand *left, *right, *result;
5490     int size, offset=0;
5491     unsigned long lit = 0L;
5492
5493     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5494
5495     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5496     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5497     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5498
5499     DEBUGpic14_AopType(__LINE__,left,right,result);
5500
5501     /* if left is a literal & right is not then exchange them */
5502     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5503         AOP_NEEDSACC(left)) {
5504         operand *tmp = right ;
5505         right = left;
5506         left = tmp;
5507     }
5508
5509     /* if result = right then exchange them */
5510     if(pic14_sameRegs(AOP(result),AOP(right))){
5511         operand *tmp = right ;
5512         right = left;
5513         left = tmp;
5514     }
5515
5516     /* if right is bit then exchange them */
5517     if (AOP_TYPE(right) == AOP_CRY &&
5518         AOP_TYPE(left) != AOP_CRY){
5519         operand *tmp = right ;
5520         right = left;
5521         left = tmp;
5522     }
5523
5524     DEBUGpic14_AopType(__LINE__,left,right,result);
5525
5526     if(AOP_TYPE(right) == AOP_LIT)
5527         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5528
5529     size = AOP_SIZE(result);
5530
5531     // if(bit | yy)
5532     // xx = bit | yy;
5533     if (AOP_TYPE(left) == AOP_CRY){
5534         if(AOP_TYPE(right) == AOP_LIT){
5535             // c = bit & literal;
5536             if(lit){
5537                 // lit != 0 => result = 1
5538                 if(AOP_TYPE(result) == AOP_CRY){
5539                   if(size)
5540                     emitpcode(POC_BSF, popGet(AOP(result),0));
5541                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5542                   //     AOP(result)->aopu.aop_dir,
5543                   //     AOP(result)->aopu.aop_dir);
5544                     else if(ifx)
5545                         continueIfTrue(ifx);
5546                     goto release;
5547                 }
5548             } else {
5549                 // lit == 0 => result = left
5550                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5551                     goto release;
5552                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5553             }
5554         } else {
5555             if (AOP_TYPE(right) == AOP_CRY){
5556               if(pic14_sameRegs(AOP(result),AOP(left))){
5557                 // c = bit | bit;
5558                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5559                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5560                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5561
5562                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5563                          AOP(result)->aopu.aop_dir,
5564                          AOP(result)->aopu.aop_dir);
5565                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5566                          AOP(right)->aopu.aop_dir,
5567                          AOP(right)->aopu.aop_dir);
5568                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5569                          AOP(result)->aopu.aop_dir,
5570                          AOP(result)->aopu.aop_dir);
5571               } else {
5572                 if( AOP_TYPE(result) == AOP_ACC) {
5573                   emitpcode(POC_MOVLW, popGetLit(0));
5574                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5575                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5576                   emitpcode(POC_MOVLW, popGetLit(1));
5577
5578                 } else {
5579
5580                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5581                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5582                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5583                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5584
5585                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5586                                  AOP(result)->aopu.aop_dir,
5587                                  AOP(result)->aopu.aop_dir);
5588                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5589                                  AOP(right)->aopu.aop_dir,
5590                                  AOP(right)->aopu.aop_dir);
5591                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5592                                  AOP(left)->aopu.aop_dir,
5593                                  AOP(left)->aopu.aop_dir);
5594                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5595                                  AOP(result)->aopu.aop_dir,
5596                                  AOP(result)->aopu.aop_dir);
5597                 }
5598               }
5599             } else {
5600                 // c = bit | val;
5601                 symbol *tlbl = newiTempLabel(NULL);
5602                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5603
5604
5605                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5606                 if( AOP_TYPE(right) == AOP_ACC) {
5607                   emitpcode(POC_IORLW, popGetLit(0));
5608                   emitSKPNZ;
5609                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5610                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5611                 }
5612
5613
5614
5615                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5616                     pic14_emitcode(";XXX setb","c");
5617                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5618                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5619                 pic14_toBoolean(right);
5620                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5621                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5622                     jmpTrueOrFalse(ifx, tlbl);
5623                     goto release;
5624                 } else {
5625                     CLRC;
5626                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5627                 }
5628             }
5629         }
5630         // bit = c
5631         // val = c
5632         if(size)
5633             pic14_outBitC(result);
5634         // if(bit | ...)
5635         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5636             genIfxJump(ifx, "c");           
5637         goto release ;
5638     }
5639
5640     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5641     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5642     if((AOP_TYPE(right) == AOP_LIT) &&
5643        (AOP_TYPE(result) == AOP_CRY) &&
5644        (AOP_TYPE(left) != AOP_CRY)){
5645         if(lit){
5646           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5647             // result = 1
5648             if(size)
5649                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5650             else 
5651                 continueIfTrue(ifx);
5652             goto release;
5653         } else {
5654           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5655             // lit = 0, result = boolean(left)
5656             if(size)
5657                 pic14_emitcode(";XXX setb","c");
5658             pic14_toBoolean(right);
5659             if(size){
5660                 symbol *tlbl = newiTempLabel(NULL);
5661                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5662                 CLRC;
5663                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5664             } else {
5665                 genIfxJump (ifx,"a");
5666                 goto release;
5667             }
5668         }
5669         pic14_outBitC(result);
5670         goto release ;
5671     }
5672
5673     /* if left is same as result */
5674     if(pic14_sameRegs(AOP(result),AOP(left))){
5675       int know_W = -1;
5676       for(;size--; offset++,lit>>=8) {
5677         if(AOP_TYPE(right) == AOP_LIT){
5678           if((lit & 0xff) == 0)
5679             /*  or'ing with 0 has no effect */
5680             continue;
5681           else {
5682             int p = my_powof2(lit & 0xff);
5683             if(p>=0) {
5684               /* only one bit is set in the literal, so use a bsf instruction */
5685               emitpcode(POC_BSF,
5686                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5687             } else {
5688               if(know_W != (lit & 0xff))
5689                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5690               know_W = lit & 0xff;
5691               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5692             }
5693                     
5694           }
5695         } else {
5696           if (AOP_TYPE(left) == AOP_ACC) {
5697             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5698             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5699           } else {                  
5700             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5701             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5702
5703             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5704             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5705
5706           }
5707         }
5708       }
5709     } else {
5710         // left & result in different registers
5711         if(AOP_TYPE(result) == AOP_CRY){
5712             // result = bit
5713             // if(size), result in bit
5714             // if(!size && ifx), conditional oper: if(left | right)
5715             symbol *tlbl = newiTempLabel(NULL);
5716             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5717             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5718
5719
5720             if(size)
5721                 pic14_emitcode(";XXX setb","c");
5722             while(sizer--){
5723                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5724                 pic14_emitcode(";XXX orl","a,%s",
5725                          aopGet(AOP(left),offset,FALSE,FALSE));
5726                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5727                 offset++;
5728             }
5729             if(size){
5730                 CLRC;
5731                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5732                 pic14_outBitC(result);
5733             } else if(ifx)
5734                 jmpTrueOrFalse(ifx, tlbl);
5735         } else for(;(size--);offset++){
5736           // normal case
5737           // result = left & right
5738           if(AOP_TYPE(right) == AOP_LIT){
5739             int t = (lit >> (offset*8)) & 0x0FFL;
5740             switch(t) { 
5741             case 0x00:
5742               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5743               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5744
5745               pic14_emitcode("movf","%s,w",
5746                        aopGet(AOP(left),offset,FALSE,FALSE));
5747               pic14_emitcode("movwf","%s",
5748                        aopGet(AOP(result),offset,FALSE,FALSE));
5749               break;
5750             default:
5751               emitpcode(POC_MOVLW,  popGetLit(t));
5752               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5753               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5754
5755               pic14_emitcode("movlw","0x%x",t);
5756               pic14_emitcode("iorwf","%s,w",
5757                        aopGet(AOP(left),offset,FALSE,FALSE));
5758               pic14_emitcode("movwf","%s",
5759                        aopGet(AOP(result),offset,FALSE,FALSE));
5760               
5761             }
5762             continue;
5763           }
5764
5765           // faster than result <- left, anl result,right
5766           // and better if result is SFR
5767           if (AOP_TYPE(left) == AOP_ACC) {
5768             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5769             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5770           } else {
5771             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5772             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5773
5774             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5775             pic14_emitcode("iorwf","%s,w",
5776                      aopGet(AOP(left),offset,FALSE,FALSE));
5777           }
5778           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5779           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5780         }
5781     }
5782
5783 release :
5784     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5785     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5786     freeAsmop(result,NULL,ic,TRUE);     
5787 }
5788
5789 /*-----------------------------------------------------------------*/
5790 /* genXor - code for xclusive or                                   */
5791 /*-----------------------------------------------------------------*/
5792 static void genXor (iCode *ic, iCode *ifx)
5793 {
5794   operand *left, *right, *result;
5795   int size, offset=0;
5796   unsigned long lit = 0L;
5797
5798   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5799
5800   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5801   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5802   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5803
5804   /* if left is a literal & right is not ||
5805      if left needs acc & right does not */
5806   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5807       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5808     operand *tmp = right ;
5809     right = left;
5810     left = tmp;
5811   }
5812
5813   /* if result = right then exchange them */
5814   if(pic14_sameRegs(AOP(result),AOP(right))){
5815     operand *tmp = right ;
5816     right = left;
5817     left = tmp;
5818   }
5819
5820   /* if right is bit then exchange them */
5821   if (AOP_TYPE(right) == AOP_CRY &&
5822       AOP_TYPE(left) != AOP_CRY){
5823     operand *tmp = right ;
5824     right = left;
5825     left = tmp;
5826   }
5827   if(AOP_TYPE(right) == AOP_LIT)
5828     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5829
5830   size = AOP_SIZE(result);
5831
5832   // if(bit ^ yy)
5833   // xx = bit ^ yy;
5834   if (AOP_TYPE(left) == AOP_CRY){
5835     if(AOP_TYPE(right) == AOP_LIT){
5836       // c = bit & literal;
5837       if(lit>>1){
5838         // lit>>1  != 0 => result = 1
5839         if(AOP_TYPE(result) == AOP_CRY){
5840           if(size)
5841             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5842             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5843           else if(ifx)
5844             continueIfTrue(ifx);
5845           goto release;
5846         }
5847         pic14_emitcode("setb","c");
5848       } else{
5849         // lit == (0 or 1)
5850         if(lit == 0){
5851           // lit == 0, result = left
5852           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5853             goto release;
5854           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5855         } else{
5856           // lit == 1, result = not(left)
5857           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5858             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5859             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5860             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5861             goto release;
5862           } else {
5863             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5864             pic14_emitcode("cpl","c");
5865           }
5866         }
5867       }
5868
5869     } else {
5870       // right != literal
5871       symbol *tlbl = newiTempLabel(NULL);
5872       if (AOP_TYPE(right) == AOP_CRY){
5873         // c = bit ^ bit;
5874         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5875       }
5876       else{
5877         int sizer = AOP_SIZE(right);
5878         // c = bit ^ val
5879         // if val>>1 != 0, result = 1
5880         pic14_emitcode("setb","c");
5881         while(sizer){
5882           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5883           if(sizer == 1)
5884             // test the msb of the lsb
5885             pic14_emitcode("anl","a,#0xfe");
5886           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5887           sizer--;
5888         }
5889         // val = (0,1)
5890         pic14_emitcode("rrc","a");
5891       }
5892       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5893       pic14_emitcode("cpl","c");
5894       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5895     }
5896     // bit = c
5897     // val = c
5898     if(size)
5899       pic14_outBitC(result);
5900     // if(bit | ...)
5901     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5902       genIfxJump(ifx, "c");           
5903     goto release ;
5904   }
5905
5906   if(pic14_sameRegs(AOP(result),AOP(left))){
5907     /* if left is same as result */
5908     for(;size--; offset++) {
5909       if(AOP_TYPE(right) == AOP_LIT){
5910         int t  = (lit >> (offset*8)) & 0x0FFL;
5911         if(t == 0x00L)
5912           continue;
5913         else
5914           if (IS_AOP_PREG(left)) {
5915             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5916             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5917             aopPut(AOP(result),"a",offset);
5918           } else {
5919             emitpcode(POC_MOVLW, popGetLit(t));
5920             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5921             pic14_emitcode("xrl","%s,%s",
5922                            aopGet(AOP(left),offset,FALSE,TRUE),
5923                            aopGet(AOP(right),offset,FALSE,FALSE));
5924           }
5925       } else {
5926         if (AOP_TYPE(left) == AOP_ACC)
5927           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5928         else {
5929           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5930           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5931 /*
5932           if (IS_AOP_PREG(left)) {
5933             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5934             aopPut(AOP(result),"a",offset);
5935           } else
5936             pic14_emitcode("xrl","%s,a",
5937                            aopGet(AOP(left),offset,FALSE,TRUE));
5938 */
5939         }
5940       }
5941     }
5942   } else {
5943     // left & result in different registers
5944     if(AOP_TYPE(result) == AOP_CRY){
5945       // result = bit
5946       // if(size), result in bit
5947       // if(!size && ifx), conditional oper: if(left ^ right)
5948       symbol *tlbl = newiTempLabel(NULL);
5949       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5950       if(size)
5951         pic14_emitcode("setb","c");
5952       while(sizer--){
5953         if((AOP_TYPE(right) == AOP_LIT) &&
5954            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5955           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5956         } else {
5957           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5958           pic14_emitcode("xrl","a,%s",
5959                          aopGet(AOP(left),offset,FALSE,FALSE));
5960         }
5961         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5962         offset++;
5963       }
5964       if(size){
5965         CLRC;
5966         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5967         pic14_outBitC(result);
5968       } else if(ifx)
5969         jmpTrueOrFalse(ifx, tlbl);
5970     } else for(;(size--);offset++){
5971       // normal case
5972       // result = left & right
5973       if(AOP_TYPE(right) == AOP_LIT){
5974         int t = (lit >> (offset*8)) & 0x0FFL;
5975         switch(t) { 
5976         case 0x00:
5977           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5978           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5979           pic14_emitcode("movf","%s,w",
5980                          aopGet(AOP(left),offset,FALSE,FALSE));
5981           pic14_emitcode("movwf","%s",
5982                          aopGet(AOP(result),offset,FALSE,FALSE));
5983           break;
5984         case 0xff:
5985           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5986           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5987           pic14_emitcode("comf","%s,w",
5988                          aopGet(AOP(left),offset,FALSE,FALSE));
5989           pic14_emitcode("movwf","%s",
5990                          aopGet(AOP(result),offset,FALSE,FALSE));
5991           break;
5992         default:
5993           emitpcode(POC_MOVLW, popGetLit(t));
5994           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5995           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5996           pic14_emitcode("movlw","0x%x",t);
5997           pic14_emitcode("xorwf","%s,w",
5998                          aopGet(AOP(left),offset,FALSE,FALSE));
5999           pic14_emitcode("movwf","%s",
6000                          aopGet(AOP(result),offset,FALSE,FALSE));
6001
6002         }
6003         continue;
6004       }
6005
6006       // faster than result <- left, anl result,right
6007       // and better if result is SFR
6008       if (AOP_TYPE(left) == AOP_ACC) {
6009         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6010         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6011       } else {
6012         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6013         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6014         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6015         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6016       }
6017       if ( AOP_TYPE(result) != AOP_ACC){
6018         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6019         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6020       }
6021     }
6022   }
6023
6024   release :
6025     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6026   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6027   freeAsmop(result,NULL,ic,TRUE);     
6028 }
6029
6030 /*-----------------------------------------------------------------*/
6031 /* genInline - write the inline code out                           */
6032 /*-----------------------------------------------------------------*/
6033 static void genInline (iCode *ic)
6034 {
6035     char *buffer, *bp, *bp1;
6036     
6037     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6038
6039     _G.inLine += (!options.asmpeep);
6040
6041     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6042     strcpy(buffer,IC_INLINE(ic));
6043
6044     /* emit each line as a code */
6045     while (*bp) {
6046         if (*bp == '\n') {
6047             *bp++ = '\0';
6048
6049             if(*bp1)
6050               addpCode2pBlock(pb,AssembleLine(bp1));
6051             bp1 = bp;
6052         } else {
6053             if (*bp == ':') {
6054                 bp++;
6055                 *bp = '\0';
6056                 bp++;
6057                 pic14_emitcode(bp1,"");
6058                 bp1 = bp;
6059             } else
6060                 bp++;
6061         }
6062     }
6063     if ((bp1 != bp) && *bp1)
6064       addpCode2pBlock(pb,AssembleLine(bp1));
6065
6066     Safe_free(buffer);
6067
6068     _G.inLine -= (!options.asmpeep);
6069 }
6070
6071 /*-----------------------------------------------------------------*/
6072 /* genRRC - rotate right with carry                                */
6073 /*-----------------------------------------------------------------*/
6074 static void genRRC (iCode *ic)
6075 {
6076   operand *left , *result ;
6077   int size, offset = 0, same;
6078
6079   /* rotate right with carry */
6080   left = IC_LEFT(ic);
6081   result=IC_RESULT(ic);
6082   aopOp (left,ic,FALSE);
6083   aopOp (result,ic,FALSE);
6084
6085   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6086
6087   same = pic14_sameRegs(AOP(result),AOP(left));
6088
6089   size = AOP_SIZE(result);    
6090
6091   /* get the lsb and put it into the carry */
6092   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6093
6094   offset = 0 ;
6095
6096   while(size--) {
6097
6098     if(same) {
6099       emitpcode(POC_RRF, popGet(AOP(left),offset));
6100     } else {
6101       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6102       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6103     }
6104
6105     offset++;
6106   }
6107
6108   freeAsmop(left,NULL,ic,TRUE);
6109   freeAsmop(result,NULL,ic,TRUE);
6110 }
6111
6112 /*-----------------------------------------------------------------*/
6113 /* genRLC - generate code for rotate left with carry               */
6114 /*-----------------------------------------------------------------*/
6115 static void genRLC (iCode *ic)
6116 {    
6117   operand *left , *result ;
6118   int size, offset = 0;
6119   int same;
6120
6121   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6122   /* rotate right with carry */
6123   left = IC_LEFT(ic);
6124   result=IC_RESULT(ic);
6125   aopOp (left,ic,FALSE);
6126   aopOp (result,ic,FALSE);
6127
6128   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6129
6130   same = pic14_sameRegs(AOP(result),AOP(left));
6131
6132   /* move it to the result */
6133   size = AOP_SIZE(result);    
6134
6135   /* get the msb and put it into the carry */
6136   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6137
6138   offset = 0 ;
6139
6140   while(size--) {
6141
6142     if(same) {
6143       emitpcode(POC_RLF, popGet(AOP(left),offset));
6144     } else {
6145       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6146       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6147     }
6148
6149     offset++;
6150   }
6151
6152
6153   freeAsmop(left,NULL,ic,TRUE);
6154   freeAsmop(result,NULL,ic,TRUE);
6155 }
6156
6157 /*-----------------------------------------------------------------*/
6158 /* genGetHbit - generates code get highest order bit               */
6159 /*-----------------------------------------------------------------*/
6160 static void genGetHbit (iCode *ic)
6161 {
6162     operand *left, *result;
6163     left = IC_LEFT(ic);
6164     result=IC_RESULT(ic);
6165     aopOp (left,ic,FALSE);
6166     aopOp (result,ic,FALSE);
6167
6168     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6169     /* get the highest order byte into a */
6170     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6171     if(AOP_TYPE(result) == AOP_CRY){
6172         pic14_emitcode("rlc","a");
6173         pic14_outBitC(result);
6174     }
6175     else{
6176         pic14_emitcode("rl","a");
6177         pic14_emitcode("anl","a,#0x01");
6178         pic14_outAcc(result);
6179     }
6180
6181
6182     freeAsmop(left,NULL,ic,TRUE);
6183     freeAsmop(result,NULL,ic,TRUE);
6184 }
6185
6186 /*-----------------------------------------------------------------*/
6187 /* AccRol - rotate left accumulator by known count                 */
6188 /*-----------------------------------------------------------------*/
6189 static void AccRol (int shCount)
6190 {
6191     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6192     shCount &= 0x0007;              // shCount : 0..7
6193     switch(shCount){
6194         case 0 :
6195             break;
6196         case 1 :
6197             pic14_emitcode("rl","a");
6198             break;
6199         case 2 :
6200             pic14_emitcode("rl","a");
6201             pic14_emitcode("rl","a");
6202             break;
6203         case 3 :
6204             pic14_emitcode("swap","a");
6205             pic14_emitcode("rr","a");
6206             break;
6207         case 4 :
6208             pic14_emitcode("swap","a");
6209             break;
6210         case 5 :
6211             pic14_emitcode("swap","a");
6212             pic14_emitcode("rl","a");
6213             break;
6214         case 6 :
6215             pic14_emitcode("rr","a");
6216             pic14_emitcode("rr","a");
6217             break;
6218         case 7 :
6219             pic14_emitcode("rr","a");
6220             break;
6221     }
6222 }
6223
6224 /*-----------------------------------------------------------------*/
6225 /* AccLsh - left shift accumulator by known count                  */
6226 /*-----------------------------------------------------------------*/
6227 static void AccLsh (int shCount)
6228 {
6229     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6230     if(shCount != 0){
6231         if(shCount == 1)
6232             pic14_emitcode("add","a,acc");
6233         else 
6234             if(shCount == 2) {
6235             pic14_emitcode("add","a,acc");
6236             pic14_emitcode("add","a,acc");
6237         } else {
6238             /* rotate left accumulator */
6239             AccRol(shCount);
6240             /* and kill the lower order bits */
6241             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6242         }
6243     }
6244 }
6245
6246 /*-----------------------------------------------------------------*/
6247 /* AccRsh - right shift accumulator by known count                 */
6248 /*-----------------------------------------------------------------*/
6249 static void AccRsh (int shCount)
6250 {
6251     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6252     if(shCount != 0){
6253         if(shCount == 1){
6254             CLRC;
6255             pic14_emitcode("rrc","a");
6256         } else {
6257             /* rotate right accumulator */
6258             AccRol(8 - shCount);
6259             /* and kill the higher order bits */
6260             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6261         }
6262     }
6263 }
6264
6265 #if 0
6266 /*-----------------------------------------------------------------*/
6267 /* AccSRsh - signed right shift accumulator by known count                 */
6268 /*-----------------------------------------------------------------*/
6269 static void AccSRsh (int shCount)
6270 {
6271     symbol *tlbl ;
6272     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6273     if(shCount != 0){
6274         if(shCount == 1){
6275             pic14_emitcode("mov","c,acc.7");
6276             pic14_emitcode("rrc","a");
6277         } else if(shCount == 2){
6278             pic14_emitcode("mov","c,acc.7");
6279             pic14_emitcode("rrc","a");
6280             pic14_emitcode("mov","c,acc.7");
6281             pic14_emitcode("rrc","a");
6282         } else {
6283             tlbl = newiTempLabel(NULL);
6284             /* rotate right accumulator */
6285             AccRol(8 - shCount);
6286             /* and kill the higher order bits */
6287             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6288             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6289             pic14_emitcode("orl","a,#0x%02x",
6290                      (unsigned char)~SRMask[shCount]);
6291             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6292         }
6293     }
6294 }
6295 #endif
6296 /*-----------------------------------------------------------------*/
6297 /* shiftR1Left2Result - shift right one byte from left to result   */
6298 /*-----------------------------------------------------------------*/
6299 static void shiftR1Left2ResultSigned (operand *left, int offl,
6300                                 operand *result, int offr,
6301                                 int shCount)
6302 {
6303   int same;
6304
6305   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6306
6307   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6308
6309   switch(shCount) {
6310   case 1:
6311     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6312     if(same) 
6313       emitpcode(POC_RRF, popGet(AOP(result),offr));
6314     else {
6315       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6316       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6317     }
6318
6319     break;
6320   case 2:
6321
6322     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6323     if(same) 
6324       emitpcode(POC_RRF, popGet(AOP(result),offr));
6325     else {
6326       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6327       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6328     }
6329     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6330     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6331
6332     break;
6333
6334   case 3:
6335     if(same)
6336       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6337     else {
6338       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6339       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6340     }
6341
6342     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6343     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6344     emitpcode(POC_ANDLW, popGetLit(0x1f));
6345
6346     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6347     emitpcode(POC_IORLW, popGetLit(0xe0));
6348
6349     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6350     break;
6351
6352   case 4:
6353     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6354     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6355     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6356     emitpcode(POC_IORLW,  popGetLit(0xf0));
6357     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6358     break;
6359   case 5:
6360     if(same) {
6361       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6362     } else {
6363       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6364       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6365     }
6366     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6367     emitpcode(POC_ANDLW,  popGetLit(0x07));
6368     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6369     emitpcode(POC_IORLW,  popGetLit(0xf8));
6370     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6371     break;
6372
6373   case 6:
6374     if(same) {
6375       emitpcode(POC_MOVLW, popGetLit(0x00));
6376       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6377       emitpcode(POC_MOVLW, popGetLit(0xfe));
6378       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6379       emitpcode(POC_IORLW, popGetLit(0x01));
6380       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381     } else {
6382       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6383       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6384       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6385       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6386       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6387     }
6388     break;
6389
6390   case 7:
6391     if(same) {
6392       emitpcode(POC_MOVLW, popGetLit(0x00));
6393       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6394       emitpcode(POC_MOVLW, popGetLit(0xff));
6395       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6396     } else {
6397       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6398       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6399       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6400     }
6401
6402   default:
6403     break;
6404   }
6405 }
6406
6407 /*-----------------------------------------------------------------*/
6408 /* shiftR1Left2Result - shift right one byte from left to result   */
6409 /*-----------------------------------------------------------------*/
6410 static void shiftR1Left2Result (operand *left, int offl,
6411                                 operand *result, int offr,
6412                                 int shCount, int sign)
6413 {
6414   int same;
6415
6416   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6417
6418   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6419
6420   /* Copy the msb into the carry if signed. */
6421   if(sign) {
6422     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6423     return;
6424   }
6425
6426
6427
6428   switch(shCount) {
6429   case 1:
6430     emitCLRC;
6431     if(same) 
6432       emitpcode(POC_RRF, popGet(AOP(result),offr));
6433     else {
6434       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6435       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436     }
6437     break;
6438   case 2:
6439     emitCLRC;
6440     if(same) {
6441       emitpcode(POC_RRF, popGet(AOP(result),offr));
6442     } else {
6443       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6444       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445     }
6446     emitCLRC;
6447     emitpcode(POC_RRF, popGet(AOP(result),offr));
6448
6449     break;
6450   case 3:
6451     if(same)
6452       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6453     else {
6454       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6455       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6456     }
6457
6458     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6459     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6460     emitpcode(POC_ANDLW, popGetLit(0x1f));
6461     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6462     break;
6463       
6464   case 4:
6465     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6466     emitpcode(POC_ANDLW, popGetLit(0x0f));
6467     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6468     break;
6469
6470   case 5:
6471     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6472     emitpcode(POC_ANDLW, popGetLit(0x0f));
6473     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6474     emitCLRC;
6475     emitpcode(POC_RRF, popGet(AOP(result),offr));
6476
6477     break;
6478   case 6:
6479
6480     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6481     emitpcode(POC_ANDLW, popGetLit(0x80));
6482     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6484     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6485     break;
6486
6487   case 7:
6488
6489     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6490     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6491     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6492
6493     break;
6494
6495   default:
6496     break;
6497   }
6498 }
6499
6500 /*-----------------------------------------------------------------*/
6501 /* shiftL1Left2Result - shift left one byte from left to result    */
6502 /*-----------------------------------------------------------------*/
6503 static void shiftL1Left2Result (operand *left, int offl,
6504                                 operand *result, int offr, int shCount)
6505 {
6506   int same;
6507
6508   //    char *l;
6509   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6510
6511   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6512   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6513     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6514     //    MOVA(l);
6515     /* shift left accumulator */
6516     //AccLsh(shCount); // don't comment out just yet...
6517   //    aopPut(AOP(result),"a",offr);
6518
6519   switch(shCount) {
6520   case 1:
6521     /* Shift left 1 bit position */
6522     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6523     if(same) {
6524       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6525     } else {
6526       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6527       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6528     }
6529     break;
6530   case 2:
6531     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6532     emitpcode(POC_ANDLW,popGetLit(0x7e));
6533     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6534     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6535     break;
6536   case 3:
6537     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6538     emitpcode(POC_ANDLW,popGetLit(0x3e));
6539     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6540     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6541     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6542     break;
6543   case 4:
6544     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6545     emitpcode(POC_ANDLW, popGetLit(0xf0));
6546     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6547     break;
6548   case 5:
6549     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6550     emitpcode(POC_ANDLW, popGetLit(0xf0));
6551     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6552     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6553     break;
6554   case 6:
6555     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6556     emitpcode(POC_ANDLW, popGetLit(0x30));
6557     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6558     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6559     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6560     break;
6561   case 7:
6562     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6563     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6564     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6565     break;
6566
6567   default:
6568     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6569   }
6570
6571 }
6572
6573 /*-----------------------------------------------------------------*/
6574 /* movLeft2Result - move byte from left to result                  */
6575 /*-----------------------------------------------------------------*/
6576 static void movLeft2Result (operand *left, int offl,
6577                             operand *result, int offr)
6578 {
6579   char *l;
6580   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6581   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6582     l = aopGet(AOP(left),offl,FALSE,FALSE);
6583
6584     if (*l == '@' && (IS_AOP_PREG(result))) {
6585       pic14_emitcode("mov","a,%s",l);
6586       aopPut(AOP(result),"a",offr);
6587     } else {
6588       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6589       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6590     }
6591   }
6592 }
6593
6594 /*-----------------------------------------------------------------*/
6595 /* shiftL2Left2Result - shift left two bytes from left to result   */
6596 /*-----------------------------------------------------------------*/
6597 static void shiftL2Left2Result (operand *left, int offl,
6598                                 operand *result, int offr, int shCount)
6599 {
6600
6601
6602   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6603
6604   if(pic14_sameRegs(AOP(result), AOP(left))) {
6605     switch(shCount) {
6606     case 0:
6607       break;
6608     case 1:
6609     case 2:
6610     case 3:
6611
6612       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6613       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6614       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6615
6616       while(--shCount) {
6617         emitCLRC;
6618         emitpcode(POC_RLF, popGet(AOP(result),offr));
6619         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6620       }
6621
6622       break;
6623     case 4:
6624     case 5:
6625       emitpcode(POC_MOVLW, popGetLit(0x0f));
6626       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6627       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6628       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6629       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6630       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6631       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6632       if(shCount >=5) {
6633         emitpcode(POC_RLF, popGet(AOP(result),offr));
6634         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6635       }
6636       break;
6637     case 6:
6638       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6639       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6640       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6641       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6642       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6643       emitpcode(POC_ANDLW,popGetLit(0xc0));
6644       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6645       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6646       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6647       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6648       break;
6649     case 7:
6650       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6651       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6652       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6653       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6654       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6655     }
6656
6657   } else {
6658     switch(shCount) {
6659     case 0:
6660       break;
6661     case 1:
6662     case 2:
6663     case 3:
6664       /* note, use a mov/add for the shift since the mov has a
6665          chance of getting optimized out */
6666       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6667       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6668       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6669       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6670       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6671
6672       while(--shCount) {
6673         emitCLRC;
6674         emitpcode(POC_RLF, popGet(AOP(result),offr));
6675         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6676       }
6677       break;
6678
6679     case 4:
6680     case 5:
6681       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6682       emitpcode(POC_ANDLW, popGetLit(0xF0));
6683       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6684       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6685       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6686       emitpcode(POC_ANDLW, popGetLit(0xF0));
6687       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6688       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6689
6690
6691       if(shCount == 5) {
6692         emitpcode(POC_RLF, popGet(AOP(result),offr));
6693         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6694       }
6695       break;
6696     case 6:
6697       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6698       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6699       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6700       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6701
6702       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6703       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6704       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6705       emitpcode(POC_ANDLW,popGetLit(0xc0));
6706       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6707       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6708       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6709       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6710       break;
6711     case 7:
6712       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6713       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6714       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6715       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6716       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6717     }
6718   }
6719
6720 }
6721 /*-----------------------------------------------------------------*/
6722 /* shiftR2Left2Result - shift right two bytes from left to result  */
6723 /*-----------------------------------------------------------------*/
6724 static void shiftR2Left2Result (operand *left, int offl,
6725                                 operand *result, int offr,
6726                                 int shCount, int sign)
6727 {
6728   int same=0;
6729
6730   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6731   same = pic14_sameRegs(AOP(result), AOP(left));
6732
6733   if(same && ((offl + MSB16) == offr)){
6734     same=1;
6735     /* don't crash result[offr] */
6736     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6737     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6738   } else {
6739     movLeft2Result(left,offl, result, offr);
6740     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6741   }
6742   /* a:x >> shCount (x = lsb(result))*/
6743 /*
6744   if(sign)
6745     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6746   else {
6747     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6748 */
6749   switch(shCount) {
6750   case 0:
6751     break;
6752   case 1:
6753   case 2:
6754   case 3:
6755     if(sign)
6756       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6757     else
6758       emitCLRC;
6759
6760     if(same) {
6761       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6762       emitpcode(POC_RRF,popGet(AOP(result),offr));
6763     } else {
6764       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6765       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6766       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6767       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6768     }
6769
6770     while(--shCount) {
6771       if(sign)
6772         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6773       else
6774         emitCLRC;
6775       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6776       emitpcode(POC_RRF,popGet(AOP(result),offr));
6777     }
6778     break;
6779   case 4:
6780   case 5:
6781     if(same) {
6782
6783       emitpcode(POC_MOVLW, popGetLit(0xf0));
6784       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6785       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6786
6787       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6788       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6789       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6790       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6791     } else {
6792       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6793       emitpcode(POC_ANDLW, popGetLit(0x0f));
6794       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6795
6796       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6797       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6798       emitpcode(POC_ANDLW, popGetLit(0xf0));
6799       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6800       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6801     }
6802
6803     if(shCount >=5) {
6804       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6805       emitpcode(POC_RRF, popGet(AOP(result),offr));
6806     }
6807
6808     if(sign) {
6809       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6810       emitpcode(POC_BTFSC, 
6811                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6812       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6813     }
6814
6815     break;
6816
6817   case 6:
6818     if(same) {
6819
6820       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6821       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6822
6823       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6824       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6825       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6826       emitpcode(POC_ANDLW,popGetLit(0x03));
6827       if(sign) {
6828         emitpcode(POC_BTFSC, 
6829                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6830         emitpcode(POC_IORLW,popGetLit(0xfc));
6831       }
6832       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6833       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6834       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6835       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6836     } else {
6837       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6838       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6839       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6840       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6841       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6842       emitpcode(POC_ANDLW,popGetLit(0x03));
6843       if(sign) {
6844         emitpcode(POC_BTFSC, 
6845                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6846         emitpcode(POC_IORLW,popGetLit(0xfc));
6847       }
6848       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6849       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6850
6851         
6852     }
6853
6854     break;
6855   case 7:
6856     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6857     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6858     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6859     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6860     if(sign) {
6861       emitSKPNC;
6862       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6863     } else 
6864       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6865   }
6866 }
6867
6868
6869 /*-----------------------------------------------------------------*/
6870 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6871 /*-----------------------------------------------------------------*/
6872 static void shiftLLeftOrResult (operand *left, int offl,
6873                                 operand *result, int offr, int shCount)
6874 {
6875     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6876     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6877     /* shift left accumulator */
6878     AccLsh(shCount);
6879     /* or with result */
6880     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6881     /* back to result */
6882     aopPut(AOP(result),"a",offr);
6883 }
6884
6885 /*-----------------------------------------------------------------*/
6886 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6887 /*-----------------------------------------------------------------*/
6888 static void shiftRLeftOrResult (operand *left, int offl,
6889                                 operand *result, int offr, int shCount)
6890 {
6891     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6892     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6893     /* shift right accumulator */
6894     AccRsh(shCount);
6895     /* or with result */
6896     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6897     /* back to result */
6898     aopPut(AOP(result),"a",offr);
6899 }
6900
6901 /*-----------------------------------------------------------------*/
6902 /* genlshOne - left shift a one byte quantity by known count       */
6903 /*-----------------------------------------------------------------*/
6904 static void genlshOne (operand *result, operand *left, int shCount)
6905 {       
6906     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6907     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6908 }
6909
6910 /*-----------------------------------------------------------------*/
6911 /* genlshTwo - left shift two bytes by known amount != 0           */
6912 /*-----------------------------------------------------------------*/
6913 static void genlshTwo (operand *result,operand *left, int shCount)
6914 {
6915     int size;
6916     
6917     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6918     size = pic14_getDataSize(result);
6919
6920     /* if shCount >= 8 */
6921     if (shCount >= 8) {
6922         shCount -= 8 ;
6923
6924         if (size > 1){
6925             if (shCount)
6926                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6927             else 
6928                 movLeft2Result(left, LSB, result, MSB16);
6929         }
6930         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6931     }
6932
6933     /*  1 <= shCount <= 7 */
6934     else {  
6935         if(size == 1)
6936             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6937         else 
6938             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6939     }
6940 }
6941
6942 /*-----------------------------------------------------------------*/
6943 /* shiftLLong - shift left one long from left to result            */
6944 /* offl = LSB or MSB16                                             */
6945 /*-----------------------------------------------------------------*/
6946 static void shiftLLong (operand *left, operand *result, int offr )
6947 {
6948     char *l;
6949     int size = AOP_SIZE(result);
6950
6951     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6952     if(size >= LSB+offr){
6953         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6954         MOVA(l);
6955         pic14_emitcode("add","a,acc");
6956         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6957             size >= MSB16+offr && offr != LSB )
6958             pic14_emitcode("xch","a,%s",
6959                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6960         else        
6961             aopPut(AOP(result),"a",LSB+offr);
6962     }
6963
6964     if(size >= MSB16+offr){
6965         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6966             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6967             MOVA(l);
6968         }
6969         pic14_emitcode("rlc","a");
6970         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6971             size >= MSB24+offr && offr != LSB)
6972             pic14_emitcode("xch","a,%s",
6973                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6974         else        
6975             aopPut(AOP(result),"a",MSB16+offr);
6976     }
6977
6978     if(size >= MSB24+offr){
6979         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6980             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6981             MOVA(l);
6982         }
6983         pic14_emitcode("rlc","a");
6984         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6985             size >= MSB32+offr && offr != LSB )
6986             pic14_emitcode("xch","a,%s",
6987                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6988         else        
6989             aopPut(AOP(result),"a",MSB24+offr);
6990     }
6991
6992     if(size > MSB32+offr){
6993         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6994             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6995             MOVA(l);    
6996         }
6997         pic14_emitcode("rlc","a");
6998         aopPut(AOP(result),"a",MSB32+offr);
6999     }
7000     if(offr != LSB)
7001         aopPut(AOP(result),zero,LSB);       
7002 }
7003
7004 /*-----------------------------------------------------------------*/
7005 /* genlshFour - shift four byte by a known amount != 0             */
7006 /*-----------------------------------------------------------------*/
7007 static void genlshFour (operand *result, operand *left, int shCount)
7008 {
7009     int size;
7010
7011     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7012     size = AOP_SIZE(result);
7013
7014     /* if shifting more that 3 bytes */
7015     if (shCount >= 24 ) {
7016         shCount -= 24;
7017         if (shCount)
7018             /* lowest order of left goes to the highest
7019             order of the destination */
7020             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7021         else
7022             movLeft2Result(left, LSB, result, MSB32);
7023         aopPut(AOP(result),zero,LSB);
7024         aopPut(AOP(result),zero,MSB16);
7025         aopPut(AOP(result),zero,MSB32);
7026         return;
7027     }
7028
7029     /* more than two bytes */
7030     else if ( shCount >= 16 ) {
7031         /* lower order two bytes goes to higher order two bytes */
7032         shCount -= 16;
7033         /* if some more remaining */
7034         if (shCount)
7035             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7036         else {
7037             movLeft2Result(left, MSB16, result, MSB32);
7038             movLeft2Result(left, LSB, result, MSB24);
7039         }
7040         aopPut(AOP(result),zero,MSB16);
7041         aopPut(AOP(result),zero,LSB);
7042         return;
7043     }    
7044
7045     /* if more than 1 byte */
7046     else if ( shCount >= 8 ) {
7047         /* lower order three bytes goes to higher order  three bytes */
7048         shCount -= 8;
7049         if(size == 2){
7050             if(shCount)
7051                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7052             else
7053                 movLeft2Result(left, LSB, result, MSB16);
7054         }
7055         else{   /* size = 4 */
7056             if(shCount == 0){
7057                 movLeft2Result(left, MSB24, result, MSB32);
7058                 movLeft2Result(left, MSB16, result, MSB24);
7059                 movLeft2Result(left, LSB, result, MSB16);
7060                 aopPut(AOP(result),zero,LSB);
7061             }
7062             else if(shCount == 1)
7063                 shiftLLong(left, result, MSB16);
7064             else{
7065                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7066                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7067                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7068                 aopPut(AOP(result),zero,LSB);
7069             }
7070         }
7071     }
7072
7073     /* 1 <= shCount <= 7 */
7074     else if(shCount <= 2){
7075         shiftLLong(left, result, LSB);
7076         if(shCount == 2)
7077             shiftLLong(result, result, LSB);
7078     }
7079     /* 3 <= shCount <= 7, optimize */
7080     else{
7081         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7082         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7083         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7084     }
7085 }
7086
7087 /*-----------------------------------------------------------------*/
7088 /* genLeftShiftLiteral - left shifting by known count              */
7089 /*-----------------------------------------------------------------*/
7090 static void genLeftShiftLiteral (operand *left,
7091                                  operand *right,
7092                                  operand *result,
7093                                  iCode *ic)
7094 {    
7095     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7096     int size;
7097
7098     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7099     freeAsmop(right,NULL,ic,TRUE);
7100
7101     aopOp(left,ic,FALSE);
7102     aopOp(result,ic,FALSE);
7103
7104     size = getSize(operandType(result));
7105
7106 #if VIEW_SIZE
7107     pic14_emitcode("; shift left ","result %d, left %d",size,
7108              AOP_SIZE(left));
7109 #endif
7110
7111     /* I suppose that the left size >= result size */
7112     if(shCount == 0){
7113         while(size--){
7114             movLeft2Result(left, size, result, size);
7115         }
7116     }
7117
7118     else if(shCount >= (size * 8))
7119         while(size--)
7120             aopPut(AOP(result),zero,size);
7121     else{
7122         switch (size) {
7123             case 1:
7124                 genlshOne (result,left,shCount);
7125                 break;
7126
7127             case 2:
7128             case 3:
7129                 genlshTwo (result,left,shCount);
7130                 break;
7131
7132             case 4:
7133                 genlshFour (result,left,shCount);
7134                 break;
7135         }
7136     }
7137     freeAsmop(left,NULL,ic,TRUE);
7138     freeAsmop(result,NULL,ic,TRUE);
7139 }
7140
7141 /*-----------------------------------------------------------------*
7142  * genMultiAsm - repeat assembly instruction for size of register.
7143  * if endian == 1, then the high byte (i.e base address + size of 
7144  * register) is used first else the low byte is used first;
7145  *-----------------------------------------------------------------*/
7146 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7147 {
7148
7149   int offset = 0;
7150
7151   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7152
7153   if(!reg)
7154     return;
7155
7156   if(!endian) {
7157     endian = 1;
7158   } else {
7159     endian = -1;
7160     offset = size-1;
7161   }
7162
7163   while(size--) {
7164     emitpcode(poc,    popGet(AOP(reg),offset));
7165     offset += endian;
7166   }
7167
7168 }
7169 /*-----------------------------------------------------------------*/
7170 /* genLeftShift - generates code for left shifting                 */
7171 /*-----------------------------------------------------------------*/
7172 static void genLeftShift (iCode *ic)
7173 {
7174   operand *left,*right, *result;
7175   int size, offset;
7176   char *l;
7177   symbol *tlbl , *tlbl1;
7178   pCodeOp *pctemp;
7179
7180   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7181
7182   right = IC_RIGHT(ic);
7183   left  = IC_LEFT(ic);
7184   result = IC_RESULT(ic);
7185
7186   aopOp(right,ic,FALSE);
7187
7188   /* if the shift count is known then do it 
7189      as efficiently as possible */
7190   if (AOP_TYPE(right) == AOP_LIT) {
7191     genLeftShiftLiteral (left,right,result,ic);
7192     return ;
7193   }
7194
7195   /* shift count is unknown then we have to form 
7196      a loop get the loop count in B : Note: we take
7197      only the lower order byte since shifting
7198      more that 32 bits make no sense anyway, ( the
7199      largest size of an object can be only 32 bits ) */  
7200
7201     
7202   aopOp(left,ic,FALSE);
7203   aopOp(result,ic,FALSE);
7204
7205   /* now move the left to the result if they are not the
7206      same */
7207   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7208       AOP_SIZE(result) > 1) {
7209
7210     size = AOP_SIZE(result);
7211     offset=0;
7212     while (size--) {
7213       l = aopGet(AOP(left),offset,FALSE,TRUE);
7214       if (*l == '@' && (IS_AOP_PREG(result))) {
7215
7216         pic14_emitcode("mov","a,%s",l);
7217         aopPut(AOP(result),"a",offset);
7218       } else {
7219         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7220         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7221         //aopPut(AOP(result),l,offset);
7222       }
7223       offset++;
7224     }
7225   }
7226
7227   size = AOP_SIZE(result);
7228
7229   /* if it is only one byte then */
7230   if (size == 1) {
7231     if(optimized_for_speed) {
7232       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7233       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7234       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7235       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7236       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7237       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7238       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7239       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7240       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7241       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7242       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7243       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7244     } else {
7245
7246       tlbl = newiTempLabel(NULL);
7247       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7248         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7249         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7250       }
7251
7252       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7253       emitpcode(POC_RRF,    popGet(AOP(result),0));
7254       emitpLabel(tlbl->key);
7255       emitpcode(POC_RLF,    popGet(AOP(result),0));
7256       emitpcode(POC_ADDLW,  popGetLit(1));
7257       emitSKPC;
7258       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7259     }
7260     goto release ;
7261   }
7262     
7263   if (pic14_sameRegs(AOP(left),AOP(result))) {
7264
7265     tlbl = newiTempLabel(NULL);
7266     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7267     genMultiAsm(POC_RRF, result, size,1);
7268     emitpLabel(tlbl->key);
7269     genMultiAsm(POC_RLF, result, size,0);
7270     emitpcode(POC_ADDLW,  popGetLit(1));
7271     emitSKPC;
7272     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7273     goto release;
7274   }
7275
7276   //tlbl = newiTempLabel(NULL);
7277   //offset = 0 ;   
7278   //tlbl1 = newiTempLabel(NULL);
7279
7280   //reAdjustPreg(AOP(result));    
7281     
7282   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7283   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7284   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7285   //MOVA(l);
7286   //pic14_emitcode("add","a,acc");         
7287   //aopPut(AOP(result),"a",offset++);
7288   //while (--size) {
7289   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7290   //  MOVA(l);
7291   //  pic14_emitcode("rlc","a");         
7292   //  aopPut(AOP(result),"a",offset++);
7293   //}
7294   //reAdjustPreg(AOP(result));
7295
7296   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7297   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7298
7299
7300   tlbl = newiTempLabel(NULL);
7301   tlbl1= newiTempLabel(NULL);
7302
7303   size = AOP_SIZE(result);
7304   offset = 1;
7305
7306   pctemp = popGetTempReg();  /* grab a temporary working register. */
7307
7308   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7309
7310   /* offset should be 0, 1 or 3 */
7311   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7312   emitSKPNZ;
7313   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7314
7315   emitpcode(POC_MOVWF, pctemp);
7316
7317
7318   emitpLabel(tlbl->key);
7319
7320   emitCLRC;
7321   emitpcode(POC_RLF,  popGet(AOP(result),0));
7322   while(--size)
7323     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7324
7325   emitpcode(POC_DECFSZ,  pctemp);
7326   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7327   emitpLabel(tlbl1->key);
7328
7329   popReleaseTempReg(pctemp);
7330
7331
7332  release:
7333   freeAsmop (right,NULL,ic,TRUE);
7334   freeAsmop(left,NULL,ic,TRUE);
7335   freeAsmop(result,NULL,ic,TRUE);
7336 }
7337
7338 /*-----------------------------------------------------------------*/
7339 /* genrshOne - right shift a one byte quantity by known count      */
7340 /*-----------------------------------------------------------------*/
7341 static void genrshOne (operand *result, operand *left,
7342                        int shCount, int sign)
7343 {
7344     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7345     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7346 }
7347
7348 /*-----------------------------------------------------------------*/
7349 /* genrshTwo - right shift two bytes by known amount != 0          */
7350 /*-----------------------------------------------------------------*/
7351 static void genrshTwo (operand *result,operand *left,
7352                        int shCount, int sign)
7353 {
7354   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7355   /* if shCount >= 8 */
7356   if (shCount >= 8) {
7357     shCount -= 8 ;
7358     if (shCount)
7359       shiftR1Left2Result(left, MSB16, result, LSB,
7360                          shCount, sign);
7361     else
7362       movLeft2Result(left, MSB16, result, LSB);
7363
7364     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7365
7366     if(sign) {
7367       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7368       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7369     }
7370   }
7371
7372   /*  1 <= shCount <= 7 */
7373   else
7374     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7375 }
7376
7377 /*-----------------------------------------------------------------*/
7378 /* shiftRLong - shift right one long from left to result           */
7379 /* offl = LSB or MSB16                                             */
7380 /*-----------------------------------------------------------------*/
7381 static void shiftRLong (operand *left, int offl,
7382                         operand *result, int sign)
7383 {
7384     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7385     if(!sign)
7386         pic14_emitcode("clr","c");
7387     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7388     if(sign)
7389         pic14_emitcode("mov","c,acc.7");
7390     pic14_emitcode("rrc","a");
7391     aopPut(AOP(result),"a",MSB32-offl);
7392     if(offl == MSB16)
7393         /* add sign of "a" */
7394         addSign(result, MSB32, sign);
7395
7396     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7397     pic14_emitcode("rrc","a");
7398     aopPut(AOP(result),"a",MSB24-offl);
7399
7400     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7401     pic14_emitcode("rrc","a");
7402     aopPut(AOP(result),"a",MSB16-offl);
7403
7404     if(offl == LSB){
7405         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7406         pic14_emitcode("rrc","a");
7407         aopPut(AOP(result),"a",LSB);
7408     }
7409 }
7410
7411 /*-----------------------------------------------------------------*/
7412 /* genrshFour - shift four byte by a known amount != 0             */
7413 /*-----------------------------------------------------------------*/
7414 static void genrshFour (operand *result, operand *left,
7415                         int shCount, int sign)
7416 {
7417   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7418   /* if shifting more that 3 bytes */
7419   if(shCount >= 24 ) {
7420     shCount -= 24;
7421     if(shCount)
7422       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7423     else
7424       movLeft2Result(left, MSB32, result, LSB);
7425
7426     addSign(result, MSB16, sign);
7427   }
7428   else if(shCount >= 16){
7429     shCount -= 16;
7430     if(shCount)
7431       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7432     else{
7433       movLeft2Result(left, MSB24, result, LSB);
7434       movLeft2Result(left, MSB32, result, MSB16);
7435     }
7436     addSign(result, MSB24, sign);
7437   }
7438   else if(shCount >= 8){
7439     shCount -= 8;
7440     if(shCount == 1)
7441       shiftRLong(left, MSB16, result, sign);
7442     else if(shCount == 0){
7443       movLeft2Result(left, MSB16, result, LSB);
7444       movLeft2Result(left, MSB24, result, MSB16);
7445       movLeft2Result(left, MSB32, result, MSB24);
7446       addSign(result, MSB32, sign);
7447     }
7448     else{
7449       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7450       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7451       /* the last shift is signed */
7452       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7453       addSign(result, MSB32, sign);
7454     }
7455   }
7456   else{   /* 1 <= shCount <= 7 */
7457     if(shCount <= 2){
7458       shiftRLong(left, LSB, result, sign);
7459       if(shCount == 2)
7460         shiftRLong(result, LSB, result, sign);
7461     }
7462     else{
7463       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7464       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7465       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7466     }
7467   }
7468 }
7469
7470 /*-----------------------------------------------------------------*/
7471 /* genRightShiftLiteral - right shifting by known count            */
7472 /*-----------------------------------------------------------------*/
7473 static void genRightShiftLiteral (operand *left,
7474                                   operand *right,
7475                                   operand *result,
7476                                   iCode *ic,
7477                                   int sign)
7478 {    
7479   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7480   int lsize,res_size;
7481
7482   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7483   freeAsmop(right,NULL,ic,TRUE);
7484
7485   aopOp(left,ic,FALSE);
7486   aopOp(result,ic,FALSE);
7487
7488 #if VIEW_SIZE
7489   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7490                  AOP_SIZE(left));
7491 #endif
7492
7493   lsize = pic14_getDataSize(left);
7494   res_size = pic14_getDataSize(result);
7495   /* test the LEFT size !!! */
7496
7497   /* I suppose that the left size >= result size */
7498   if(shCount == 0){
7499     while(res_size--)
7500       movLeft2Result(left, lsize, result, res_size);
7501   }
7502
7503   else if(shCount >= (lsize * 8)){
7504
7505     if(res_size == 1) {
7506       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7507       if(sign) {
7508         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7509         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7510       }
7511     } else {
7512
7513       if(sign) {
7514         emitpcode(POC_MOVLW, popGetLit(0));
7515         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7516         emitpcode(POC_MOVLW, popGetLit(0xff));
7517         while(res_size--)
7518           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7519
7520       } else {
7521
7522         while(res_size--)
7523           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7524       }
7525     }
7526   } else {
7527
7528     switch (res_size) {
7529     case 1:
7530       genrshOne (result,left,shCount,sign);
7531       break;
7532
7533     case 2:
7534       genrshTwo (result,left,shCount,sign);
7535       break;
7536
7537     case 4:
7538       genrshFour (result,left,shCount,sign);
7539       break;
7540     default :
7541       break;
7542     }
7543
7544   }
7545
7546   freeAsmop(left,NULL,ic,TRUE);
7547   freeAsmop(result,NULL,ic,TRUE);
7548 }
7549
7550 /*-----------------------------------------------------------------*/
7551 /* genSignedRightShift - right shift of signed number              */
7552 /*-----------------------------------------------------------------*/
7553 static void genSignedRightShift (iCode *ic)
7554 {
7555   operand *right, *left, *result;
7556   int size, offset;
7557   //  char *l;
7558   symbol *tlbl, *tlbl1 ;
7559   pCodeOp *pctemp;
7560
7561   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7562
7563   /* we do it the hard way put the shift count in b
7564      and loop thru preserving the sign */
7565   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7566
7567   right = IC_RIGHT(ic);
7568   left  = IC_LEFT(ic);
7569   result = IC_RESULT(ic);
7570
7571   aopOp(right,ic,FALSE);  
7572   aopOp(left,ic,FALSE);
7573   aopOp(result,ic,FALSE);
7574
7575
7576   if ( AOP_TYPE(right) == AOP_LIT) {
7577     genRightShiftLiteral (left,right,result,ic,1);
7578     return ;
7579   }
7580   /* shift count is unknown then we have to form 
7581      a loop get the loop count in B : Note: we take
7582      only the lower order byte since shifting
7583      more that 32 bits make no sense anyway, ( the
7584      largest size of an object can be only 32 bits ) */  
7585
7586   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7587   //pic14_emitcode("inc","b");
7588   //freeAsmop (right,NULL,ic,TRUE);
7589   //aopOp(left,ic,FALSE);
7590   //aopOp(result,ic,FALSE);
7591
7592   /* now move the left to the result if they are not the
7593      same */
7594   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7595       AOP_SIZE(result) > 1) {
7596
7597     size = AOP_SIZE(result);
7598     offset=0;
7599     while (size--) { 
7600       /*
7601         l = aopGet(AOP(left),offset,FALSE,TRUE);
7602         if (*l == '@' && IS_AOP_PREG(result)) {
7603
7604         pic14_emitcode("mov","a,%s",l);
7605         aopPut(AOP(result),"a",offset);
7606         } else
7607         aopPut(AOP(result),l,offset);
7608       */
7609       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7610       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7611
7612       offset++;
7613     }
7614   }
7615
7616   /* mov the highest order bit to OVR */    
7617   tlbl = newiTempLabel(NULL);
7618   tlbl1= newiTempLabel(NULL);
7619
7620   size = AOP_SIZE(result);
7621   offset = size - 1;
7622
7623   pctemp = popGetTempReg();  /* grab a temporary working register. */
7624
7625   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7626
7627   /* offset should be 0, 1 or 3 */
7628   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7629   emitSKPNZ;
7630   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7631
7632   emitpcode(POC_MOVWF, pctemp);
7633
7634
7635   emitpLabel(tlbl->key);
7636
7637   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7638   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7639
7640   while(--size) {
7641     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7642   }
7643
7644   emitpcode(POC_DECFSZ,  pctemp);
7645   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7646   emitpLabel(tlbl1->key);
7647
7648   popReleaseTempReg(pctemp);
7649 #if 0
7650   size = AOP_SIZE(result);
7651   offset = size - 1;
7652   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7653   pic14_emitcode("rlc","a");
7654   pic14_emitcode("mov","ov,c");
7655   /* if it is only one byte then */
7656   if (size == 1) {
7657     l = aopGet(AOP(left),0,FALSE,FALSE);
7658     MOVA(l);
7659     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7660     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7661     pic14_emitcode("mov","c,ov");
7662     pic14_emitcode("rrc","a");
7663     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7664     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7665     aopPut(AOP(result),"a",0);
7666     goto release ;
7667   }
7668
7669   reAdjustPreg(AOP(result));
7670   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7671   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7672   pic14_emitcode("mov","c,ov");
7673   while (size--) {
7674     l = aopGet(AOP(result),offset,FALSE,FALSE);
7675     MOVA(l);
7676     pic14_emitcode("rrc","a");         
7677     aopPut(AOP(result),"a",offset--);
7678   }
7679   reAdjustPreg(AOP(result));
7680   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7681   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7682
7683  release:
7684 #endif
7685
7686   freeAsmop(left,NULL,ic,TRUE);
7687   freeAsmop(result,NULL,ic,TRUE);
7688   freeAsmop(right,NULL,ic,TRUE);
7689 }
7690
7691 /*-----------------------------------------------------------------*/
7692 /* genRightShift - generate code for right shifting                */
7693 /*-----------------------------------------------------------------*/
7694 static void genRightShift (iCode *ic)
7695 {
7696     operand *right, *left, *result;
7697     sym_link *retype ;
7698     int size, offset;
7699     char *l;
7700     symbol *tlbl, *tlbl1 ;
7701
7702     /* if signed then we do it the hard way preserve the
7703     sign bit moving it inwards */
7704     retype = getSpec(operandType(IC_RESULT(ic)));
7705     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7706
7707     if (!SPEC_USIGN(retype)) {
7708         genSignedRightShift (ic);
7709         return ;
7710     }
7711
7712     /* signed & unsigned types are treated the same : i.e. the
7713     signed is NOT propagated inwards : quoting from the
7714     ANSI - standard : "for E1 >> E2, is equivalent to division
7715     by 2**E2 if unsigned or if it has a non-negative value,
7716     otherwise the result is implementation defined ", MY definition
7717     is that the sign does not get propagated */
7718
7719     right = IC_RIGHT(ic);
7720     left  = IC_LEFT(ic);
7721     result = IC_RESULT(ic);
7722
7723     aopOp(right,ic,FALSE);
7724
7725     /* if the shift count is known then do it 
7726     as efficiently as possible */
7727     if (AOP_TYPE(right) == AOP_LIT) {
7728         genRightShiftLiteral (left,right,result,ic, 0);
7729         return ;
7730     }
7731
7732     /* shift count is unknown then we have to form 
7733     a loop get the loop count in B : Note: we take
7734     only the lower order byte since shifting
7735     more that 32 bits make no sense anyway, ( the
7736     largest size of an object can be only 32 bits ) */  
7737
7738     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7739     pic14_emitcode("inc","b");
7740     aopOp(left,ic,FALSE);
7741     aopOp(result,ic,FALSE);
7742
7743     /* now move the left to the result if they are not the
7744     same */
7745     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7746         AOP_SIZE(result) > 1) {
7747
7748         size = AOP_SIZE(result);
7749         offset=0;
7750         while (size--) {
7751             l = aopGet(AOP(left),offset,FALSE,TRUE);
7752             if (*l == '@' && IS_AOP_PREG(result)) {
7753
7754                 pic14_emitcode("mov","a,%s",l);
7755                 aopPut(AOP(result),"a",offset);
7756             } else
7757                 aopPut(AOP(result),l,offset);
7758             offset++;
7759         }
7760     }
7761
7762     tlbl = newiTempLabel(NULL);
7763     tlbl1= newiTempLabel(NULL);
7764     size = AOP_SIZE(result);
7765     offset = size - 1;
7766
7767     /* if it is only one byte then */
7768     if (size == 1) {
7769
7770       tlbl = newiTempLabel(NULL);
7771       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7772         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7773         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7774       }
7775
7776       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7777       emitpcode(POC_RLF,    popGet(AOP(result),0));
7778       emitpLabel(tlbl->key);
7779       emitpcode(POC_RRF,    popGet(AOP(result),0));
7780       emitpcode(POC_ADDLW,  popGetLit(1));
7781       emitSKPC;
7782       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7783
7784       goto release ;
7785     }
7786
7787     reAdjustPreg(AOP(result));
7788     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7789     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7790     CLRC;
7791     while (size--) {
7792         l = aopGet(AOP(result),offset,FALSE,FALSE);
7793         MOVA(l);
7794         pic14_emitcode("rrc","a");         
7795         aopPut(AOP(result),"a",offset--);
7796     }
7797     reAdjustPreg(AOP(result));
7798
7799     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7800     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7801
7802 release:
7803     freeAsmop(left,NULL,ic,TRUE);
7804     freeAsmop (right,NULL,ic,TRUE);
7805     freeAsmop(result,NULL,ic,TRUE);
7806 }
7807
7808 /*-----------------------------------------------------------------*/
7809 /* genUnpackBits - generates code for unpacking bits               */
7810 /*-----------------------------------------------------------------*/
7811 static void genUnpackBits (operand *result, char *rname, int ptype)
7812 {    
7813     int shCnt ;
7814     int rlen = 0 ;
7815     sym_link *etype;
7816     int offset = 0 ;
7817
7818     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7819     etype = getSpec(operandType(result));
7820
7821     /* read the first byte  */
7822     switch (ptype) {
7823
7824     case POINTER:
7825     case IPOINTER:
7826         pic14_emitcode("mov","a,@%s",rname);
7827         break;
7828         
7829     case PPOINTER:
7830         pic14_emitcode("movx","a,@%s",rname);
7831         break;
7832         
7833     case FPOINTER:
7834         pic14_emitcode("movx","a,@dptr");
7835         break;
7836
7837     case CPOINTER:
7838         pic14_emitcode("clr","a");
7839         pic14_emitcode("movc","a","@a+dptr");
7840         break;
7841
7842     case GPOINTER:
7843         pic14_emitcode("lcall","__gptrget");
7844         break;
7845     }
7846
7847     /* if we have bitdisplacement then it fits   */
7848     /* into this byte completely or if length is */
7849     /* less than a byte                          */
7850     if ((shCnt = SPEC_BSTR(etype)) || 
7851         (SPEC_BLEN(etype) <= 8))  {
7852
7853         /* shift right acc */
7854         AccRsh(shCnt);
7855
7856         pic14_emitcode("anl","a,#0x%02x",
7857                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7858         aopPut(AOP(result),"a",offset);
7859         return ;
7860     }
7861
7862     /* bit field did not fit in a byte  */
7863     rlen = SPEC_BLEN(etype) - 8;
7864     aopPut(AOP(result),"a",offset++);
7865
7866     while (1)  {
7867
7868         switch (ptype) {
7869         case POINTER:
7870         case IPOINTER:
7871             pic14_emitcode("inc","%s",rname);
7872             pic14_emitcode("mov","a,@%s",rname);
7873             break;
7874             
7875         case PPOINTER:
7876             pic14_emitcode("inc","%s",rname);
7877             pic14_emitcode("movx","a,@%s",rname);
7878             break;
7879
7880         case FPOINTER:
7881             pic14_emitcode("inc","dptr");
7882             pic14_emitcode("movx","a,@dptr");
7883             break;
7884             
7885         case CPOINTER:
7886             pic14_emitcode("clr","a");
7887             pic14_emitcode("inc","dptr");
7888             pic14_emitcode("movc","a","@a+dptr");
7889             break;
7890             
7891         case GPOINTER:
7892             pic14_emitcode("inc","dptr");
7893             pic14_emitcode("lcall","__gptrget");
7894             break;
7895         }
7896
7897         rlen -= 8;            
7898         /* if we are done */
7899         if ( rlen <= 0 )
7900             break ;
7901         
7902         aopPut(AOP(result),"a",offset++);
7903                               
7904     }
7905     
7906     if (rlen) {
7907         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7908         aopPut(AOP(result),"a",offset);        
7909     }
7910     
7911     return ;
7912 }
7913
7914 #if 0
7915 /*-----------------------------------------------------------------*/
7916 /* genDataPointerGet - generates code when ptr offset is known     */
7917 /*-----------------------------------------------------------------*/
7918 static void genDataPointerGet (operand *left, 
7919                                operand *result, 
7920                                iCode *ic)
7921 {
7922   int size , offset = 0;
7923
7924
7925   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7926
7927
7928   /* optimization - most of the time, left and result are the same
7929    * address, but different types. for the pic code, we could omit
7930    * the following
7931    */
7932
7933   aopOp(result,ic,TRUE);
7934
7935   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7936
7937   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7938
7939   size = AOP_SIZE(result);
7940
7941   while (size--) {
7942     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7943     offset++;
7944   }
7945
7946   freeAsmop(left,NULL,ic,TRUE);
7947   freeAsmop(result,NULL,ic,TRUE);
7948 }
7949 #endif
7950 /*-----------------------------------------------------------------*/
7951 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7952 /*-----------------------------------------------------------------*/
7953 static void genNearPointerGet (operand *left, 
7954                                operand *result, 
7955                                iCode *ic)
7956 {
7957     asmop *aop = NULL;
7958     //regs *preg = NULL ;
7959     char *rname ;
7960     sym_link *rtype, *retype;
7961     sym_link *ltype = operandType(left);    
7962     //char buffer[80];
7963
7964     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7965
7966     rtype = operandType(result);
7967     retype= getSpec(rtype);
7968     
7969     aopOp(left,ic,FALSE);
7970     
7971     /* if left is rematerialisable and
7972        result is not bit variable type and
7973        the left is pointer to data space i.e
7974        lower 128 bytes of space */
7975     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7976         !IS_BITVAR(retype)         &&
7977         DCL_TYPE(ltype) == POINTER) {
7978       //genDataPointerGet (left,result,ic);
7979         return ;
7980     }
7981     
7982     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7983
7984         /* if the value is already in a pointer register
7985        then don't need anything more */
7986     if (!AOP_INPREG(AOP(left))) {
7987         /* otherwise get a free pointer register */
7988     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7989 /*
7990         aop = newAsmop(0);
7991         preg = getFreePtr(ic,&aop,FALSE);
7992         pic14_emitcode("mov","%s,%s",
7993                 preg->name,
7994                 aopGet(AOP(left),0,FALSE,TRUE));
7995         rname = preg->name ;
7996 */
7997     rname ="BAD";
7998     } else
7999         rname = aopGet(AOP(left),0,FALSE,FALSE);
8000     
8001     aopOp (result,ic,FALSE);
8002     
8003       /* if bitfield then unpack the bits */
8004     if (IS_BITVAR(retype)) 
8005         genUnpackBits (result,rname,POINTER);
8006     else {
8007         /* we have can just get the values */
8008       int size = AOP_SIZE(result);
8009       int offset = 0 ;  
8010         
8011       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8012
8013       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8014       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8015       while(size--) {
8016         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8017         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8018         if(size)
8019           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8020       }
8021 /*
8022         while (size--) {
8023             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8024
8025                 pic14_emitcode("mov","a,@%s",rname);
8026                 aopPut(AOP(result),"a",offset);
8027             } else {
8028                 sprintf(buffer,"@%s",rname);
8029                 aopPut(AOP(result),buffer,offset);
8030             }
8031             offset++ ;
8032             if (size)
8033                 pic14_emitcode("inc","%s",rname);
8034         }
8035 */
8036     }
8037
8038     /* now some housekeeping stuff */
8039     if (aop) {
8040         /* we had to allocate for this iCode */
8041     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8042         freeAsmop(NULL,aop,ic,TRUE);
8043     } else { 
8044         /* we did not allocate which means left
8045            already in a pointer register, then
8046            if size > 0 && this could be used again
8047            we have to point it back to where it 
8048            belongs */
8049     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8050         if (AOP_SIZE(result) > 1 &&
8051             !OP_SYMBOL(left)->remat &&
8052             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8053               ic->depth )) {
8054             int size = AOP_SIZE(result) - 1;
8055             while (size--)
8056                 pic14_emitcode("dec","%s",rname);
8057         }
8058     }
8059
8060     /* done */
8061     freeAsmop(left,NULL,ic,TRUE);
8062     freeAsmop(result,NULL,ic,TRUE);
8063      
8064 }
8065
8066 /*-----------------------------------------------------------------*/
8067 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8068 /*-----------------------------------------------------------------*/
8069 static void genPagedPointerGet (operand *left, 
8070                                operand *result, 
8071                                iCode *ic)
8072 {
8073     asmop *aop = NULL;
8074     regs *preg = NULL ;
8075     char *rname ;
8076     sym_link *rtype, *retype;    
8077
8078     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8079
8080     rtype = operandType(result);
8081     retype= getSpec(rtype);
8082     
8083     aopOp(left,ic,FALSE);
8084
8085   /* if the value is already in a pointer register
8086        then don't need anything more */
8087     if (!AOP_INPREG(AOP(left))) {
8088         /* otherwise get a free pointer register */
8089         aop = newAsmop(0);
8090         preg = getFreePtr(ic,&aop,FALSE);
8091         pic14_emitcode("mov","%s,%s",
8092                 preg->name,
8093                 aopGet(AOP(left),0,FALSE,TRUE));
8094         rname = preg->name ;
8095     } else
8096         rname = aopGet(AOP(left),0,FALSE,FALSE);
8097     
8098     freeAsmop(left,NULL,ic,TRUE);
8099     aopOp (result,ic,FALSE);
8100
8101     /* if bitfield then unpack the bits */
8102     if (IS_BITVAR(retype)) 
8103         genUnpackBits (result,rname,PPOINTER);
8104     else {
8105         /* we have can just get the values */
8106         int size = AOP_SIZE(result);
8107         int offset = 0 ;        
8108         
8109         while (size--) {
8110             
8111             pic14_emitcode("movx","a,@%s",rname);
8112             aopPut(AOP(result),"a",offset);
8113             
8114             offset++ ;
8115             
8116             if (size)
8117                 pic14_emitcode("inc","%s",rname);
8118         }
8119     }
8120
8121     /* now some housekeeping stuff */
8122     if (aop) {
8123         /* we had to allocate for this iCode */
8124         freeAsmop(NULL,aop,ic,TRUE);
8125     } else { 
8126         /* we did not allocate which means left
8127            already in a pointer register, then
8128            if size > 0 && this could be used again
8129            we have to point it back to where it 
8130            belongs */
8131         if (AOP_SIZE(result) > 1 &&
8132             !OP_SYMBOL(left)->remat &&
8133             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8134               ic->depth )) {
8135             int size = AOP_SIZE(result) - 1;
8136             while (size--)
8137                 pic14_emitcode("dec","%s",rname);
8138         }
8139     }
8140
8141     /* done */
8142     freeAsmop(result,NULL,ic,TRUE);
8143     
8144         
8145 }
8146
8147 /*-----------------------------------------------------------------*/
8148 /* genFarPointerGet - gget value from far space                    */
8149 /*-----------------------------------------------------------------*/
8150 static void genFarPointerGet (operand *left,
8151                               operand *result, iCode *ic)
8152 {
8153     int size, offset ;
8154     sym_link *retype = getSpec(operandType(result));
8155
8156     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8157
8158     aopOp(left,ic,FALSE);
8159
8160     /* if the operand is already in dptr 
8161     then we do nothing else we move the value to dptr */
8162     if (AOP_TYPE(left) != AOP_STR) {
8163         /* if this is remateriazable */
8164         if (AOP_TYPE(left) == AOP_IMMD)
8165             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8166         else { /* we need to get it byte by byte */
8167             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8168             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8169             if (options.model == MODEL_FLAT24)
8170             {
8171                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8172             }
8173         }
8174     }
8175     /* so dptr know contains the address */
8176     freeAsmop(left,NULL,ic,TRUE);
8177     aopOp(result,ic,FALSE);
8178
8179     /* if bit then unpack */
8180     if (IS_BITVAR(retype)) 
8181         genUnpackBits(result,"dptr",FPOINTER);
8182     else {
8183         size = AOP_SIZE(result);
8184         offset = 0 ;
8185
8186         while (size--) {
8187             pic14_emitcode("movx","a,@dptr");
8188             aopPut(AOP(result),"a",offset++);
8189             if (size)
8190                 pic14_emitcode("inc","dptr");
8191         }
8192     }
8193
8194     freeAsmop(result,NULL,ic,TRUE);
8195 }
8196 #if 0
8197 /*-----------------------------------------------------------------*/
8198 /* genCodePointerGet - get value from code space                  */
8199 /*-----------------------------------------------------------------*/
8200 static void genCodePointerGet (operand *left,
8201                                 operand *result, iCode *ic)
8202 {
8203     int size, offset ;
8204     sym_link *retype = getSpec(operandType(result));
8205
8206     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8207
8208     aopOp(left,ic,FALSE);
8209
8210     /* if the operand is already in dptr 
8211     then we do nothing else we move the value to dptr */
8212     if (AOP_TYPE(left) != AOP_STR) {
8213         /* if this is remateriazable */
8214         if (AOP_TYPE(left) == AOP_IMMD)
8215             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8216         else { /* we need to get it byte by byte */
8217             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8218             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8219             if (options.model == MODEL_FLAT24)
8220             {
8221                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8222             }
8223         }
8224     }
8225     /* so dptr know contains the address */
8226     freeAsmop(left,NULL,ic,TRUE);
8227     aopOp(result,ic,FALSE);
8228
8229     /* if bit then unpack */
8230     if (IS_BITVAR(retype)) 
8231         genUnpackBits(result,"dptr",CPOINTER);
8232     else {
8233         size = AOP_SIZE(result);
8234         offset = 0 ;
8235
8236         while (size--) {
8237             pic14_emitcode("clr","a");
8238             pic14_emitcode("movc","a,@a+dptr");
8239             aopPut(AOP(result),"a",offset++);
8240             if (size)
8241                 pic14_emitcode("inc","dptr");
8242         }
8243     }
8244
8245     freeAsmop(result,NULL,ic,TRUE);
8246 }
8247 #endif
8248 /*-----------------------------------------------------------------*/
8249 /* genGenPointerGet - gget value from generic pointer space        */
8250 /*-----------------------------------------------------------------*/
8251 static void genGenPointerGet (operand *left,
8252                               operand *result, iCode *ic)
8253 {
8254   int size, offset ;
8255   sym_link *retype = getSpec(operandType(result));
8256
8257   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8258   aopOp(left,ic,FALSE);
8259   aopOp(result,ic,FALSE);
8260
8261
8262   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8263
8264   /* if the operand is already in dptr 
8265      then we do nothing else we move the value to dptr */
8266   //  if (AOP_TYPE(left) != AOP_STR) {
8267     /* if this is remateriazable */
8268     if (AOP_TYPE(left) == AOP_IMMD) {
8269       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8270       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8271     }
8272     else { /* we need to get it byte by byte */
8273
8274       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8275       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8276
8277       size = AOP_SIZE(result);
8278       offset = 0 ;
8279
8280       while(size--) {
8281         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8282         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8283         if(size)
8284           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8285       }
8286       goto release;
8287     }
8288     //}
8289   /* so dptr know contains the address */
8290
8291   /* if bit then unpack */
8292   //if (IS_BITVAR(retype)) 
8293   //  genUnpackBits(result,"dptr",GPOINTER);
8294
8295  release:
8296   freeAsmop(left,NULL,ic,TRUE);
8297   freeAsmop(result,NULL,ic,TRUE);
8298
8299 }
8300
8301 /*-----------------------------------------------------------------*/
8302 /* genConstPointerGet - get value from const generic pointer space */
8303 /*-----------------------------------------------------------------*/
8304 static void genConstPointerGet (operand *left,
8305                                 operand *result, iCode *ic)
8306 {
8307   //sym_link *retype = getSpec(operandType(result));
8308   symbol *albl = newiTempLabel(NULL);
8309   symbol *blbl = newiTempLabel(NULL);
8310   PIC_OPCODE poc;
8311
8312   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8313   aopOp(left,ic,FALSE);
8314   aopOp(result,ic,FALSE);
8315
8316
8317   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8318
8319   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8320
8321   emitpcode(POC_CALL,popGetLabel(albl->key));
8322   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8323   emitpLabel(albl->key);
8324
8325   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8326     
8327   emitpcode(poc,popGet(AOP(left),1));
8328   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8329   emitpcode(poc,popGet(AOP(left),0));
8330   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8331
8332   emitpLabel(blbl->key);
8333
8334   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8335
8336
8337   freeAsmop(left,NULL,ic,TRUE);
8338   freeAsmop(result,NULL,ic,TRUE);
8339
8340 }
8341 /*-----------------------------------------------------------------*/
8342 /* genPointerGet - generate code for pointer get                   */
8343 /*-----------------------------------------------------------------*/
8344 static void genPointerGet (iCode *ic)
8345 {
8346     operand *left, *result ;
8347     sym_link *type, *etype;
8348     int p_type;
8349
8350     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8351
8352     left = IC_LEFT(ic);
8353     result = IC_RESULT(ic) ;
8354
8355     /* depending on the type of pointer we need to
8356     move it to the correct pointer register */
8357     type = operandType(left);
8358     etype = getSpec(type);
8359
8360     if (IS_PTR_CONST(type))
8361       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8362
8363     /* if left is of type of pointer then it is simple */
8364     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8365         p_type = DCL_TYPE(type);
8366     else {
8367         /* we have to go by the storage class */
8368         p_type = PTR_TYPE(SPEC_OCLS(etype));
8369
8370         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8371
8372         if (SPEC_OCLS(etype)->codesp ) {
8373           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8374           //p_type = CPOINTER ; 
8375         }
8376         else
8377             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8378               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8379                /*p_type = FPOINTER ;*/ 
8380             else
8381                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8382                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8383 /*                  p_type = PPOINTER; */
8384                 else
8385                     if (SPEC_OCLS(etype) == idata )
8386                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8387 /*                      p_type = IPOINTER; */
8388                     else
8389                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8390 /*                      p_type = POINTER ; */
8391     }
8392
8393     /* now that we have the pointer type we assign
8394     the pointer values */
8395     switch (p_type) {
8396
8397     case POINTER:       
8398     case IPOINTER:
8399         genNearPointerGet (left,result,ic);
8400         break;
8401
8402     case PPOINTER:
8403         genPagedPointerGet(left,result,ic);
8404         break;
8405
8406     case FPOINTER:
8407         genFarPointerGet (left,result,ic);
8408         break;
8409
8410     case CPOINTER:
8411         genConstPointerGet (left,result,ic);
8412         //pic14_emitcodePointerGet (left,result,ic);
8413         break;
8414
8415     case GPOINTER:
8416       if (IS_PTR_CONST(type))
8417         genConstPointerGet (left,result,ic);
8418       else
8419         genGenPointerGet (left,result,ic);
8420       break;
8421     }
8422
8423 }
8424
8425 /*-----------------------------------------------------------------*/
8426 /* genPackBits - generates code for packed bit storage             */
8427 /*-----------------------------------------------------------------*/
8428 static void genPackBits (sym_link    *etype ,
8429                          operand *right ,
8430                          char *rname, int p_type)
8431 {
8432     int shCount = 0 ;
8433     int offset = 0  ;
8434     int rLen = 0 ;
8435     int blen, bstr ;   
8436     char *l ;
8437
8438     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8439     blen = SPEC_BLEN(etype);
8440     bstr = SPEC_BSTR(etype);
8441
8442     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8443     MOVA(l);   
8444
8445     /* if the bit lenth is less than or    */
8446     /* it exactly fits a byte then         */
8447     if (SPEC_BLEN(etype) <= 8 )  {
8448         shCount = SPEC_BSTR(etype) ;
8449
8450         /* shift left acc */
8451         AccLsh(shCount);
8452
8453         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8454
8455
8456             switch (p_type) {
8457                 case POINTER:
8458                     pic14_emitcode ("mov","b,a");
8459                     pic14_emitcode("mov","a,@%s",rname);
8460                     break;
8461
8462                 case FPOINTER:
8463                     pic14_emitcode ("mov","b,a");
8464                     pic14_emitcode("movx","a,@dptr");
8465                     break;
8466
8467                 case GPOINTER:
8468                     pic14_emitcode ("push","b");
8469                     pic14_emitcode ("push","acc");
8470                     pic14_emitcode ("lcall","__gptrget");
8471                     pic14_emitcode ("pop","b");
8472                     break;
8473             }
8474
8475             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8476                       ((unsigned char)(0xFF << (blen+bstr)) | 
8477                        (unsigned char)(0xFF >> (8-bstr)) ) );
8478             pic14_emitcode ("orl","a,b");
8479             if (p_type == GPOINTER)
8480                 pic14_emitcode("pop","b");
8481         }
8482     }
8483
8484     switch (p_type) {
8485         case POINTER:
8486             pic14_emitcode("mov","@%s,a",rname);
8487             break;
8488
8489         case FPOINTER:
8490             pic14_emitcode("movx","@dptr,a");
8491             break;
8492
8493         case GPOINTER:
8494             DEBUGpic14_emitcode(";lcall","__gptrput");
8495             break;
8496     }
8497
8498     /* if we r done */
8499     if ( SPEC_BLEN(etype) <= 8 )
8500         return ;
8501
8502     pic14_emitcode("inc","%s",rname);
8503     rLen = SPEC_BLEN(etype) ;     
8504
8505     /* now generate for lengths greater than one byte */
8506     while (1) {
8507
8508         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8509
8510         rLen -= 8 ;
8511         if (rLen <= 0 )
8512             break ;
8513
8514         switch (p_type) {
8515             case POINTER:
8516                 if (*l == '@') {
8517                     MOVA(l);
8518                     pic14_emitcode("mov","@%s,a",rname);
8519                 } else
8520                     pic14_emitcode("mov","@%s,%s",rname,l);
8521                 break;
8522
8523             case FPOINTER:
8524                 MOVA(l);
8525                 pic14_emitcode("movx","@dptr,a");
8526                 break;
8527
8528             case GPOINTER:
8529                 MOVA(l);
8530                 DEBUGpic14_emitcode(";lcall","__gptrput");
8531                 break;  
8532         }   
8533         pic14_emitcode ("inc","%s",rname);
8534     }
8535
8536     MOVA(l);
8537
8538     /* last last was not complete */
8539     if (rLen)   {
8540         /* save the byte & read byte */
8541         switch (p_type) {
8542             case POINTER:
8543                 pic14_emitcode ("mov","b,a");
8544                 pic14_emitcode("mov","a,@%s",rname);
8545                 break;
8546
8547             case FPOINTER:
8548                 pic14_emitcode ("mov","b,a");
8549                 pic14_emitcode("movx","a,@dptr");
8550                 break;
8551
8552             case GPOINTER:
8553                 pic14_emitcode ("push","b");
8554                 pic14_emitcode ("push","acc");
8555                 pic14_emitcode ("lcall","__gptrget");
8556                 pic14_emitcode ("pop","b");
8557                 break;
8558         }
8559
8560         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8561         pic14_emitcode ("orl","a,b");
8562     }
8563
8564     if (p_type == GPOINTER)
8565         pic14_emitcode("pop","b");
8566
8567     switch (p_type) {
8568
8569     case POINTER:
8570         pic14_emitcode("mov","@%s,a",rname);
8571         break;
8572         
8573     case FPOINTER:
8574         pic14_emitcode("movx","@dptr,a");
8575         break;
8576         
8577     case GPOINTER:
8578         DEBUGpic14_emitcode(";lcall","__gptrput");
8579         break;                  
8580     }
8581 }
8582 /*-----------------------------------------------------------------*/
8583 /* genDataPointerSet - remat pointer to data space                 */
8584 /*-----------------------------------------------------------------*/
8585 static void genDataPointerSet(operand *right,
8586                               operand *result,
8587                               iCode *ic)
8588 {
8589     int size, offset = 0 ;
8590     char *l, buffer[256];
8591
8592     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8593     aopOp(right,ic,FALSE);
8594     
8595     l = aopGet(AOP(result),0,FALSE,TRUE);
8596     size = AOP_SIZE(right);
8597 /*
8598     if ( AOP_TYPE(result) == AOP_PCODE) {
8599       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8600               AOP(result)->aopu.pcop->name,
8601               PCOI(AOP(result)->aopu.pcop)->offset);
8602     }
8603 */
8604
8605     // tsd, was l+1 - the underline `_' prefix was being stripped
8606     while (size--) {
8607       if (offset) {
8608         sprintf(buffer,"(%s + %d)",l,offset);
8609         fprintf(stderr,"oops  %s\n",buffer);
8610       } else
8611         sprintf(buffer,"%s",l);
8612
8613         if (AOP_TYPE(right) == AOP_LIT) {
8614           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8615           lit = lit >> (8*offset);
8616           if(lit&0xff) {
8617             pic14_emitcode("movlw","%d",lit);
8618             pic14_emitcode("movwf","%s",buffer);
8619
8620             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8621             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8622             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8623
8624           } else {
8625             pic14_emitcode("clrf","%s",buffer);
8626             //emitpcode(POC_CLRF, popRegFromString(buffer));
8627             emitpcode(POC_CLRF, popGet(AOP(result),0));
8628           }
8629         }else {
8630           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8631           pic14_emitcode("movwf","%s",buffer);
8632
8633           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8634           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8635           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8636
8637         }
8638
8639         offset++;
8640     }
8641
8642     freeAsmop(right,NULL,ic,TRUE);
8643     freeAsmop(result,NULL,ic,TRUE);
8644 }
8645
8646 /*-----------------------------------------------------------------*/
8647 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8648 /*-----------------------------------------------------------------*/
8649 static void genNearPointerSet (operand *right,
8650                                operand *result, 
8651                                iCode *ic)
8652 {
8653   asmop *aop = NULL;
8654   char *l;
8655   sym_link *retype;
8656   sym_link *ptype = operandType(result);
8657
8658     
8659   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8660   retype= getSpec(operandType(right));
8661
8662   aopOp(result,ic,FALSE);
8663
8664     
8665   /* if the result is rematerializable &
8666      in data space & not a bit variable */
8667   //if (AOP_TYPE(result) == AOP_IMMD &&
8668   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8669       DCL_TYPE(ptype) == POINTER   &&
8670       !IS_BITVAR(retype)) {
8671     genDataPointerSet (right,result,ic);
8672     freeAsmop(result,NULL,ic,TRUE);
8673     return;
8674   }
8675
8676   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8677   aopOp(right,ic,FALSE);
8678   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8679
8680   /* if the value is already in a pointer register
8681      then don't need anything more */
8682   if (!AOP_INPREG(AOP(result))) {
8683     /* otherwise get a free pointer register */
8684     //aop = newAsmop(0);
8685     //preg = getFreePtr(ic,&aop,FALSE);
8686     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8687     //pic14_emitcode("mov","%s,%s",
8688     //         preg->name,
8689     //         aopGet(AOP(result),0,FALSE,TRUE));
8690     //rname = preg->name ;
8691     //pic14_emitcode("movwf","fsr");
8692     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8693     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8694     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8695     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8696     goto release;
8697
8698   }// else
8699   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8700
8701
8702   /* if bitfield then unpack the bits */
8703   if (IS_BITVAR(retype)) {
8704     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8705            "The programmer is obviously confused");
8706     //genPackBits (retype,right,rname,POINTER);
8707     exit(1);
8708   }
8709   else {
8710     /* we have can just get the values */
8711     int size = AOP_SIZE(right);
8712     int offset = 0 ;    
8713
8714     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8715     while (size--) {
8716       l = aopGet(AOP(right),offset,FALSE,TRUE);
8717       if (*l == '@' ) {
8718         //MOVA(l);
8719         //pic14_emitcode("mov","@%s,a",rname);
8720         pic14_emitcode("movf","indf,w ;1");
8721       } else {
8722
8723         if (AOP_TYPE(right) == AOP_LIT) {
8724           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8725           if(lit) {
8726             pic14_emitcode("movlw","%s",l);
8727             pic14_emitcode("movwf","indf ;2");
8728           } else 
8729             pic14_emitcode("clrf","indf");
8730         }else {
8731           pic14_emitcode("movf","%s,w",l);
8732           pic14_emitcode("movwf","indf ;2");
8733         }
8734         //pic14_emitcode("mov","@%s,%s",rname,l);
8735       }
8736       if (size)
8737         pic14_emitcode("incf","fsr,f ;3");
8738       //pic14_emitcode("inc","%s",rname);
8739       offset++;
8740     }
8741   }
8742
8743   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8744   /* now some housekeeping stuff */
8745   if (aop) {
8746     /* we had to allocate for this iCode */
8747     freeAsmop(NULL,aop,ic,TRUE);
8748   } else { 
8749     /* we did not allocate which means left
8750        already in a pointer register, then
8751        if size > 0 && this could be used again
8752        we have to point it back to where it 
8753        belongs */
8754     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8755     if (AOP_SIZE(right) > 1 &&
8756         !OP_SYMBOL(result)->remat &&
8757         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8758           ic->depth )) {
8759       int size = AOP_SIZE(right) - 1;
8760       while (size--)
8761         pic14_emitcode("decf","fsr,f");
8762       //pic14_emitcode("dec","%s",rname);
8763     }
8764   }
8765
8766   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8767   /* done */
8768  release:
8769   freeAsmop(right,NULL,ic,TRUE);
8770   freeAsmop(result,NULL,ic,TRUE);
8771 }
8772
8773 /*-----------------------------------------------------------------*/
8774 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8775 /*-----------------------------------------------------------------*/
8776 static void genPagedPointerSet (operand *right,
8777                                operand *result, 
8778                                iCode *ic)
8779 {
8780     asmop *aop = NULL;
8781     regs *preg = NULL ;
8782     char *rname , *l;
8783     sym_link *retype;
8784        
8785     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8786
8787     retype= getSpec(operandType(right));
8788     
8789     aopOp(result,ic,FALSE);
8790     
8791     /* if the value is already in a pointer register
8792        then don't need anything more */
8793     if (!AOP_INPREG(AOP(result))) {
8794         /* otherwise get a free pointer register */
8795         aop = newAsmop(0);
8796         preg = getFreePtr(ic,&aop,FALSE);
8797         pic14_emitcode("mov","%s,%s",
8798                 preg->name,
8799                 aopGet(AOP(result),0,FALSE,TRUE));
8800         rname = preg->name ;
8801     } else
8802         rname = aopGet(AOP(result),0,FALSE,FALSE);
8803     
8804     freeAsmop(result,NULL,ic,TRUE);
8805     aopOp (right,ic,FALSE);
8806
8807     /* if bitfield then unpack the bits */
8808     if (IS_BITVAR(retype)) 
8809         genPackBits (retype,right,rname,PPOINTER);
8810     else {
8811         /* we have can just get the values */
8812         int size = AOP_SIZE(right);
8813         int offset = 0 ;        
8814         
8815         while (size--) {
8816             l = aopGet(AOP(right),offset,FALSE,TRUE);
8817             
8818             MOVA(l);
8819             pic14_emitcode("movx","@%s,a",rname);
8820
8821             if (size)
8822                 pic14_emitcode("inc","%s",rname);
8823
8824             offset++;
8825         }
8826     }
8827     
8828     /* now some housekeeping stuff */
8829     if (aop) {
8830         /* we had to allocate for this iCode */
8831         freeAsmop(NULL,aop,ic,TRUE);
8832     } else { 
8833         /* we did not allocate which means left
8834            already in a pointer register, then
8835            if size > 0 && this could be used again
8836            we have to point it back to where it 
8837            belongs */
8838         if (AOP_SIZE(right) > 1 &&
8839             !OP_SYMBOL(result)->remat &&
8840             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8841               ic->depth )) {
8842             int size = AOP_SIZE(right) - 1;
8843             while (size--)
8844                 pic14_emitcode("dec","%s",rname);
8845         }
8846     }
8847
8848     /* done */
8849     freeAsmop(right,NULL,ic,TRUE);
8850     
8851         
8852 }
8853
8854 /*-----------------------------------------------------------------*/
8855 /* genFarPointerSet - set value from far space                     */
8856 /*-----------------------------------------------------------------*/
8857 static void genFarPointerSet (operand *right,
8858                               operand *result, iCode *ic)
8859 {
8860     int size, offset ;
8861     sym_link *retype = getSpec(operandType(right));
8862
8863     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8864     aopOp(result,ic,FALSE);
8865
8866     /* if the operand is already in dptr 
8867     then we do nothing else we move the value to dptr */
8868     if (AOP_TYPE(result) != AOP_STR) {
8869         /* if this is remateriazable */
8870         if (AOP_TYPE(result) == AOP_IMMD)
8871             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8872         else { /* we need to get it byte by byte */
8873             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8874             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8875             if (options.model == MODEL_FLAT24)
8876             {
8877                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8878             }
8879         }
8880     }
8881     /* so dptr know contains the address */
8882     freeAsmop(result,NULL,ic,TRUE);
8883     aopOp(right,ic,FALSE);
8884
8885     /* if bit then unpack */
8886     if (IS_BITVAR(retype)) 
8887         genPackBits(retype,right,"dptr",FPOINTER);
8888     else {
8889         size = AOP_SIZE(right);
8890         offset = 0 ;
8891
8892         while (size--) {
8893             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8894             MOVA(l);
8895             pic14_emitcode("movx","@dptr,a");
8896             if (size)
8897                 pic14_emitcode("inc","dptr");
8898         }
8899     }
8900
8901     freeAsmop(right,NULL,ic,TRUE);
8902 }
8903
8904 /*-----------------------------------------------------------------*/
8905 /* genGenPointerSet - set value from generic pointer space         */
8906 /*-----------------------------------------------------------------*/
8907 static void genGenPointerSet (operand *right,
8908                               operand *result, iCode *ic)
8909 {
8910   int size, offset ;
8911   sym_link *retype = getSpec(operandType(right));
8912
8913   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8914
8915   aopOp(result,ic,FALSE);
8916   aopOp(right,ic,FALSE);
8917   size = AOP_SIZE(right);
8918
8919   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8920
8921   /* if the operand is already in dptr 
8922      then we do nothing else we move the value to dptr */
8923   if (AOP_TYPE(result) != AOP_STR) {
8924     /* if this is remateriazable */
8925     if (AOP_TYPE(result) == AOP_IMMD) {
8926       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8927       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8928     }
8929     else { /* we need to get it byte by byte */
8930       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8931       size = AOP_SIZE(right);
8932       offset = 0 ;
8933
8934       /* hack hack! see if this the FSR. If so don't load W */
8935       if(AOP_TYPE(right) != AOP_ACC) {
8936
8937         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8938         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8939
8940         //if(size==2)
8941         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8942         //if(size==4) {
8943         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8944         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8945         //}
8946
8947         while(size--) {
8948           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8949           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8950           
8951           if(size)
8952             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8953         }
8954
8955
8956         goto release;
8957       } 
8958
8959       if(aopIdx(AOP(result),0) != 4) {
8960
8961         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8962         goto release;
8963       }
8964
8965       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8966       goto release;
8967
8968     }
8969   }
8970   /* so dptr know contains the address */
8971
8972
8973   /* if bit then unpack */
8974   if (IS_BITVAR(retype)) 
8975     genPackBits(retype,right,"dptr",GPOINTER);
8976   else {
8977     size = AOP_SIZE(right);
8978     offset = 0 ;
8979
8980   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8981
8982     while (size--) {
8983
8984       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8985       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8986
8987       if (AOP_TYPE(right) == AOP_LIT) 
8988         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8989       else
8990         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8991
8992       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8993
8994       offset++;
8995     }
8996   }
8997
8998  release:
8999   freeAsmop(right,NULL,ic,TRUE);
9000   freeAsmop(result,NULL,ic,TRUE);
9001 }
9002
9003 /*-----------------------------------------------------------------*/
9004 /* genPointerSet - stores the value into a pointer location        */
9005 /*-----------------------------------------------------------------*/
9006 static void genPointerSet (iCode *ic)
9007 {    
9008     operand *right, *result ;
9009     sym_link *type, *etype;
9010     int p_type;
9011
9012     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9013
9014     right = IC_RIGHT(ic);
9015     result = IC_RESULT(ic) ;
9016
9017     /* depending on the type of pointer we need to
9018     move it to the correct pointer register */
9019     type = operandType(result);
9020     etype = getSpec(type);
9021     /* if left is of type of pointer then it is simple */
9022     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9023         p_type = DCL_TYPE(type);
9024     }
9025     else {
9026         /* we have to go by the storage class */
9027         p_type = PTR_TYPE(SPEC_OCLS(etype));
9028
9029 /*      if (SPEC_OCLS(etype)->codesp ) { */
9030 /*          p_type = CPOINTER ;  */
9031 /*      } */
9032 /*      else */
9033 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9034 /*              p_type = FPOINTER ; */
9035 /*          else */
9036 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9037 /*                  p_type = PPOINTER ; */
9038 /*              else */
9039 /*                  if (SPEC_OCLS(etype) == idata ) */
9040 /*                      p_type = IPOINTER ; */
9041 /*                  else */
9042 /*                      p_type = POINTER ; */
9043     }
9044
9045     /* now that we have the pointer type we assign
9046     the pointer values */
9047     switch (p_type) {
9048
9049     case POINTER:
9050     case IPOINTER:
9051         genNearPointerSet (right,result,ic);
9052         break;
9053
9054     case PPOINTER:
9055         genPagedPointerSet (right,result,ic);
9056         break;
9057
9058     case FPOINTER:
9059         genFarPointerSet (right,result,ic);
9060         break;
9061
9062     case GPOINTER:
9063         genGenPointerSet (right,result,ic);
9064         break;
9065
9066     default:
9067       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9068               "genPointerSet: illegal pointer type");
9069     }
9070 }
9071
9072 /*-----------------------------------------------------------------*/
9073 /* genIfx - generate code for Ifx statement                        */
9074 /*-----------------------------------------------------------------*/
9075 static void genIfx (iCode *ic, iCode *popIc)
9076 {
9077   operand *cond = IC_COND(ic);
9078   int isbit =0;
9079
9080   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9081
9082   aopOp(cond,ic,FALSE);
9083
9084   /* get the value into acc */
9085   if (AOP_TYPE(cond) != AOP_CRY)
9086     pic14_toBoolean(cond);
9087   else
9088     isbit = 1;
9089   /* the result is now in the accumulator */
9090   freeAsmop(cond,NULL,ic,TRUE);
9091
9092   /* if there was something to be popped then do it */
9093   if (popIc)
9094     genIpop(popIc);
9095
9096   /* if the condition is  a bit variable */
9097   if (isbit && IS_ITEMP(cond) && 
9098       SPIL_LOC(cond)) {
9099     genIfxJump(ic,SPIL_LOC(cond)->rname);
9100     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9101   }
9102   else {
9103     if (isbit && !IS_ITEMP(cond))
9104       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9105     else
9106       genIfxJump(ic,"a");
9107   }
9108   ic->generated = 1;
9109
9110 }
9111
9112 /*-----------------------------------------------------------------*/
9113 /* genAddrOf - generates code for address of                       */
9114 /*-----------------------------------------------------------------*/
9115 static void genAddrOf (iCode *ic)
9116 {
9117   operand *right, *result, *left;
9118   int size, offset ;
9119
9120   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9121
9122
9123   //aopOp(IC_RESULT(ic),ic,FALSE);
9124
9125   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9126   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9127   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9128
9129   DEBUGpic14_AopType(__LINE__,left,right,result);
9130
9131   size = AOP_SIZE(IC_RESULT(ic));
9132   offset = 0;
9133
9134   while (size--) {
9135     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9136     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9137     offset++;
9138   }
9139
9140   freeAsmop(left,NULL,ic,FALSE);
9141   freeAsmop(result,NULL,ic,TRUE);
9142
9143 }
9144
9145 #if 0
9146 /*-----------------------------------------------------------------*/
9147 /* genFarFarAssign - assignment when both are in far space         */
9148 /*-----------------------------------------------------------------*/
9149 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9150 {
9151     int size = AOP_SIZE(right);
9152     int offset = 0;
9153     char *l ;
9154     /* first push the right side on to the stack */
9155     while (size--) {
9156         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9157         MOVA(l);
9158         pic14_emitcode ("push","acc");
9159     }
9160     
9161     freeAsmop(right,NULL,ic,FALSE);
9162     /* now assign DPTR to result */
9163     aopOp(result,ic,FALSE);
9164     size = AOP_SIZE(result);
9165     while (size--) {
9166         pic14_emitcode ("pop","acc");
9167         aopPut(AOP(result),"a",--offset);
9168     }
9169     freeAsmop(result,NULL,ic,FALSE);
9170         
9171 }
9172 #endif
9173
9174 /*-----------------------------------------------------------------*/
9175 /* genAssign - generate code for assignment                        */
9176 /*-----------------------------------------------------------------*/
9177 static void genAssign (iCode *ic)
9178 {
9179   operand *result, *right;
9180   int size, offset,know_W;
9181   unsigned long lit = 0L;
9182
9183   result = IC_RESULT(ic);
9184   right  = IC_RIGHT(ic) ;
9185
9186   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9187
9188   /* if they are the same */
9189   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9190     return ;
9191
9192   aopOp(right,ic,FALSE);
9193   aopOp(result,ic,TRUE);
9194
9195   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9196
9197   /* if they are the same registers */
9198   if (pic14_sameRegs(AOP(right),AOP(result)))
9199     goto release;
9200
9201   /* if the result is a bit */
9202   if (AOP_TYPE(result) == AOP_CRY) {
9203
9204     /* if the right size is a literal then
9205        we know what the value is */
9206     if (AOP_TYPE(right) == AOP_LIT) {
9207           
9208       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9209                   popGet(AOP(result),0));
9210
9211       if (((int) operandLitValue(right))) 
9212         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9213                        AOP(result)->aopu.aop_dir,
9214                        AOP(result)->aopu.aop_dir);
9215       else
9216         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9217                        AOP(result)->aopu.aop_dir,
9218                        AOP(result)->aopu.aop_dir);
9219       goto release;
9220     }
9221
9222     /* the right is also a bit variable */
9223     if (AOP_TYPE(right) == AOP_CRY) {
9224       emitpcode(POC_BCF,    popGet(AOP(result),0));
9225       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9226       emitpcode(POC_BSF,    popGet(AOP(result),0));
9227
9228       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9229                      AOP(result)->aopu.aop_dir,
9230                      AOP(result)->aopu.aop_dir);
9231       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9232                      AOP(right)->aopu.aop_dir,
9233                      AOP(right)->aopu.aop_dir);
9234       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9235                      AOP(result)->aopu.aop_dir,
9236                      AOP(result)->aopu.aop_dir);
9237       goto release ;
9238     }
9239
9240     /* we need to or */
9241     emitpcode(POC_BCF,    popGet(AOP(result),0));
9242     pic14_toBoolean(right);
9243     emitSKPZ;
9244     emitpcode(POC_BSF,    popGet(AOP(result),0));
9245     //aopPut(AOP(result),"a",0);
9246     goto release ;
9247   }
9248
9249   /* bit variables done */
9250   /* general case */
9251   size = AOP_SIZE(result);
9252   offset = 0 ;
9253   if(AOP_TYPE(right) == AOP_LIT)
9254     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9255
9256   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9257   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9258     if(aopIdx(AOP(result),0) == 4) {
9259   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9260       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9261       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9262       goto release;
9263     } else
9264       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9265   }
9266
9267   know_W=-1;
9268   while (size--) {
9269   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9270     if(AOP_TYPE(right) == AOP_LIT) {
9271       if(lit&0xff) {
9272         if(know_W != (lit&0xff))
9273           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9274         know_W = lit&0xff;
9275         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9276       } else
9277         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9278
9279       lit >>= 8;
9280
9281     } else if (AOP_TYPE(right) == AOP_CRY) {
9282       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9283       if(offset == 0) {
9284         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9285         emitpcode(POC_INCF, popGet(AOP(result),0));
9286       }
9287     } else {
9288   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9289       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9290       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9291     }
9292             
9293     offset++;
9294   }
9295
9296     
9297  release:
9298   freeAsmop (right,NULL,ic,FALSE);
9299   freeAsmop (result,NULL,ic,TRUE);
9300 }   
9301
9302 /*-----------------------------------------------------------------*/
9303 /* genJumpTab - genrates code for jump table                       */
9304 /*-----------------------------------------------------------------*/
9305 static void genJumpTab (iCode *ic)
9306 {
9307     symbol *jtab;
9308     char *l;
9309
9310     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9311
9312     aopOp(IC_JTCOND(ic),ic,FALSE);
9313     /* get the condition into accumulator */
9314     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9315     MOVA(l);
9316     /* multiply by three */
9317     pic14_emitcode("add","a,acc");
9318     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9319
9320     jtab = newiTempLabel(NULL);
9321     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9322     pic14_emitcode("jmp","@a+dptr");
9323     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9324
9325     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9326     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9327     emitSKPNC;
9328     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9329     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9330     emitpLabel(jtab->key);
9331
9332     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9333
9334     /* now generate the jump labels */
9335     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9336          jtab = setNextItem(IC_JTLABELS(ic))) {
9337         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9338         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9339         
9340     }
9341
9342 }
9343
9344 /*-----------------------------------------------------------------*/
9345 /* genMixedOperation - gen code for operators between mixed types  */
9346 /*-----------------------------------------------------------------*/
9347 /*
9348   TSD - Written for the PIC port - but this unfortunately is buggy.
9349   This routine is good in that it is able to efficiently promote 
9350   types to different (larger) sizes. Unfortunately, the temporary
9351   variables that are optimized out by this routine are sometimes
9352   used in other places. So until I know how to really parse the 
9353   iCode tree, I'm going to not be using this routine :(.
9354 */
9355 static int genMixedOperation (iCode *ic)
9356 {
9357 #if 0
9358   operand *result = IC_RESULT(ic);
9359   sym_link *ctype = operandType(IC_LEFT(ic));
9360   operand *right = IC_RIGHT(ic);
9361   int ret = 0;
9362   int big,small;
9363   int offset;
9364
9365   iCode *nextic;
9366   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9367
9368   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9369
9370   nextic = ic->next;
9371   if(!nextic)
9372     return 0;
9373
9374   nextright = IC_RIGHT(nextic);
9375   nextleft  = IC_LEFT(nextic);
9376   nextresult = IC_RESULT(nextic);
9377
9378   aopOp(right,ic,FALSE);
9379   aopOp(result,ic,FALSE);
9380   aopOp(nextright,  nextic, FALSE);
9381   aopOp(nextleft,   nextic, FALSE);
9382   aopOp(nextresult, nextic, FALSE);
9383
9384   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9385
9386     operand *t = right;
9387     right = nextright;
9388     nextright = t; 
9389
9390     pic14_emitcode(";remove right +","");
9391
9392   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9393 /*
9394     operand *t = right;
9395     right = nextleft;
9396     nextleft = t; 
9397 */
9398     pic14_emitcode(";remove left +","");
9399   } else
9400     return 0;
9401
9402   big = AOP_SIZE(nextleft);
9403   small = AOP_SIZE(nextright);
9404
9405   switch(nextic->op) {
9406
9407   case '+':
9408     pic14_emitcode(";optimize a +","");
9409     /* if unsigned or not an integral type */
9410     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9411       pic14_emitcode(";add a bit to something","");
9412     } else {
9413
9414       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9415
9416       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9417         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9418         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9419       } else
9420         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9421
9422       offset = 0;
9423       while(--big) {
9424
9425         offset++;
9426
9427         if(--small) {
9428           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9429             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9430             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9431           }
9432
9433           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9434           emitSKPNC;
9435           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9436                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9437                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9438           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9439           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9440
9441         } else {
9442           pic14_emitcode("rlf","known_zero,w");
9443
9444           /*
9445             if right is signed
9446               btfsc  right,7
9447                addlw ff
9448           */
9449           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9450             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9451             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9452           } else {
9453             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9454           }
9455         }
9456       }
9457       ret = 1;
9458     }
9459   }
9460   ret = 1;
9461
9462 release:
9463   freeAsmop(right,NULL,ic,TRUE);
9464   freeAsmop(result,NULL,ic,TRUE);
9465   freeAsmop(nextright,NULL,ic,TRUE);
9466   freeAsmop(nextleft,NULL,ic,TRUE);
9467   if(ret)
9468     nextic->generated = 1;
9469
9470   return ret;
9471 #else
9472   return 0;
9473 #endif
9474 }
9475 /*-----------------------------------------------------------------*/
9476 /* genCast - gen code for casting                                  */
9477 /*-----------------------------------------------------------------*/
9478 static void genCast (iCode *ic)
9479 {
9480     operand *result = IC_RESULT(ic);
9481     sym_link *ctype = operandType(IC_LEFT(ic));
9482     sym_link *rtype = operandType(IC_RIGHT(ic));
9483     operand *right = IC_RIGHT(ic);
9484     int size, offset ;
9485
9486     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9487     /* if they are equivalent then do nothing */
9488     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9489         return ;
9490
9491     aopOp(right,ic,FALSE) ;
9492     aopOp(result,ic,FALSE);
9493
9494     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9495
9496     /* if the result is a bit */
9497     if (AOP_TYPE(result) == AOP_CRY) {
9498         /* if the right size is a literal then
9499         we know what the value is */
9500       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9501         if (AOP_TYPE(right) == AOP_LIT) {
9502
9503           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9504                       popGet(AOP(result),0));
9505
9506             if (((int) operandLitValue(right))) 
9507               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9508                        AOP(result)->aopu.aop_dir,
9509                        AOP(result)->aopu.aop_dir);
9510             else
9511               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9512                        AOP(result)->aopu.aop_dir,
9513                        AOP(result)->aopu.aop_dir);
9514
9515             goto release;
9516         }
9517
9518         /* the right is also a bit variable */
9519         if (AOP_TYPE(right) == AOP_CRY) {
9520
9521           emitCLRC;
9522           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9523
9524           pic14_emitcode("clrc","");
9525           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9526                    AOP(right)->aopu.aop_dir,
9527                    AOP(right)->aopu.aop_dir);
9528             aopPut(AOP(result),"c",0);
9529             goto release ;
9530         }
9531
9532         /* we need to or */
9533         if (AOP_TYPE(right) == AOP_REG) {
9534           emitpcode(POC_BCF,    popGet(AOP(result),0));
9535           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9536           emitpcode(POC_BSF,    popGet(AOP(result),0));
9537         }
9538         pic14_toBoolean(right);
9539         aopPut(AOP(result),"a",0);
9540         goto release ;
9541     }
9542
9543     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9544       int offset = 1;
9545       size = AOP_SIZE(result);
9546
9547       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9548
9549       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9550       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9551       emitpcode(POC_INCF,   popGet(AOP(result),0));
9552
9553       while (size--)
9554         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9555
9556       goto release;
9557     }
9558
9559     /* if they are the same size : or less */
9560     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9561
9562         /* if they are in the same place */
9563       if (pic14_sameRegs(AOP(right),AOP(result)))
9564         goto release;
9565
9566       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9567       if (IS_PTR_CONST(rtype))
9568         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9569       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9570         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9571
9572       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9573         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9574         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9575         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9576         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9577         if(AOP_SIZE(result) <2)
9578           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9579
9580       } else {
9581
9582         /* if they in different places then copy */
9583         size = AOP_SIZE(result);
9584         offset = 0 ;
9585         while (size--) {
9586           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9587           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9588
9589           //aopPut(AOP(result),
9590           // aopGet(AOP(right),offset,FALSE,FALSE),
9591           // offset);
9592
9593           offset++;
9594         }
9595       }
9596       goto release;
9597     }
9598
9599
9600     /* if the result is of type pointer */
9601     if (IS_PTR(ctype)) {
9602
9603         int p_type;
9604         sym_link *type = operandType(right);
9605         sym_link *etype = getSpec(type);
9606       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9607
9608         /* pointer to generic pointer */
9609         if (IS_GENPTR(ctype)) {
9610             char *l = zero;
9611             
9612             if (IS_PTR(type)) 
9613                 p_type = DCL_TYPE(type);
9614             else {
9615                 /* we have to go by the storage class */
9616                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9617
9618 /*              if (SPEC_OCLS(etype)->codesp )  */
9619 /*                  p_type = CPOINTER ;  */
9620 /*              else */
9621 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9622 /*                      p_type = FPOINTER ; */
9623 /*                  else */
9624 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9625 /*                          p_type = PPOINTER; */
9626 /*                      else */
9627 /*                          if (SPEC_OCLS(etype) == idata ) */
9628 /*                              p_type = IPOINTER ; */
9629 /*                          else */
9630 /*                              p_type = POINTER ; */
9631             }
9632                 
9633             /* the first two bytes are known */
9634       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9635             size = GPTRSIZE - 1; 
9636             offset = 0 ;
9637             while (size--) {
9638               if(offset < AOP_SIZE(right)) {
9639       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9640                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9641                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9642                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9643                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9644                 } else { 
9645                   aopPut(AOP(result),
9646                          aopGet(AOP(right),offset,FALSE,FALSE),
9647                          offset);
9648                 }
9649               } else 
9650                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9651               offset++;
9652             }
9653             /* the last byte depending on type */
9654             switch (p_type) {
9655             case IPOINTER:
9656             case POINTER:
9657                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9658                 break;
9659             case FPOINTER:
9660               pic14_emitcode(";BUG!? ","%d",__LINE__);
9661                 l = one;
9662                 break;
9663             case CPOINTER:
9664               pic14_emitcode(";BUG!? ","%d",__LINE__);
9665                 l = "#0x02";
9666                 break;                          
9667             case PPOINTER:
9668               pic14_emitcode(";BUG!? ","%d",__LINE__);
9669                 l = "#0x03";
9670                 break;
9671                 
9672             default:
9673                 /* this should never happen */
9674                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9675                        "got unknown pointer type");
9676                 exit(1);
9677             }
9678             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9679             goto release ;
9680         }
9681         
9682         /* just copy the pointers */
9683         size = AOP_SIZE(result);
9684         offset = 0 ;
9685         while (size--) {
9686             aopPut(AOP(result),
9687                    aopGet(AOP(right),offset,FALSE,FALSE),
9688                    offset);
9689             offset++;
9690         }
9691         goto release ;
9692     }
9693     
9694
9695
9696     /* so we now know that the size of destination is greater
9697     than the size of the source.
9698     Now, if the next iCode is an operator then we might be
9699     able to optimize the operation without performing a cast.
9700     */
9701     if(genMixedOperation(ic))
9702       goto release;
9703
9704     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9705     
9706     /* we move to result for the size of source */
9707     size = AOP_SIZE(right);
9708     offset = 0 ;
9709     while (size--) {
9710       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9711       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9712       offset++;
9713     }
9714
9715     /* now depending on the sign of the destination */
9716     size = AOP_SIZE(result) - AOP_SIZE(right);
9717     /* if unsigned or not an integral type */
9718     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9719       while (size--)
9720         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9721     } else {
9722       /* we need to extend the sign :{ */
9723
9724       if(size == 1) {
9725         /* Save one instruction of casting char to int */
9726         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9727         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9728         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9729       } else {
9730         emitpcodeNULLop(POC_CLRW);
9731
9732         if(offset)
9733           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9734         else
9735           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9736         
9737         emitpcode(POC_MOVLW,   popGetLit(0xff));
9738
9739         while (size--)
9740           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9741       }
9742     }
9743
9744 release:
9745     freeAsmop(right,NULL,ic,TRUE);
9746     freeAsmop(result,NULL,ic,TRUE);
9747
9748 }
9749
9750 /*-----------------------------------------------------------------*/
9751 /* genDjnz - generate decrement & jump if not zero instrucion      */
9752 /*-----------------------------------------------------------------*/
9753 static int genDjnz (iCode *ic, iCode *ifx)
9754 {
9755     symbol *lbl, *lbl1;
9756     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9757
9758     if (!ifx)
9759         return 0;
9760     
9761     /* if the if condition has a false label
9762        then we cannot save */
9763     if (IC_FALSE(ifx))
9764         return 0;
9765
9766     /* if the minus is not of the form 
9767        a = a - 1 */
9768     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9769         !IS_OP_LITERAL(IC_RIGHT(ic)))
9770         return 0;
9771
9772     if (operandLitValue(IC_RIGHT(ic)) != 1)
9773         return 0;
9774
9775     /* if the size of this greater than one then no
9776        saving */
9777     if (getSize(operandType(IC_RESULT(ic))) > 1)
9778         return 0;
9779
9780     /* otherwise we can save BIG */
9781     lbl = newiTempLabel(NULL);
9782     lbl1= newiTempLabel(NULL);
9783
9784     aopOp(IC_RESULT(ic),ic,FALSE);
9785     
9786     if (IS_AOP_PREG(IC_RESULT(ic))) {
9787         pic14_emitcode("dec","%s",
9788                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9789         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9790         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9791     } else {    
9792
9793
9794       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9795       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9796
9797       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9798       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9799
9800     }
9801 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9802 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9803 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9804 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9805
9806     
9807     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9808     ifx->generated = 1;
9809     return 1;
9810 }
9811
9812 /*-----------------------------------------------------------------*/
9813 /* genReceive - generate code for a receive iCode                  */
9814 /*-----------------------------------------------------------------*/
9815 static void genReceive (iCode *ic)
9816 {    
9817   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9818
9819   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9820       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9821         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9822
9823     int size = getSize(operandType(IC_RESULT(ic)));
9824     int offset =  fReturnSizePic - size;
9825     while (size--) {
9826       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9827                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9828       offset++;
9829     }
9830     aopOp(IC_RESULT(ic),ic,FALSE);  
9831     size = AOP_SIZE(IC_RESULT(ic));
9832     offset = 0;
9833     while (size--) {
9834       pic14_emitcode ("pop","acc");
9835       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9836     }
9837         
9838   } else {
9839     _G.accInUse++;
9840     aopOp(IC_RESULT(ic),ic,FALSE);  
9841     _G.accInUse--;
9842     assignResultValue(IC_RESULT(ic));   
9843   }
9844
9845   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9846 }
9847
9848 /*-----------------------------------------------------------------*/
9849 /* genpic14Code - generate code for pic14 based controllers        */
9850 /*-----------------------------------------------------------------*/
9851 /*
9852  * At this point, ralloc.c has gone through the iCode and attempted
9853  * to optimize in a way suitable for a PIC. Now we've got to generate
9854  * PIC instructions that correspond to the iCode.
9855  *
9856  * Once the instructions are generated, we'll pass through both the
9857  * peep hole optimizer and the pCode optimizer.
9858  *-----------------------------------------------------------------*/
9859
9860 void genpic14Code (iCode *lic)
9861 {
9862     iCode *ic;
9863     int cln = 0;
9864
9865     lineHead = lineCurr = NULL;
9866
9867     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9868     addpBlock(pb);
9869
9870     /* if debug information required */
9871     if (options.debug && currFunc) { 
9872       if (currFunc) {
9873         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9874         _G.debugLine = 1;
9875         if (IS_STATIC(currFunc->etype)) {
9876           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9877           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9878         } else {
9879           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9880           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9881         }
9882         _G.debugLine = 0;
9883       }
9884     }
9885
9886
9887     for (ic = lic ; ic ; ic = ic->next ) {
9888
9889       DEBUGpic14_emitcode(";ic","");
9890         if ( cln != ic->lineno ) {
9891             if ( options.debug ) {
9892                 _G.debugLine = 1;
9893                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9894                          FileBaseName(ic->filename),ic->lineno,
9895                          ic->level,ic->block);
9896                 _G.debugLine = 0;
9897             }
9898             /*
9899               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9900               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9901               printCLine(ic->filename, ic->lineno));
9902             */
9903             addpCode2pBlock(pb,
9904                             newpCodeCSource(ic->lineno, 
9905                                             ic->filename, 
9906                                             printCLine(ic->filename, ic->lineno)));
9907
9908             cln = ic->lineno ;
9909         }
9910         /* if the result is marked as
9911            spilt and rematerializable or code for
9912            this has already been generated then
9913            do nothing */
9914         if (resultRemat(ic) || ic->generated ) 
9915             continue ;
9916         
9917         /* depending on the operation */
9918         switch (ic->op) {
9919         case '!' :
9920             genNot(ic);
9921             break;
9922             
9923         case '~' :
9924             genCpl(ic);
9925             break;
9926             
9927         case UNARYMINUS:
9928             genUminus (ic);
9929             break;
9930             
9931         case IPUSH:
9932             genIpush (ic);
9933             break;
9934             
9935         case IPOP:
9936             /* IPOP happens only when trying to restore a 
9937                spilt live range, if there is an ifx statement
9938                following this pop then the if statement might
9939                be using some of the registers being popped which
9940                would destory the contents of the register so
9941                we need to check for this condition and handle it */
9942             if (ic->next            && 
9943                 ic->next->op == IFX &&
9944                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9945                 genIfx (ic->next,ic);
9946             else
9947                 genIpop (ic);
9948             break; 
9949             
9950         case CALL:
9951             genCall (ic);
9952             break;
9953             
9954         case PCALL:
9955             genPcall (ic);
9956             break;
9957             
9958         case FUNCTION:
9959             genFunction (ic);
9960             break;
9961             
9962         case ENDFUNCTION:
9963             genEndFunction (ic);
9964             break;
9965             
9966         case RETURN:
9967             genRet (ic);
9968             break;
9969             
9970         case LABEL:
9971             genLabel (ic);
9972             break;
9973             
9974         case GOTO:
9975             genGoto (ic);
9976             break;
9977             
9978         case '+' :
9979             genPlus (ic) ;
9980             break;
9981             
9982         case '-' :
9983             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9984                 genMinus (ic);
9985             break;
9986             
9987         case '*' :
9988             genMult (ic);
9989             break;
9990             
9991         case '/' :
9992             genDiv (ic) ;
9993             break;
9994             
9995         case '%' :
9996             genMod (ic);
9997             break;
9998             
9999         case '>' :
10000             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10001             break;
10002             
10003         case '<' :
10004             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10005             break;
10006             
10007         case LE_OP:
10008         case GE_OP:
10009         case NE_OP:
10010             
10011             /* note these two are xlated by algebraic equivalence
10012                during parsing SDCC.y */
10013             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10014                    "got '>=' or '<=' shouldn't have come here");
10015             break;      
10016             
10017         case EQ_OP:
10018             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10019             break;          
10020             
10021         case AND_OP:
10022             genAndOp (ic);
10023             break;
10024             
10025         case OR_OP:
10026             genOrOp (ic);
10027             break;
10028             
10029         case '^' :
10030             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10031             break;
10032             
10033         case '|' :
10034                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10035             break;
10036             
10037         case BITWISEAND:
10038             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10039             break;
10040             
10041         case INLINEASM:
10042             genInline (ic);
10043             break;
10044             
10045         case RRC:
10046             genRRC (ic);
10047             break;
10048             
10049         case RLC:
10050             genRLC (ic);
10051             break;
10052             
10053         case GETHBIT:
10054             genGetHbit (ic);
10055             break;
10056             
10057         case LEFT_OP:
10058             genLeftShift (ic);
10059             break;
10060             
10061         case RIGHT_OP:
10062             genRightShift (ic);
10063             break;
10064             
10065         case GET_VALUE_AT_ADDRESS:
10066             genPointerGet(ic);
10067             break;
10068             
10069         case '=' :
10070             if (POINTER_SET(ic))
10071                 genPointerSet(ic);
10072             else
10073                 genAssign(ic);
10074             break;
10075             
10076         case IFX:
10077             genIfx (ic,NULL);
10078             break;
10079             
10080         case ADDRESS_OF:
10081             genAddrOf (ic);
10082             break;
10083             
10084         case JUMPTABLE:
10085             genJumpTab (ic);
10086             break;
10087             
10088         case CAST:
10089             genCast (ic);
10090             break;
10091             
10092         case RECEIVE:
10093             genReceive(ic);
10094             break;
10095             
10096         case SEND:
10097             addSet(&_G.sendSet,ic);
10098             break;
10099
10100         default :
10101             ic = ic;
10102         }
10103     }
10104     
10105
10106     /* now we are ready to call the 
10107        peep hole optimizer */
10108     if (!options.nopeep) {
10109       peepHole (&lineHead);
10110     }
10111     /* now do the actual printing */
10112     printLine (lineHead,codeOutFile);
10113
10114 #ifdef PCODE_DEBUG
10115     DFPRINTF((stderr,"printing pBlock\n\n"));
10116     printpBlock(stdout,pb);
10117 #endif
10118
10119     return;
10120 }