Added regression tests for compound comparisons.
[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         aop->coff = offset ;
1116         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1117             dname)
1118             return "acc";
1119         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1120         
1121         return aop->aopu.aop_str[offset];
1122         
1123     case AOP_PCODE:
1124       {
1125         pCodeOp *pcop = aop->aopu.pcop;
1126         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1127         if(pcop->name) {
1128           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1129           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1130           sprintf(s,"%s", pcop->name);
1131         } else
1132           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1133
1134       }
1135       rs = Safe_calloc(1,strlen(s)+1);
1136       strcpy(rs,s);   
1137       return rs;
1138
1139     }
1140
1141     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1142            "aopget got unsupported aop->type");
1143     exit(0);
1144 }
1145
1146
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp                  */
1149 /*-----------------------------------------------------------------*/
1150 pCodeOp *popGetTempReg(void)
1151 {
1152
1153   pCodeOp *pcop;
1154
1155   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1156   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1157     PCOR(pcop)->r->wasUsed=1;
1158     PCOR(pcop)->r->isFree=0;
1159   }
1160
1161   return pcop;
1162 }
1163
1164 /*-----------------------------------------------------------------*/
1165 /* popGetTempReg - create a new temporary pCodeOp                  */
1166 /*-----------------------------------------------------------------*/
1167 void popReleaseTempReg(pCodeOp *pcop)
1168 {
1169
1170   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1171     PCOR(pcop)->r->isFree = 1;
1172
1173 }
1174 /*-----------------------------------------------------------------*/
1175 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1176 /*-----------------------------------------------------------------*/
1177 pCodeOp *popGetLabel(unsigned int key)
1178 {
1179
1180   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1181
1182   if(key>max_key)
1183     max_key = key;
1184
1185   return newpCodeOpLabel(NULL,key+100+labelOffset);
1186 }
1187
1188 /*-----------------------------------------------------------------*/
1189 /* popCopyReg - copy a pcode operator                              */
1190 /*-----------------------------------------------------------------*/
1191 pCodeOp *popCopyReg(pCodeOpReg *pc)
1192 {
1193   pCodeOpReg *pcor;
1194
1195   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1196   pcor->pcop.type = pc->pcop.type;
1197   if(pc->pcop.name) {
1198     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1199       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1200   } else
1201     pcor->pcop.name = NULL;
1202
1203   pcor->r = pc->r;
1204   pcor->rIdx = pc->rIdx;
1205   pcor->r->wasUsed=1;
1206
1207   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1208
1209   return PCOP(pcor);
1210 }
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion              */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetLit(unsigned int lit)
1215 {
1216
1217   return newpCodeOpLit(lit);
1218 }
1219
1220
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion         */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1225 {
1226
1227   return newpCodeOpImmd(name, offset,index, 0);
1228 }
1229
1230
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion              */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str)
1235 {
1236   pCodeOp *pcop;
1237
1238
1239   if(!str) {
1240     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1241     exit (1);
1242   }
1243
1244   pcop = newpCodeOp(str,PO_STR);
1245
1246   return pcop;
1247 }
1248
1249 /*-----------------------------------------------------------------*/
1250 /* popRegFromString -                                              */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popRegFromString(char *str, int size, int offset)
1253 {
1254
1255   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256   pcop->type = PO_DIR;
1257
1258   DEBUGpic14_emitcode(";","%d",__LINE__);
1259
1260   if(!str)
1261     str = "BAD_STRING";
1262
1263   pcop->name = Safe_calloc(1,strlen(str)+1);
1264   strcpy(pcop->name,str);
1265
1266   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1267
1268   PCOR(pcop)->r = dirregWithName(pcop->name);
1269   if(PCOR(pcop)->r == NULL) {
1270     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1271     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1272     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1273   } else {
1274     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1275   }
1276   PCOR(pcop)->instance = offset;
1277
1278   return pcop;
1279 }
1280
1281 pCodeOp *popRegFromIdx(int rIdx)
1282 {
1283   pCodeOp *pcop;
1284
1285   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1286                        __FUNCTION__,__LINE__,rIdx);
1287
1288   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1289
1290   PCOR(pcop)->rIdx = rIdx;
1291   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1292   PCOR(pcop)->r->isFree = 0;
1293   PCOR(pcop)->r->wasUsed = 1;
1294
1295   pcop->type = PCOR(pcop)->r->pc_type;
1296
1297
1298   return pcop;
1299 }
1300 /*-----------------------------------------------------------------*/
1301 /* popGet - asm operator to pcode operator conversion              */
1302 /*-----------------------------------------------------------------*/
1303 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1304 {
1305   //char *s = buffer ;
1306     //char *rs;
1307
1308     pCodeOp *pcop;
1309
1310     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1311     /* offset is greater than
1312     size then zero */
1313
1314     if (offset > (aop->size - 1) &&
1315         aop->type != AOP_LIT)
1316       return NULL;  //zero;
1317
1318     /* depending on type */
1319     switch (aop->type) {
1320         
1321     case AOP_R0:
1322     case AOP_R1:
1323     case AOP_DPTR:
1324     case AOP_DPTR2:
1325     case AOP_ACC:
1326         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1327         return NULL;
1328         
1329     case AOP_IMMD:
1330       DEBUGpic14_emitcode(";","%d",__LINE__);
1331       return popGetImmd(aop->aopu.aop_immd,offset,0);
1332
1333     case AOP_DIR:
1334       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1335 #if 0
1336         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1337         pcop->type = PO_DIR;
1338
1339         /*
1340         if (offset)
1341             sprintf(s,"(%s + %d)",
1342                     aop->aopu.aop_dir,
1343                     offset);
1344         else
1345             sprintf(s,"%s",aop->aopu.aop_dir);
1346         pcop->name = Safe_calloc(1,strlen(s)+1);
1347         strcpy(pcop->name,s);   
1348         */
1349         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1350         strcpy(pcop->name,aop->aopu.aop_dir);   
1351         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1352         if(PCOR(pcop)->r == NULL) {
1353           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1354           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1355           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1356         } else {
1357           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1358         }
1359         PCOR(pcop)->instance = offset;
1360
1361         return pcop;
1362 #endif
1363         
1364     case AOP_REG:
1365       {
1366         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1367
1368         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1369         PCOR(pcop)->rIdx = rIdx;
1370         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1371         PCOR(pcop)->r->wasUsed=1;
1372         PCOR(pcop)->r->isFree=0;
1373
1374         PCOR(pcop)->instance = offset;
1375         pcop->type = PCOR(pcop)->r->pc_type;
1376         //rs = aop->aopu.aop_reg[offset]->name;
1377         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1378         return pcop;
1379       }
1380
1381     case AOP_CRY:
1382       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1383       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1384       //if(PCOR(pcop)->r == NULL)
1385       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1386       return pcop;
1387         
1388     case AOP_LIT:
1389       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1390
1391     case AOP_STR:
1392       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1393       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1394       /*
1395       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1396       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1397       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1398       pcop->type = PCOR(pcop)->r->pc_type;
1399       pcop->name = PCOR(pcop)->r->name;
1400
1401       return pcop;
1402       */
1403
1404     case AOP_PCODE:
1405       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1406                           __LINE__, 
1407                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1408       pcop = pCodeOpCopy(aop->aopu.pcop);
1409       PCOI(pcop)->offset = offset;
1410       return pcop;
1411     }
1412
1413     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1414            "popGet got unsupported aop->type");
1415     exit(0);
1416 }
1417 /*-----------------------------------------------------------------*/
1418 /* aopPut - puts a string for a aop                                */
1419 /*-----------------------------------------------------------------*/
1420 void aopPut (asmop *aop, char *s, int offset)
1421 {
1422     char *d = buffer ;
1423     symbol *lbl ;
1424
1425     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1426
1427     if (aop->size && offset > ( aop->size - 1)) {
1428         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1429                "aopPut got offset > aop->size");
1430         exit(0);
1431     }
1432
1433     /* will assign value to value */
1434     /* depending on where it is ofcourse */
1435     switch (aop->type) {
1436     case AOP_DIR:
1437       if (offset) {
1438         sprintf(d,"(%s + %d)",
1439                 aop->aopu.aop_dir,offset);
1440         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1441
1442       } else
1443             sprintf(d,"%s",aop->aopu.aop_dir);
1444         
1445         if (strcmp(d,s)) {
1446           DEBUGpic14_emitcode(";","%d",__LINE__);
1447           if(strcmp(s,"W"))
1448             pic14_emitcode("movf","%s,w",s);
1449           pic14_emitcode("movwf","%s",d);
1450
1451           if(strcmp(s,"W")) {
1452             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1453             if(offset >= aop->size) {
1454               emitpcode(POC_CLRF,popGet(aop,offset));
1455               break;
1456             } else
1457               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1458           }
1459
1460           emitpcode(POC_MOVWF,popGet(aop,offset));
1461
1462
1463         }
1464         break;
1465         
1466     case AOP_REG:
1467       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1468         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1469           /*
1470             if (*s == '@'           ||
1471                 strcmp(s,"r0") == 0 ||
1472                 strcmp(s,"r1") == 0 ||
1473                 strcmp(s,"r2") == 0 ||
1474                 strcmp(s,"r3") == 0 ||
1475                 strcmp(s,"r4") == 0 ||
1476                 strcmp(s,"r5") == 0 ||
1477                 strcmp(s,"r6") == 0 || 
1478                 strcmp(s,"r7") == 0 )
1479                 pic14_emitcode("mov","%s,%s  ; %d",
1480                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1481             else
1482           */
1483
1484           if(strcmp(s,"W")==0 )
1485             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1486
1487           pic14_emitcode("movwf","%s",
1488                    aop->aopu.aop_reg[offset]->name);
1489
1490           if(strcmp(s,zero)==0) {
1491             emitpcode(POC_CLRF,popGet(aop,offset));
1492
1493           } else if(strcmp(s,"W")==0) {
1494             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1495             pcop->type = PO_GPR_REGISTER;
1496
1497             PCOR(pcop)->rIdx = -1;
1498             PCOR(pcop)->r = NULL;
1499
1500             DEBUGpic14_emitcode(";","%d",__LINE__);
1501             pcop->name = Safe_strdup(s);
1502             emitpcode(POC_MOVFW,pcop);
1503             emitpcode(POC_MOVWF,popGet(aop,offset));
1504           } else if(strcmp(s,one)==0) {
1505             emitpcode(POC_CLRF,popGet(aop,offset));
1506             emitpcode(POC_INCF,popGet(aop,offset));
1507           } else {
1508             emitpcode(POC_MOVWF,popGet(aop,offset));
1509           }
1510         }
1511         break;
1512         
1513     case AOP_DPTR:
1514     case AOP_DPTR2:
1515     
1516     if (aop->type == AOP_DPTR2)
1517     {
1518         genSetDPTR(1);
1519     }
1520     
1521         if (aop->code) {
1522             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1523                    "aopPut writting to code space");
1524             exit(0);
1525         }
1526         
1527         while (offset > aop->coff) {
1528             aop->coff++;
1529             pic14_emitcode ("inc","dptr");
1530         }
1531         
1532         while (offset < aop->coff) {
1533             aop->coff-- ;
1534             pic14_emitcode("lcall","__decdptr");
1535         }
1536         
1537         aop->coff = offset;
1538         
1539         /* if not in accumulater */
1540         MOVA(s);        
1541         
1542         pic14_emitcode ("movx","@dptr,a");
1543         
1544     if (aop->type == AOP_DPTR2)
1545     {
1546         genSetDPTR(0);
1547     }
1548         break;
1549         
1550     case AOP_R0:
1551     case AOP_R1:
1552         while (offset > aop->coff) {
1553             aop->coff++;
1554             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1555         }
1556         while (offset < aop->coff) {
1557             aop->coff-- ;
1558             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559         }
1560         aop->coff = offset;
1561         
1562         if (aop->paged) {
1563             MOVA(s);           
1564             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565             
1566         } else
1567             if (*s == '@') {
1568                 MOVA(s);
1569                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1570             } else
1571                 if (strcmp(s,"r0") == 0 ||
1572                     strcmp(s,"r1") == 0 ||
1573                     strcmp(s,"r2") == 0 ||
1574                     strcmp(s,"r3") == 0 ||
1575                     strcmp(s,"r4") == 0 ||
1576                     strcmp(s,"r5") == 0 ||
1577                     strcmp(s,"r6") == 0 || 
1578                     strcmp(s,"r7") == 0 ) {
1579                     char buffer[10];
1580                     sprintf(buffer,"a%s",s);
1581                     pic14_emitcode("mov","@%s,%s",
1582                              aop->aopu.aop_ptr->name,buffer);
1583                 } else
1584                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585         
1586         break;
1587         
1588     case AOP_STK:
1589         if (strcmp(s,"a") == 0)
1590             pic14_emitcode("push","acc");
1591         else
1592             pic14_emitcode("push","%s",s);
1593         
1594         break;
1595         
1596     case AOP_CRY:
1597         /* if bit variable */
1598         if (!aop->aopu.aop_dir) {
1599             pic14_emitcode("clr","a");
1600             pic14_emitcode("rlc","a");
1601         } else {
1602             if (s == zero) 
1603                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1604             else
1605                 if (s == one)
1606                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1607                 else
1608                     if (!strcmp(s,"c"))
1609                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1610                     else {
1611                         lbl = newiTempLabel(NULL);
1612                         
1613                         if (strcmp(s,"a")) {
1614                             MOVA(s);
1615                         }
1616                         pic14_emitcode("clr","c");
1617                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1618                         pic14_emitcode("cpl","c");
1619                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1620                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621                     }
1622         }
1623         break;
1624         
1625     case AOP_STR:
1626         aop->coff = offset;
1627         if (strcmp(aop->aopu.aop_str[offset],s))
1628             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629         break;
1630         
1631     case AOP_ACC:
1632         aop->coff = offset;
1633         if (!offset && (strcmp(s,"acc") == 0))
1634             break;
1635         
1636         if (strcmp(aop->aopu.aop_str[offset],s))
1637             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1638         break;
1639
1640     default :
1641         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1642                "aopPut got unsupported aop->type");
1643         exit(0);    
1644     }    
1645
1646 }
1647
1648 /*-----------------------------------------------------------------*/
1649 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1650 /*-----------------------------------------------------------------*/
1651 void mov2w (asmop *aop, int offset)
1652 {
1653
1654   if(!aop)
1655     return;
1656
1657   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_SWAPFW, 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   int res_offset = 0;  /* the result may be a different size then left or right */
4533   int res_size = AOP_SIZE(result);
4534   resolvedIfx rIfx;
4535   symbol *lbl;
4536
4537   unsigned long lit = 0L;
4538   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4539   DEBUGpic14_AopType(__LINE__,left,right,result);
4540   if(result)
4541     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4542   resolveIfx(&rIfx,ifx);
4543   lbl =  newiTempLabel(NULL);
4544
4545
4546   /* if the left side is a literal or 
4547      if the right is in a pointer register and left 
4548      is not */
4549   if ((AOP_TYPE(left) == AOP_LIT) || 
4550       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4551     operand *t = right;
4552     right = left;
4553     left = t;
4554   }
4555   if(AOP_TYPE(right) == AOP_LIT)
4556     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4557
4558   /* if the right side is a literal then anything goes */
4559   if (AOP_TYPE(right) == AOP_LIT &&
4560       AOP_TYPE(left) != AOP_DIR ) {
4561     switch(size) {
4562     case 2:
4563       genc16bit2lit(left, lit, 0);
4564       emitSKPNZ;
4565       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4566       break;
4567     default:
4568       while (size--) {
4569         if(lit & 0xff) {
4570           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4572         } else {
4573           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4574         }
4575
4576         emitSKPNZ;
4577         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4578         offset++;
4579         if(res_offset < res_size-1)
4580           res_offset++;
4581         lit >>= 8;
4582       }
4583       break;
4584     }
4585   }
4586
4587   /* if the right side is in a register or in direct space or
4588      if the left is a pointer register & right is not */    
4589   else if (AOP_TYPE(right) == AOP_REG ||
4590            AOP_TYPE(right) == AOP_DIR || 
4591            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4592            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4593     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4594     int lbl_key = lbl->key;
4595
4596     if(result) {
4597       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4598       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4599     }else {
4600       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4601       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4602               __FUNCTION__,__LINE__);
4603       return;
4604     }
4605
4606 /*     switch(size) { */
4607 /*     case 2: */
4608 /*       genc16bit2lit(left, lit, 0); */
4609 /*       emitSKPNZ; */
4610 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4611 /*       break; */
4612 /*     default: */
4613     while (size--) {
4614       int emit_skip=1;
4615       if((AOP_TYPE(left) == AOP_DIR) && 
4616          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4617
4618         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4620
4621       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4622             
4623         switch (lit & 0xff) {
4624         case 0:
4625           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4626           break;
4627         case 1:
4628           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4631           emit_skip=0;
4632           break;
4633         case 0xff:
4634           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4635           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4638           emit_skip=0;
4639           break;
4640         default:
4641           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4642           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4643         }
4644         lit >>= 8;
4645
4646       } else {
4647         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4648       }
4649       if(emit_skip) {
4650         if(AOP_TYPE(result) == AOP_CRY) {
4651           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4652           if(rIfx.condition)
4653             emitSKPNZ;
4654           else
4655             emitSKPZ;
4656           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4657         } else {
4658           /* fix me. probably need to check result size too */
4659           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4660           if(rIfx.condition)
4661             emitSKPZ;
4662           else
4663             emitSKPNZ;
4664           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4665           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4666         }
4667         if(ifx)
4668           ifx->generated=1;
4669       }
4670       emit_skip++;
4671       offset++;
4672       if(res_offset < res_size-1)
4673         res_offset++;
4674     }
4675 /*       break; */
4676 /*     } */
4677   } else if(AOP_TYPE(right) == AOP_REG &&
4678             AOP_TYPE(left) != AOP_DIR){
4679
4680     while(size--) {
4681       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4682       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4683       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4684       if(rIfx.condition)
4685         emitSKPNZ;
4686       else
4687         emitSKPZ;
4688       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4689       offset++;
4690       if(res_offset < res_size-1)
4691         res_offset++;
4692     }
4693       
4694   }else{
4695     /* right is a pointer reg need both a & b */
4696     while(size--) {
4697       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4698       if(strcmp(l,"b"))
4699         pic14_emitcode("mov","b,%s",l);
4700       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4701       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4702       offset++;
4703     }
4704   }
4705
4706   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4707   if(!rIfx.condition)
4708     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4709
4710   emitpLabel(lbl->key);
4711
4712   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4713
4714   if(ifx)
4715     ifx->generated = 1;
4716 }
4717
4718 #if 0
4719 /*-----------------------------------------------------------------*/
4720 /* gencjne - compare and jump if not equal                         */
4721 /*-----------------------------------------------------------------*/
4722 static void gencjne(operand *left, operand *right, iCode *ifx)
4723 {
4724     symbol *tlbl  = newiTempLabel(NULL);
4725
4726     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4727     gencjneshort(left, right, lbl);
4728
4729     pic14_emitcode("mov","a,%s",one);
4730     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4731     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4732     pic14_emitcode("clr","a");
4733     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4734
4735     emitpLabel(lbl->key);
4736     emitpLabel(tlbl->key);
4737
4738 }
4739 #endif
4740
4741 /*-----------------------------------------------------------------*/
4742 /* genCmpEq - generates code for equal to                          */
4743 /*-----------------------------------------------------------------*/
4744 static void genCmpEq (iCode *ic, iCode *ifx)
4745 {
4746     operand *left, *right, *result;
4747     unsigned long lit = 0L;
4748     int size,offset=0;
4749
4750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4751
4752     if(ifx)
4753       DEBUGpic14_emitcode ("; ifx is non-null","");
4754     else
4755       DEBUGpic14_emitcode ("; ifx is null","");
4756
4757     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4758     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4759     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4760
4761     size = max(AOP_SIZE(left),AOP_SIZE(right));
4762
4763     DEBUGpic14_AopType(__LINE__,left,right,result);
4764
4765     /* if literal, literal on the right or 
4766     if the right is in a pointer register and left 
4767     is not */
4768     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4769         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4770       operand *tmp = right ;
4771       right = left;
4772       left = tmp;
4773     }
4774
4775
4776     if(ifx && !AOP_SIZE(result)){
4777         symbol *tlbl;
4778         /* if they are both bit variables */
4779         if (AOP_TYPE(left) == AOP_CRY &&
4780             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4781             if(AOP_TYPE(right) == AOP_LIT){
4782                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4783                 if(lit == 0L){
4784                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785                     pic14_emitcode("cpl","c");
4786                 } else if(lit == 1L) {
4787                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4788                 } else {
4789                     pic14_emitcode("clr","c");
4790                 }
4791                 /* AOP_TYPE(right) == AOP_CRY */
4792             } else {
4793                 symbol *lbl = newiTempLabel(NULL);
4794                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4795                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4796                 pic14_emitcode("cpl","c");
4797                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4798             }
4799             /* if true label then we jump if condition
4800             supplied is true */
4801             tlbl = newiTempLabel(NULL);
4802             if ( IC_TRUE(ifx) ) {
4803                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4804                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4805             } else {
4806                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4807                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4808             }
4809             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4810
4811             {
4812               /* left and right are both bit variables, result is carry */
4813               resolvedIfx rIfx;
4814               
4815               resolveIfx(&rIfx,ifx);
4816
4817               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4818               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4819               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4820               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4821               genSkipz2(&rIfx,0);
4822             }
4823         } else {
4824
4825           /* They're not both bit variables. Is the right a literal? */
4826           if(AOP_TYPE(right) == AOP_LIT) {
4827             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4828             
4829             switch(size) {
4830
4831             case 1:
4832               switch(lit & 0xff) {
4833               case 1:
4834                 if ( IC_TRUE(ifx) ) {
4835                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4836                   emitSKPNZ;
4837                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4838                 } else {
4839                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4840                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4841                 }
4842                 break;
4843               case 0xff:
4844                 if ( IC_TRUE(ifx) ) {
4845                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4846                   emitSKPNZ;
4847                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4848                 } else {
4849                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4850                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4851                 }
4852                 break;
4853               default:
4854                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4855                 if(lit)
4856                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4857                 genSkip(ifx,'z');
4858               }
4859
4860
4861               /* end of size == 1 */
4862               break;
4863               
4864             case 2:
4865               genc16bit2lit(left,lit,offset);
4866               genSkip(ifx,'z');
4867               break;
4868               /* end of size == 2 */
4869
4870             default:
4871               /* size is 4 */
4872               if(lit==0) {
4873                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4874                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4875                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4876                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4877
4878               } else {
4879
4880                 /* search for patterns that can be optimized */
4881
4882                 genc16bit2lit(left,lit,0);
4883                 lit >>= 16;
4884                 if(lit) {
4885                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4886                   //genSkip(ifx,'z');
4887                   genc16bit2lit(left,lit,2);
4888                 } else {
4889                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4890                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4891
4892                 }
4893                 
4894               }
4895
4896               genSkip(ifx,'z');
4897             }
4898           
4899             ifx->generated = 1;
4900             goto release ;
4901             
4902
4903           } else if(AOP_TYPE(right) == AOP_CRY ) {
4904             /* we know the left is not a bit, but that the right is */
4905             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4906             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4907                       popGet(AOP(right),offset));
4908             emitpcode(POC_XORLW,popGetLit(1));
4909
4910             /* if the two are equal, then W will be 0 and the Z bit is set
4911              * we could test Z now, or go ahead and check the high order bytes if
4912              * the variable we're comparing is larger than a byte. */
4913
4914             while(--size)
4915               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4916
4917             if ( IC_TRUE(ifx) ) {
4918               emitSKPNZ;
4919               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4920               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4921             } else {
4922               emitSKPZ;
4923               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4924               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4925             }
4926
4927           } else {
4928             /* They're both variables that are larger than bits */
4929             int s = size;
4930
4931             tlbl = newiTempLabel(NULL);
4932
4933             while(size--) {
4934               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4935               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4936
4937               if ( IC_TRUE(ifx) ) {
4938                 if(size) {
4939                   emitSKPZ;
4940                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4941                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4942                 } else {
4943                   emitSKPNZ;
4944                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4945                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4946                 }
4947               } else {
4948                 emitSKPZ;
4949                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4950                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4951               }
4952               offset++;
4953             }
4954             if(s>1 && IC_TRUE(ifx)) {
4955               emitpLabel(tlbl->key);
4956               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4957             }
4958           }
4959         }
4960         /* mark the icode as generated */
4961         ifx->generated = 1;
4962         goto release ;
4963     }
4964
4965     /* if they are both bit variables */
4966     if (AOP_TYPE(left) == AOP_CRY &&
4967         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4968         if(AOP_TYPE(right) == AOP_LIT){
4969             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4970             if(lit == 0L){
4971                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972                 pic14_emitcode("cpl","c");
4973             } else if(lit == 1L) {
4974                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4975             } else {
4976                 pic14_emitcode("clr","c");
4977             }
4978             /* AOP_TYPE(right) == AOP_CRY */
4979         } else {
4980             symbol *lbl = newiTempLabel(NULL);
4981             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4982             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4983             pic14_emitcode("cpl","c");
4984             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4985         }
4986         /* c = 1 if egal */
4987         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4988             pic14_outBitC(result);
4989             goto release ;
4990         }
4991         if (ifx) {
4992             genIfxJump (ifx,"c");
4993             goto release ;
4994         }
4995         /* if the result is used in an arithmetic operation
4996         then put the result in place */
4997         pic14_outBitC(result);
4998     } else {
4999       
5000       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5001       gencjne(left,right,result,ifx);
5002 /*
5003       if(ifx) 
5004         gencjne(left,right,newiTempLabel(NULL));
5005       else {
5006         if(IC_TRUE(ifx)->key)
5007           gencjne(left,right,IC_TRUE(ifx)->key);
5008         else
5009           gencjne(left,right,IC_FALSE(ifx)->key);
5010         ifx->generated = 1;
5011         goto release ;
5012       }
5013       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5014         aopPut(AOP(result),"a",0);
5015         goto release ;
5016       }
5017
5018       if (ifx) {
5019         genIfxJump (ifx,"a");
5020         goto release ;
5021       }
5022 */
5023       /* if the result is used in an arithmetic operation
5024          then put the result in place */
5025 /*
5026       if (AOP_TYPE(result) != AOP_CRY) 
5027         pic14_outAcc(result);
5028 */
5029       /* leave the result in acc */
5030     }
5031
5032 release:
5033     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5034     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035     freeAsmop(result,NULL,ic,TRUE);
5036 }
5037
5038 /*-----------------------------------------------------------------*/
5039 /* ifxForOp - returns the icode containing the ifx for operand     */
5040 /*-----------------------------------------------------------------*/
5041 static iCode *ifxForOp ( operand *op, iCode *ic )
5042 {
5043     /* if true symbol then needs to be assigned */
5044     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5045     if (IS_TRUE_SYMOP(op))
5046         return NULL ;
5047
5048     /* if this has register type condition and
5049     the next instruction is ifx with the same operand
5050     and live to of the operand is upto the ifx only then */
5051     if (ic->next &&
5052         ic->next->op == IFX &&
5053         IC_COND(ic->next)->key == op->key &&
5054         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5055         return ic->next;
5056
5057     if (ic->next &&
5058         ic->next->op == IFX &&
5059         IC_COND(ic->next)->key == op->key) {
5060       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5061       return ic->next;
5062     }
5063
5064     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5065     if (ic->next &&
5066         ic->next->op == IFX)
5067       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5068
5069     if (ic->next &&
5070         ic->next->op == IFX &&
5071         IC_COND(ic->next)->key == op->key) {
5072       DEBUGpic14_emitcode ("; "," key is okay");
5073       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5074                            OP_SYMBOL(op)->liveTo,
5075                            ic->next->seq);
5076     }
5077
5078
5079     return NULL;
5080 }
5081 /*-----------------------------------------------------------------*/
5082 /* genAndOp - for && operation                                     */
5083 /*-----------------------------------------------------------------*/
5084 static void genAndOp (iCode *ic)
5085 {
5086     operand *left,*right, *result;
5087 /*     symbol *tlbl; */
5088
5089     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5090     /* note here that && operations that are in an
5091     if statement are taken away by backPatchLabels
5092     only those used in arthmetic operations remain */
5093     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5094     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5095     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5096
5097     DEBUGpic14_AopType(__LINE__,left,right,result);
5098
5099     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5100     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5101     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5102
5103     /* if both are bit variables */
5104 /*     if (AOP_TYPE(left) == AOP_CRY && */
5105 /*         AOP_TYPE(right) == AOP_CRY ) { */
5106 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5107 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5108 /*         pic14_outBitC(result); */
5109 /*     } else { */
5110 /*         tlbl = newiTempLabel(NULL); */
5111 /*         pic14_toBoolean(left);     */
5112 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5113 /*         pic14_toBoolean(right); */
5114 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5115 /*         pic14_outBitAcc(result); */
5116 /*     } */
5117
5118     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5119     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120     freeAsmop(result,NULL,ic,TRUE);
5121 }
5122
5123
5124 /*-----------------------------------------------------------------*/
5125 /* genOrOp - for || operation                                      */
5126 /*-----------------------------------------------------------------*/
5127 /*
5128   tsd pic port -
5129   modified this code, but it doesn't appear to ever get called
5130 */
5131
5132 static void genOrOp (iCode *ic)
5133 {
5134     operand *left,*right, *result;
5135     symbol *tlbl;
5136
5137     /* note here that || operations that are in an
5138     if statement are taken away by backPatchLabels
5139     only those used in arthmetic operations remain */
5140     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5141     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5142     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5143     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5144
5145     DEBUGpic14_AopType(__LINE__,left,right,result);
5146
5147     /* if both are bit variables */
5148     if (AOP_TYPE(left) == AOP_CRY &&
5149         AOP_TYPE(right) == AOP_CRY ) {
5150       pic14_emitcode("clrc","");
5151       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5152                AOP(left)->aopu.aop_dir,
5153                AOP(left)->aopu.aop_dir);
5154       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5155                AOP(right)->aopu.aop_dir,
5156                AOP(right)->aopu.aop_dir);
5157       pic14_emitcode("setc","");
5158
5159     } else {
5160         tlbl = newiTempLabel(NULL);
5161         pic14_toBoolean(left);
5162         emitSKPZ;
5163         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5164         pic14_toBoolean(right);
5165         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5166
5167         pic14_outBitAcc(result);
5168     }
5169
5170     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172     freeAsmop(result,NULL,ic,TRUE);            
5173 }
5174
5175 /*-----------------------------------------------------------------*/
5176 /* isLiteralBit - test if lit == 2^n                               */
5177 /*-----------------------------------------------------------------*/
5178 static int isLiteralBit(unsigned long lit)
5179 {
5180     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5181     0x100L,0x200L,0x400L,0x800L,
5182     0x1000L,0x2000L,0x4000L,0x8000L,
5183     0x10000L,0x20000L,0x40000L,0x80000L,
5184     0x100000L,0x200000L,0x400000L,0x800000L,
5185     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5186     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5187     int idx;
5188     
5189     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5190     for(idx = 0; idx < 32; idx++)
5191         if(lit == pw[idx])
5192             return idx+1;
5193     return 0;
5194 }
5195
5196 /*-----------------------------------------------------------------*/
5197 /* continueIfTrue -                                                */
5198 /*-----------------------------------------------------------------*/
5199 static void continueIfTrue (iCode *ic)
5200 {
5201     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5202     if(IC_TRUE(ic))
5203         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5204     ic->generated = 1;
5205 }
5206
5207 /*-----------------------------------------------------------------*/
5208 /* jmpIfTrue -                                                     */
5209 /*-----------------------------------------------------------------*/
5210 static void jumpIfTrue (iCode *ic)
5211 {
5212     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5213     if(!IC_TRUE(ic))
5214         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5215     ic->generated = 1;
5216 }
5217
5218 /*-----------------------------------------------------------------*/
5219 /* jmpTrueOrFalse -                                                */
5220 /*-----------------------------------------------------------------*/
5221 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5222 {
5223     // ugly but optimized by peephole
5224     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5225     if(IC_TRUE(ic)){
5226         symbol *nlbl = newiTempLabel(NULL);
5227         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5228         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5229         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5230         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5231     }
5232     else{
5233         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5234         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5235     }
5236     ic->generated = 1;
5237 }
5238
5239 /*-----------------------------------------------------------------*/
5240 /* genAnd  - code for and                                          */
5241 /*-----------------------------------------------------------------*/
5242 static void genAnd (iCode *ic, iCode *ifx)
5243 {
5244   operand *left, *right, *result;
5245   int size, offset=0;  
5246   unsigned long lit = 0L;
5247   int bytelit = 0;
5248   resolvedIfx rIfx;
5249
5250
5251   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5252   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5253   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5254   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5255
5256   resolveIfx(&rIfx,ifx);
5257
5258   /* if left is a literal & right is not then exchange them */
5259   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5260       AOP_NEEDSACC(left)) {
5261     operand *tmp = right ;
5262     right = left;
5263     left = tmp;
5264   }
5265
5266   /* if result = right then exchange them */
5267   if(pic14_sameRegs(AOP(result),AOP(right))){
5268     operand *tmp = right ;
5269     right = left;
5270     left = tmp;
5271   }
5272
5273   /* if right is bit then exchange them */
5274   if (AOP_TYPE(right) == AOP_CRY &&
5275       AOP_TYPE(left) != AOP_CRY){
5276     operand *tmp = right ;
5277     right = left;
5278     left = tmp;
5279   }
5280   if(AOP_TYPE(right) == AOP_LIT)
5281     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5282
5283   size = AOP_SIZE(result);
5284
5285   DEBUGpic14_AopType(__LINE__,left,right,result);
5286
5287   // if(bit & yy)
5288   // result = bit & yy;
5289   if (AOP_TYPE(left) == AOP_CRY){
5290     // c = bit & literal;
5291     if(AOP_TYPE(right) == AOP_LIT){
5292       if(lit & 1) {
5293         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5294           // no change
5295           goto release;
5296         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5297       } else {
5298         // bit(result) = 0;
5299         if(size && (AOP_TYPE(result) == AOP_CRY)){
5300           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5301           goto release;
5302         }
5303         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5304           jumpIfTrue(ifx);
5305           goto release;
5306         }
5307         pic14_emitcode("clr","c");
5308       }
5309     } else {
5310       if (AOP_TYPE(right) == AOP_CRY){
5311         // c = bit & bit;
5312         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5313         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5314       } else {
5315         // c = bit & val;
5316         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5317         // c = lsb
5318         pic14_emitcode("rrc","a");
5319         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5320       }
5321     }
5322     // bit = c
5323     // val = c
5324     if(size)
5325       pic14_outBitC(result);
5326     // if(bit & ...)
5327     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5328       genIfxJump(ifx, "c");           
5329     goto release ;
5330   }
5331
5332   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5333   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5334   if((AOP_TYPE(right) == AOP_LIT) &&
5335      (AOP_TYPE(result) == AOP_CRY) &&
5336      (AOP_TYPE(left) != AOP_CRY)){
5337     int posbit = isLiteralBit(lit);
5338     /* left &  2^n */
5339     if(posbit){
5340       posbit--;
5341       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5342       // bit = left & 2^n
5343       if(size)
5344         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5345       // if(left &  2^n)
5346       else{
5347         if(ifx){
5348 /*
5349           if(IC_TRUE(ifx)) {
5350             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5351             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5352           } else {
5353             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5354             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5355           }
5356 */
5357           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5358                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5359           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5360           
5361           ifx->generated = 1;
5362         }
5363         goto release;
5364       }
5365     } else {
5366       symbol *tlbl = newiTempLabel(NULL);
5367       int sizel = AOP_SIZE(left);
5368       if(size)
5369         pic14_emitcode("setb","c");
5370       while(sizel--){
5371         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5372           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5373           // byte ==  2^n ?
5374           if((posbit = isLiteralBit(bytelit)) != 0)
5375             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5376           else{
5377             if(bytelit != 0x0FFL)
5378               pic14_emitcode("anl","a,%s",
5379                              aopGet(AOP(right),offset,FALSE,TRUE));
5380             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5381           }
5382         }
5383         offset++;
5384       }
5385       // bit = left & literal
5386       if(size){
5387         pic14_emitcode("clr","c");
5388         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5389       }
5390       // if(left & literal)
5391       else{
5392         if(ifx)
5393           jmpTrueOrFalse(ifx, tlbl);
5394         goto release ;
5395       }
5396     }
5397     pic14_outBitC(result);
5398     goto release ;
5399   }
5400
5401   /* if left is same as result */
5402   if(pic14_sameRegs(AOP(result),AOP(left))){
5403     int know_W = -1;
5404     for(;size--; offset++,lit>>=8) {
5405       if(AOP_TYPE(right) == AOP_LIT){
5406         switch(lit & 0xff) {
5407         case 0x00:
5408           /*  and'ing with 0 has clears the result */
5409           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5410           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5411           break;
5412         case 0xff:
5413           /* and'ing with 0xff is a nop when the result and left are the same */
5414           break;
5415
5416         default:
5417           {
5418             int p = my_powof2( (~lit) & 0xff );
5419             if(p>=0) {
5420               /* only one bit is set in the literal, so use a bcf instruction */
5421               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5422               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5423
5424             } else {
5425               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5426               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5427               if(know_W != (lit&0xff))
5428                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5429               know_W = lit &0xff;
5430               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5431             }
5432           }    
5433         }
5434       } else {
5435         if (AOP_TYPE(left) == AOP_ACC) {
5436           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5437         } else {                    
5438           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5439           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5440
5441         }
5442       }
5443     }
5444
5445   } else {
5446     // left & result in different registers
5447     if(AOP_TYPE(result) == AOP_CRY){
5448       // result = bit
5449       // if(size), result in bit
5450       // if(!size && ifx), conditional oper: if(left & right)
5451       symbol *tlbl = newiTempLabel(NULL);
5452       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5453       if(size)
5454         pic14_emitcode("setb","c");
5455       while(sizer--){
5456         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5457         pic14_emitcode("anl","a,%s",
5458                        aopGet(AOP(left),offset,FALSE,FALSE));
5459         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5460         offset++;
5461       }
5462       if(size){
5463         CLRC;
5464         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5465         pic14_outBitC(result);
5466       } else if(ifx)
5467         jmpTrueOrFalse(ifx, tlbl);
5468     } else {
5469       for(;(size--);offset++) {
5470         // normal case
5471         // result = left & right
5472         if(AOP_TYPE(right) == AOP_LIT){
5473           int t = (lit >> (offset*8)) & 0x0FFL;
5474           switch(t) { 
5475           case 0x00:
5476             pic14_emitcode("clrf","%s",
5477                            aopGet(AOP(result),offset,FALSE,FALSE));
5478             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5479             break;
5480           case 0xff:
5481             pic14_emitcode("movf","%s,w",
5482                            aopGet(AOP(left),offset,FALSE,FALSE));
5483             pic14_emitcode("movwf","%s",
5484                            aopGet(AOP(result),offset,FALSE,FALSE));
5485             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5486             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5487             break;
5488           default:
5489             pic14_emitcode("movlw","0x%x",t);
5490             pic14_emitcode("andwf","%s,w",
5491                            aopGet(AOP(left),offset,FALSE,FALSE));
5492             pic14_emitcode("movwf","%s",
5493                            aopGet(AOP(result),offset,FALSE,FALSE));
5494               
5495             emitpcode(POC_MOVLW, popGetLit(t));
5496             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5497             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5498           }
5499           continue;
5500         }
5501
5502         if (AOP_TYPE(left) == AOP_ACC) {
5503           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5504           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5505         } else {
5506           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5507           pic14_emitcode("andwf","%s,w",
5508                          aopGet(AOP(left),offset,FALSE,FALSE));
5509           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5510           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5511         }
5512         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5513         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5514       }
5515     }
5516   }
5517
5518   release :
5519     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5520   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521   freeAsmop(result,NULL,ic,TRUE);     
5522 }
5523
5524 /*-----------------------------------------------------------------*/
5525 /* genOr  - code for or                                            */
5526 /*-----------------------------------------------------------------*/
5527 static void genOr (iCode *ic, iCode *ifx)
5528 {
5529     operand *left, *right, *result;
5530     int size, offset=0;
5531     unsigned long lit = 0L;
5532
5533     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5534
5535     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5536     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5537     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5538
5539     DEBUGpic14_AopType(__LINE__,left,right,result);
5540
5541     /* if left is a literal & right is not then exchange them */
5542     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5543         AOP_NEEDSACC(left)) {
5544         operand *tmp = right ;
5545         right = left;
5546         left = tmp;
5547     }
5548
5549     /* if result = right then exchange them */
5550     if(pic14_sameRegs(AOP(result),AOP(right))){
5551         operand *tmp = right ;
5552         right = left;
5553         left = tmp;
5554     }
5555
5556     /* if right is bit then exchange them */
5557     if (AOP_TYPE(right) == AOP_CRY &&
5558         AOP_TYPE(left) != AOP_CRY){
5559         operand *tmp = right ;
5560         right = left;
5561         left = tmp;
5562     }
5563
5564     DEBUGpic14_AopType(__LINE__,left,right,result);
5565
5566     if(AOP_TYPE(right) == AOP_LIT)
5567         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5568
5569     size = AOP_SIZE(result);
5570
5571     // if(bit | yy)
5572     // xx = bit | yy;
5573     if (AOP_TYPE(left) == AOP_CRY){
5574         if(AOP_TYPE(right) == AOP_LIT){
5575             // c = bit & literal;
5576             if(lit){
5577                 // lit != 0 => result = 1
5578                 if(AOP_TYPE(result) == AOP_CRY){
5579                   if(size)
5580                     emitpcode(POC_BSF, popGet(AOP(result),0));
5581                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5582                   //     AOP(result)->aopu.aop_dir,
5583                   //     AOP(result)->aopu.aop_dir);
5584                     else if(ifx)
5585                         continueIfTrue(ifx);
5586                     goto release;
5587                 }
5588             } else {
5589                 // lit == 0 => result = left
5590                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5591                     goto release;
5592                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5593             }
5594         } else {
5595             if (AOP_TYPE(right) == AOP_CRY){
5596               if(pic14_sameRegs(AOP(result),AOP(left))){
5597                 // c = bit | bit;
5598                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5599                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5600                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5601
5602                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5603                          AOP(result)->aopu.aop_dir,
5604                          AOP(result)->aopu.aop_dir);
5605                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5606                          AOP(right)->aopu.aop_dir,
5607                          AOP(right)->aopu.aop_dir);
5608                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5609                          AOP(result)->aopu.aop_dir,
5610                          AOP(result)->aopu.aop_dir);
5611               } else {
5612                 if( AOP_TYPE(result) == AOP_ACC) {
5613                   emitpcode(POC_MOVLW, popGetLit(0));
5614                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5615                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5616                   emitpcode(POC_MOVLW, popGetLit(1));
5617
5618                 } else {
5619
5620                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5621                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5622                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5623                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5624
5625                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5626                                  AOP(result)->aopu.aop_dir,
5627                                  AOP(result)->aopu.aop_dir);
5628                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5629                                  AOP(right)->aopu.aop_dir,
5630                                  AOP(right)->aopu.aop_dir);
5631                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5632                                  AOP(left)->aopu.aop_dir,
5633                                  AOP(left)->aopu.aop_dir);
5634                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635                                  AOP(result)->aopu.aop_dir,
5636                                  AOP(result)->aopu.aop_dir);
5637                 }
5638               }
5639             } else {
5640                 // c = bit | val;
5641                 symbol *tlbl = newiTempLabel(NULL);
5642                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5643
5644
5645                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5646                 if( AOP_TYPE(right) == AOP_ACC) {
5647                   emitpcode(POC_IORLW, popGetLit(0));
5648                   emitSKPNZ;
5649                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5650                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5651                 }
5652
5653
5654
5655                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5656                     pic14_emitcode(";XXX setb","c");
5657                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5658                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5659                 pic14_toBoolean(right);
5660                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5662                     jmpTrueOrFalse(ifx, tlbl);
5663                     goto release;
5664                 } else {
5665                     CLRC;
5666                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5667                 }
5668             }
5669         }
5670         // bit = c
5671         // val = c
5672         if(size)
5673             pic14_outBitC(result);
5674         // if(bit | ...)
5675         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5676             genIfxJump(ifx, "c");           
5677         goto release ;
5678     }
5679
5680     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5681     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5682     if((AOP_TYPE(right) == AOP_LIT) &&
5683        (AOP_TYPE(result) == AOP_CRY) &&
5684        (AOP_TYPE(left) != AOP_CRY)){
5685         if(lit){
5686           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5687             // result = 1
5688             if(size)
5689                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5690             else 
5691                 continueIfTrue(ifx);
5692             goto release;
5693         } else {
5694           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695             // lit = 0, result = boolean(left)
5696             if(size)
5697                 pic14_emitcode(";XXX setb","c");
5698             pic14_toBoolean(right);
5699             if(size){
5700                 symbol *tlbl = newiTempLabel(NULL);
5701                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5702                 CLRC;
5703                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5704             } else {
5705                 genIfxJump (ifx,"a");
5706                 goto release;
5707             }
5708         }
5709         pic14_outBitC(result);
5710         goto release ;
5711     }
5712
5713     /* if left is same as result */
5714     if(pic14_sameRegs(AOP(result),AOP(left))){
5715       int know_W = -1;
5716       for(;size--; offset++,lit>>=8) {
5717         if(AOP_TYPE(right) == AOP_LIT){
5718           if((lit & 0xff) == 0)
5719             /*  or'ing with 0 has no effect */
5720             continue;
5721           else {
5722             int p = my_powof2(lit & 0xff);
5723             if(p>=0) {
5724               /* only one bit is set in the literal, so use a bsf instruction */
5725               emitpcode(POC_BSF,
5726                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5727             } else {
5728               if(know_W != (lit & 0xff))
5729                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5730               know_W = lit & 0xff;
5731               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5732             }
5733                     
5734           }
5735         } else {
5736           if (AOP_TYPE(left) == AOP_ACC) {
5737             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5738             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5739           } else {                  
5740             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5741             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5742
5743             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5744             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5745
5746           }
5747         }
5748       }
5749     } else {
5750         // left & result in different registers
5751         if(AOP_TYPE(result) == AOP_CRY){
5752             // result = bit
5753             // if(size), result in bit
5754             // if(!size && ifx), conditional oper: if(left | right)
5755             symbol *tlbl = newiTempLabel(NULL);
5756             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5757             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5758
5759
5760             if(size)
5761                 pic14_emitcode(";XXX setb","c");
5762             while(sizer--){
5763                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5764                 pic14_emitcode(";XXX orl","a,%s",
5765                          aopGet(AOP(left),offset,FALSE,FALSE));
5766                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5767                 offset++;
5768             }
5769             if(size){
5770                 CLRC;
5771                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772                 pic14_outBitC(result);
5773             } else if(ifx)
5774                 jmpTrueOrFalse(ifx, tlbl);
5775         } else for(;(size--);offset++){
5776           // normal case
5777           // result = left & right
5778           if(AOP_TYPE(right) == AOP_LIT){
5779             int t = (lit >> (offset*8)) & 0x0FFL;
5780             switch(t) { 
5781             case 0x00:
5782               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5783               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5784
5785               pic14_emitcode("movf","%s,w",
5786                        aopGet(AOP(left),offset,FALSE,FALSE));
5787               pic14_emitcode("movwf","%s",
5788                        aopGet(AOP(result),offset,FALSE,FALSE));
5789               break;
5790             default:
5791               emitpcode(POC_MOVLW,  popGetLit(t));
5792               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5793               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5794
5795               pic14_emitcode("movlw","0x%x",t);
5796               pic14_emitcode("iorwf","%s,w",
5797                        aopGet(AOP(left),offset,FALSE,FALSE));
5798               pic14_emitcode("movwf","%s",
5799                        aopGet(AOP(result),offset,FALSE,FALSE));
5800               
5801             }
5802             continue;
5803           }
5804
5805           // faster than result <- left, anl result,right
5806           // and better if result is SFR
5807           if (AOP_TYPE(left) == AOP_ACC) {
5808             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5809             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5810           } else {
5811             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5812             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5813
5814             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5815             pic14_emitcode("iorwf","%s,w",
5816                      aopGet(AOP(left),offset,FALSE,FALSE));
5817           }
5818           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5819           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5820         }
5821     }
5822
5823 release :
5824     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5825     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826     freeAsmop(result,NULL,ic,TRUE);     
5827 }
5828
5829 /*-----------------------------------------------------------------*/
5830 /* genXor - code for xclusive or                                   */
5831 /*-----------------------------------------------------------------*/
5832 static void genXor (iCode *ic, iCode *ifx)
5833 {
5834   operand *left, *right, *result;
5835   int size, offset=0;
5836   unsigned long lit = 0L;
5837
5838   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5839
5840   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5841   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5842   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5843
5844   /* if left is a literal & right is not ||
5845      if left needs acc & right does not */
5846   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5847       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5848     operand *tmp = right ;
5849     right = left;
5850     left = tmp;
5851   }
5852
5853   /* if result = right then exchange them */
5854   if(pic14_sameRegs(AOP(result),AOP(right))){
5855     operand *tmp = right ;
5856     right = left;
5857     left = tmp;
5858   }
5859
5860   /* if right is bit then exchange them */
5861   if (AOP_TYPE(right) == AOP_CRY &&
5862       AOP_TYPE(left) != AOP_CRY){
5863     operand *tmp = right ;
5864     right = left;
5865     left = tmp;
5866   }
5867   if(AOP_TYPE(right) == AOP_LIT)
5868     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5869
5870   size = AOP_SIZE(result);
5871
5872   // if(bit ^ yy)
5873   // xx = bit ^ yy;
5874   if (AOP_TYPE(left) == AOP_CRY){
5875     if(AOP_TYPE(right) == AOP_LIT){
5876       // c = bit & literal;
5877       if(lit>>1){
5878         // lit>>1  != 0 => result = 1
5879         if(AOP_TYPE(result) == AOP_CRY){
5880           if(size)
5881             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5882             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5883           else if(ifx)
5884             continueIfTrue(ifx);
5885           goto release;
5886         }
5887         pic14_emitcode("setb","c");
5888       } else{
5889         // lit == (0 or 1)
5890         if(lit == 0){
5891           // lit == 0, result = left
5892           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5893             goto release;
5894           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5895         } else{
5896           // lit == 1, result = not(left)
5897           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5898             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5899             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5900             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5901             goto release;
5902           } else {
5903             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5904             pic14_emitcode("cpl","c");
5905           }
5906         }
5907       }
5908
5909     } else {
5910       // right != literal
5911       symbol *tlbl = newiTempLabel(NULL);
5912       if (AOP_TYPE(right) == AOP_CRY){
5913         // c = bit ^ bit;
5914         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5915       }
5916       else{
5917         int sizer = AOP_SIZE(right);
5918         // c = bit ^ val
5919         // if val>>1 != 0, result = 1
5920         pic14_emitcode("setb","c");
5921         while(sizer){
5922           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5923           if(sizer == 1)
5924             // test the msb of the lsb
5925             pic14_emitcode("anl","a,#0xfe");
5926           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5927           sizer--;
5928         }
5929         // val = (0,1)
5930         pic14_emitcode("rrc","a");
5931       }
5932       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5933       pic14_emitcode("cpl","c");
5934       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5935     }
5936     // bit = c
5937     // val = c
5938     if(size)
5939       pic14_outBitC(result);
5940     // if(bit | ...)
5941     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5942       genIfxJump(ifx, "c");           
5943     goto release ;
5944   }
5945
5946   if(pic14_sameRegs(AOP(result),AOP(left))){
5947     /* if left is same as result */
5948     for(;size--; offset++) {
5949       if(AOP_TYPE(right) == AOP_LIT){
5950         int t  = (lit >> (offset*8)) & 0x0FFL;
5951         if(t == 0x00L)
5952           continue;
5953         else
5954           if (IS_AOP_PREG(left)) {
5955             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5956             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5957             aopPut(AOP(result),"a",offset);
5958           } else {
5959             emitpcode(POC_MOVLW, popGetLit(t));
5960             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5961             pic14_emitcode("xrl","%s,%s",
5962                            aopGet(AOP(left),offset,FALSE,TRUE),
5963                            aopGet(AOP(right),offset,FALSE,FALSE));
5964           }
5965       } else {
5966         if (AOP_TYPE(left) == AOP_ACC)
5967           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5968         else {
5969           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5970           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5971 /*
5972           if (IS_AOP_PREG(left)) {
5973             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5974             aopPut(AOP(result),"a",offset);
5975           } else
5976             pic14_emitcode("xrl","%s,a",
5977                            aopGet(AOP(left),offset,FALSE,TRUE));
5978 */
5979         }
5980       }
5981     }
5982   } else {
5983     // left & result in different registers
5984     if(AOP_TYPE(result) == AOP_CRY){
5985       // result = bit
5986       // if(size), result in bit
5987       // if(!size && ifx), conditional oper: if(left ^ right)
5988       symbol *tlbl = newiTempLabel(NULL);
5989       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5990       if(size)
5991         pic14_emitcode("setb","c");
5992       while(sizer--){
5993         if((AOP_TYPE(right) == AOP_LIT) &&
5994            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5995           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5996         } else {
5997           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5998           pic14_emitcode("xrl","a,%s",
5999                          aopGet(AOP(left),offset,FALSE,FALSE));
6000         }
6001         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6002         offset++;
6003       }
6004       if(size){
6005         CLRC;
6006         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6007         pic14_outBitC(result);
6008       } else if(ifx)
6009         jmpTrueOrFalse(ifx, tlbl);
6010     } else for(;(size--);offset++){
6011       // normal case
6012       // result = left & right
6013       if(AOP_TYPE(right) == AOP_LIT){
6014         int t = (lit >> (offset*8)) & 0x0FFL;
6015         switch(t) { 
6016         case 0x00:
6017           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6018           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6019           pic14_emitcode("movf","%s,w",
6020                          aopGet(AOP(left),offset,FALSE,FALSE));
6021           pic14_emitcode("movwf","%s",
6022                          aopGet(AOP(result),offset,FALSE,FALSE));
6023           break;
6024         case 0xff:
6025           emitpcode(POC_COMFW,popGet(AOP(left),offset));
6026           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027           pic14_emitcode("comf","%s,w",
6028                          aopGet(AOP(left),offset,FALSE,FALSE));
6029           pic14_emitcode("movwf","%s",
6030                          aopGet(AOP(result),offset,FALSE,FALSE));
6031           break;
6032         default:
6033           emitpcode(POC_MOVLW, popGetLit(t));
6034           emitpcode(POC_XORFW,popGet(AOP(left),offset));
6035           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6036           pic14_emitcode("movlw","0x%x",t);
6037           pic14_emitcode("xorwf","%s,w",
6038                          aopGet(AOP(left),offset,FALSE,FALSE));
6039           pic14_emitcode("movwf","%s",
6040                          aopGet(AOP(result),offset,FALSE,FALSE));
6041
6042         }
6043         continue;
6044       }
6045
6046       // faster than result <- left, anl result,right
6047       // and better if result is SFR
6048       if (AOP_TYPE(left) == AOP_ACC) {
6049         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6050         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6051       } else {
6052         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6053         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6054         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6055         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6056       }
6057       if ( AOP_TYPE(result) != AOP_ACC){
6058         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6059         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6060       }
6061     }
6062   }
6063
6064   release :
6065     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6066   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067   freeAsmop(result,NULL,ic,TRUE);     
6068 }
6069
6070 /*-----------------------------------------------------------------*/
6071 /* genInline - write the inline code out                           */
6072 /*-----------------------------------------------------------------*/
6073 static void genInline (iCode *ic)
6074 {
6075     char *buffer, *bp, *bp1;
6076     
6077     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6078
6079     _G.inLine += (!options.asmpeep);
6080
6081     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6082     strcpy(buffer,IC_INLINE(ic));
6083
6084     /* emit each line as a code */
6085     while (*bp) {
6086         if (*bp == '\n') {
6087             *bp++ = '\0';
6088
6089             if(*bp1)
6090               addpCode2pBlock(pb,AssembleLine(bp1));
6091             bp1 = bp;
6092         } else {
6093             if (*bp == ':') {
6094                 bp++;
6095                 *bp = '\0';
6096                 bp++;
6097                 pic14_emitcode(bp1,"");
6098                 bp1 = bp;
6099             } else
6100                 bp++;
6101         }
6102     }
6103     if ((bp1 != bp) && *bp1)
6104       addpCode2pBlock(pb,AssembleLine(bp1));
6105
6106     Safe_free(buffer);
6107
6108     _G.inLine -= (!options.asmpeep);
6109 }
6110
6111 /*-----------------------------------------------------------------*/
6112 /* genRRC - rotate right with carry                                */
6113 /*-----------------------------------------------------------------*/
6114 static void genRRC (iCode *ic)
6115 {
6116   operand *left , *result ;
6117   int size, offset = 0, same;
6118
6119   /* rotate right with carry */
6120   left = IC_LEFT(ic);
6121   result=IC_RESULT(ic);
6122   aopOp (left,ic,FALSE);
6123   aopOp (result,ic,FALSE);
6124
6125   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6126
6127   same = pic14_sameRegs(AOP(result),AOP(left));
6128
6129   size = AOP_SIZE(result);    
6130
6131   /* get the lsb and put it into the carry */
6132   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6133
6134   offset = 0 ;
6135
6136   while(size--) {
6137
6138     if(same) {
6139       emitpcode(POC_RRF, popGet(AOP(left),offset));
6140     } else {
6141       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6142       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6143     }
6144
6145     offset++;
6146   }
6147
6148   freeAsmop(left,NULL,ic,TRUE);
6149   freeAsmop(result,NULL,ic,TRUE);
6150 }
6151
6152 /*-----------------------------------------------------------------*/
6153 /* genRLC - generate code for rotate left with carry               */
6154 /*-----------------------------------------------------------------*/
6155 static void genRLC (iCode *ic)
6156 {    
6157   operand *left , *result ;
6158   int size, offset = 0;
6159   int same;
6160
6161   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6162   /* rotate right with carry */
6163   left = IC_LEFT(ic);
6164   result=IC_RESULT(ic);
6165   aopOp (left,ic,FALSE);
6166   aopOp (result,ic,FALSE);
6167
6168   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6169
6170   same = pic14_sameRegs(AOP(result),AOP(left));
6171
6172   /* move it to the result */
6173   size = AOP_SIZE(result);    
6174
6175   /* get the msb and put it into the carry */
6176   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6177
6178   offset = 0 ;
6179
6180   while(size--) {
6181
6182     if(same) {
6183       emitpcode(POC_RLF, popGet(AOP(left),offset));
6184     } else {
6185       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6186       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6187     }
6188
6189     offset++;
6190   }
6191
6192
6193   freeAsmop(left,NULL,ic,TRUE);
6194   freeAsmop(result,NULL,ic,TRUE);
6195 }
6196
6197 /*-----------------------------------------------------------------*/
6198 /* genGetHbit - generates code get highest order bit               */
6199 /*-----------------------------------------------------------------*/
6200 static void genGetHbit (iCode *ic)
6201 {
6202     operand *left, *result;
6203     left = IC_LEFT(ic);
6204     result=IC_RESULT(ic);
6205     aopOp (left,ic,FALSE);
6206     aopOp (result,ic,FALSE);
6207
6208     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6209     /* get the highest order byte into a */
6210     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6211     if(AOP_TYPE(result) == AOP_CRY){
6212         pic14_emitcode("rlc","a");
6213         pic14_outBitC(result);
6214     }
6215     else{
6216         pic14_emitcode("rl","a");
6217         pic14_emitcode("anl","a,#0x01");
6218         pic14_outAcc(result);
6219     }
6220
6221
6222     freeAsmop(left,NULL,ic,TRUE);
6223     freeAsmop(result,NULL,ic,TRUE);
6224 }
6225
6226 /*-----------------------------------------------------------------*/
6227 /* AccRol - rotate left accumulator by known count                 */
6228 /*-----------------------------------------------------------------*/
6229 static void AccRol (int shCount)
6230 {
6231     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6232     shCount &= 0x0007;              // shCount : 0..7
6233     switch(shCount){
6234         case 0 :
6235             break;
6236         case 1 :
6237             pic14_emitcode("rl","a");
6238             break;
6239         case 2 :
6240             pic14_emitcode("rl","a");
6241             pic14_emitcode("rl","a");
6242             break;
6243         case 3 :
6244             pic14_emitcode("swap","a");
6245             pic14_emitcode("rr","a");
6246             break;
6247         case 4 :
6248             pic14_emitcode("swap","a");
6249             break;
6250         case 5 :
6251             pic14_emitcode("swap","a");
6252             pic14_emitcode("rl","a");
6253             break;
6254         case 6 :
6255             pic14_emitcode("rr","a");
6256             pic14_emitcode("rr","a");
6257             break;
6258         case 7 :
6259             pic14_emitcode("rr","a");
6260             break;
6261     }
6262 }
6263
6264 /*-----------------------------------------------------------------*/
6265 /* AccLsh - left shift accumulator by known count                  */
6266 /*-----------------------------------------------------------------*/
6267 static void AccLsh (int shCount)
6268 {
6269     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6270     if(shCount != 0){
6271         if(shCount == 1)
6272             pic14_emitcode("add","a,acc");
6273         else 
6274             if(shCount == 2) {
6275             pic14_emitcode("add","a,acc");
6276             pic14_emitcode("add","a,acc");
6277         } else {
6278             /* rotate left accumulator */
6279             AccRol(shCount);
6280             /* and kill the lower order bits */
6281             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6282         }
6283     }
6284 }
6285
6286 /*-----------------------------------------------------------------*/
6287 /* AccRsh - right shift accumulator by known count                 */
6288 /*-----------------------------------------------------------------*/
6289 static void AccRsh (int shCount)
6290 {
6291     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6292     if(shCount != 0){
6293         if(shCount == 1){
6294             CLRC;
6295             pic14_emitcode("rrc","a");
6296         } else {
6297             /* rotate right accumulator */
6298             AccRol(8 - shCount);
6299             /* and kill the higher order bits */
6300             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6301         }
6302     }
6303 }
6304
6305 #if 0
6306 /*-----------------------------------------------------------------*/
6307 /* AccSRsh - signed right shift accumulator by known count                 */
6308 /*-----------------------------------------------------------------*/
6309 static void AccSRsh (int shCount)
6310 {
6311     symbol *tlbl ;
6312     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6313     if(shCount != 0){
6314         if(shCount == 1){
6315             pic14_emitcode("mov","c,acc.7");
6316             pic14_emitcode("rrc","a");
6317         } else if(shCount == 2){
6318             pic14_emitcode("mov","c,acc.7");
6319             pic14_emitcode("rrc","a");
6320             pic14_emitcode("mov","c,acc.7");
6321             pic14_emitcode("rrc","a");
6322         } else {
6323             tlbl = newiTempLabel(NULL);
6324             /* rotate right accumulator */
6325             AccRol(8 - shCount);
6326             /* and kill the higher order bits */
6327             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6328             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6329             pic14_emitcode("orl","a,#0x%02x",
6330                      (unsigned char)~SRMask[shCount]);
6331             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6332         }
6333     }
6334 }
6335 #endif
6336 /*-----------------------------------------------------------------*/
6337 /* shiftR1Left2Result - shift right one byte from left to result   */
6338 /*-----------------------------------------------------------------*/
6339 static void shiftR1Left2ResultSigned (operand *left, int offl,
6340                                 operand *result, int offr,
6341                                 int shCount)
6342 {
6343   int same;
6344
6345   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6346
6347   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6348
6349   switch(shCount) {
6350   case 1:
6351     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6352     if(same) 
6353       emitpcode(POC_RRF, popGet(AOP(result),offr));
6354     else {
6355       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6356       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6357     }
6358
6359     break;
6360   case 2:
6361
6362     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6363     if(same) 
6364       emitpcode(POC_RRF, popGet(AOP(result),offr));
6365     else {
6366       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6367       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368     }
6369     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6370     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6371
6372     break;
6373
6374   case 3:
6375     if(same)
6376       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6377     else {
6378       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6379       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6380     }
6381
6382     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6383     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6384     emitpcode(POC_ANDLW, popGetLit(0x1f));
6385
6386     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6387     emitpcode(POC_IORLW, popGetLit(0xe0));
6388
6389     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6390     break;
6391
6392   case 4:
6393     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6394     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6395     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6396     emitpcode(POC_IORLW,  popGetLit(0xf0));
6397     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6398     break;
6399   case 5:
6400     if(same) {
6401       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6402     } else {
6403       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6404       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6405     }
6406     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6407     emitpcode(POC_ANDLW,  popGetLit(0x07));
6408     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6409     emitpcode(POC_IORLW,  popGetLit(0xf8));
6410     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6411     break;
6412
6413   case 6:
6414     if(same) {
6415       emitpcode(POC_MOVLW, popGetLit(0x00));
6416       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6417       emitpcode(POC_MOVLW, popGetLit(0xfe));
6418       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6419       emitpcode(POC_IORLW, popGetLit(0x01));
6420       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6421     } else {
6422       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6423       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6425       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6427     }
6428     break;
6429
6430   case 7:
6431     if(same) {
6432       emitpcode(POC_MOVLW, popGetLit(0x00));
6433       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6434       emitpcode(POC_MOVLW, popGetLit(0xff));
6435       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436     } else {
6437       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6438       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6439       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6440     }
6441
6442   default:
6443     break;
6444   }
6445 }
6446
6447 /*-----------------------------------------------------------------*/
6448 /* shiftR1Left2Result - shift right one byte from left to result   */
6449 /*-----------------------------------------------------------------*/
6450 static void shiftR1Left2Result (operand *left, int offl,
6451                                 operand *result, int offr,
6452                                 int shCount, int sign)
6453 {
6454   int same;
6455
6456   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6457
6458   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6459
6460   /* Copy the msb into the carry if signed. */
6461   if(sign) {
6462     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6463     return;
6464   }
6465
6466
6467
6468   switch(shCount) {
6469   case 1:
6470     emitCLRC;
6471     if(same) 
6472       emitpcode(POC_RRF, popGet(AOP(result),offr));
6473     else {
6474       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6476     }
6477     break;
6478   case 2:
6479     emitCLRC;
6480     if(same) {
6481       emitpcode(POC_RRF, popGet(AOP(result),offr));
6482     } else {
6483       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6484       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6485     }
6486     emitCLRC;
6487     emitpcode(POC_RRF, popGet(AOP(result),offr));
6488
6489     break;
6490   case 3:
6491     if(same)
6492       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6493     else {
6494       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6495       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6496     }
6497
6498     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6499     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6500     emitpcode(POC_ANDLW, popGetLit(0x1f));
6501     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502     break;
6503       
6504   case 4:
6505     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6506     emitpcode(POC_ANDLW, popGetLit(0x0f));
6507     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6508     break;
6509
6510   case 5:
6511     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6512     emitpcode(POC_ANDLW, popGetLit(0x0f));
6513     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514     emitCLRC;
6515     emitpcode(POC_RRF, popGet(AOP(result),offr));
6516
6517     break;
6518   case 6:
6519
6520     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6521     emitpcode(POC_ANDLW, popGetLit(0x80));
6522     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6523     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6524     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6525     break;
6526
6527   case 7:
6528
6529     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6530     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6531     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6532
6533     break;
6534
6535   default:
6536     break;
6537   }
6538 }
6539
6540 /*-----------------------------------------------------------------*/
6541 /* shiftL1Left2Result - shift left one byte from left to result    */
6542 /*-----------------------------------------------------------------*/
6543 static void shiftL1Left2Result (operand *left, int offl,
6544                                 operand *result, int offr, int shCount)
6545 {
6546   int same;
6547
6548   //    char *l;
6549   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6550
6551   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6552   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6553     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6554     //    MOVA(l);
6555     /* shift left accumulator */
6556     //AccLsh(shCount); // don't comment out just yet...
6557   //    aopPut(AOP(result),"a",offr);
6558
6559   switch(shCount) {
6560   case 1:
6561     /* Shift left 1 bit position */
6562     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6563     if(same) {
6564       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6565     } else {
6566       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6567       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6568     }
6569     break;
6570   case 2:
6571     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6572     emitpcode(POC_ANDLW,popGetLit(0x7e));
6573     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6574     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6575     break;
6576   case 3:
6577     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6578     emitpcode(POC_ANDLW,popGetLit(0x3e));
6579     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6580     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6581     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6582     break;
6583   case 4:
6584     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6585     emitpcode(POC_ANDLW, popGetLit(0xf0));
6586     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6587     break;
6588   case 5:
6589     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6590     emitpcode(POC_ANDLW, popGetLit(0xf0));
6591     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6592     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6593     break;
6594   case 6:
6595     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6596     emitpcode(POC_ANDLW, popGetLit(0x30));
6597     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6598     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6599     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6600     break;
6601   case 7:
6602     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6603     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6604     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6605     break;
6606
6607   default:
6608     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6609   }
6610
6611 }
6612
6613 /*-----------------------------------------------------------------*/
6614 /* movLeft2Result - move byte from left to result                  */
6615 /*-----------------------------------------------------------------*/
6616 static void movLeft2Result (operand *left, int offl,
6617                             operand *result, int offr)
6618 {
6619   char *l;
6620   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6621   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6622     l = aopGet(AOP(left),offl,FALSE,FALSE);
6623
6624     if (*l == '@' && (IS_AOP_PREG(result))) {
6625       pic14_emitcode("mov","a,%s",l);
6626       aopPut(AOP(result),"a",offr);
6627     } else {
6628       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6629       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6630     }
6631   }
6632 }
6633
6634 /*-----------------------------------------------------------------*/
6635 /* shiftL2Left2Result - shift left two bytes from left to result   */
6636 /*-----------------------------------------------------------------*/
6637 static void shiftL2Left2Result (operand *left, int offl,
6638                                 operand *result, int offr, int shCount)
6639 {
6640
6641
6642   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6643
6644   if(pic14_sameRegs(AOP(result), AOP(left))) {
6645     switch(shCount) {
6646     case 0:
6647       break;
6648     case 1:
6649     case 2:
6650     case 3:
6651
6652       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6653       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6654       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6655
6656       while(--shCount) {
6657         emitCLRC;
6658         emitpcode(POC_RLF, popGet(AOP(result),offr));
6659         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6660       }
6661
6662       break;
6663     case 4:
6664     case 5:
6665       emitpcode(POC_MOVLW, popGetLit(0x0f));
6666       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6667       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6668       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6669       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6670       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6671       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6672       if(shCount >=5) {
6673         emitpcode(POC_RLF, popGet(AOP(result),offr));
6674         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6675       }
6676       break;
6677     case 6:
6678       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6679       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6680       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6681       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6682       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6683       emitpcode(POC_ANDLW,popGetLit(0xc0));
6684       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6685       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6686       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6688       break;
6689     case 7:
6690       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6691       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6692       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6693       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6694       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6695     }
6696
6697   } else {
6698     switch(shCount) {
6699     case 0:
6700       break;
6701     case 1:
6702     case 2:
6703     case 3:
6704       /* note, use a mov/add for the shift since the mov has a
6705          chance of getting optimized out */
6706       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6707       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6708       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6709       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6710       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6711
6712       while(--shCount) {
6713         emitCLRC;
6714         emitpcode(POC_RLF, popGet(AOP(result),offr));
6715         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6716       }
6717       break;
6718
6719     case 4:
6720     case 5:
6721       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6722       emitpcode(POC_ANDLW, popGetLit(0xF0));
6723       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6724       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6725       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6726       emitpcode(POC_ANDLW, popGetLit(0xF0));
6727       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6728       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6729
6730
6731       if(shCount == 5) {
6732         emitpcode(POC_RLF, popGet(AOP(result),offr));
6733         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6734       }
6735       break;
6736     case 6:
6737       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6738       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6739       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6740       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6741
6742       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6743       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6744       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6745       emitpcode(POC_ANDLW,popGetLit(0xc0));
6746       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6747       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6748       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6749       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6750       break;
6751     case 7:
6752       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6753       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6754       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6756       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6757     }
6758   }
6759
6760 }
6761 /*-----------------------------------------------------------------*/
6762 /* shiftR2Left2Result - shift right two bytes from left to result  */
6763 /*-----------------------------------------------------------------*/
6764 static void shiftR2Left2Result (operand *left, int offl,
6765                                 operand *result, int offr,
6766                                 int shCount, int sign)
6767 {
6768   int same=0;
6769
6770   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6771   same = pic14_sameRegs(AOP(result), AOP(left));
6772
6773   if(same && ((offl + MSB16) == offr)){
6774     same=1;
6775     /* don't crash result[offr] */
6776     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6777     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6778   } else {
6779     movLeft2Result(left,offl, result, offr);
6780     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6781   }
6782   /* a:x >> shCount (x = lsb(result))*/
6783 /*
6784   if(sign)
6785     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6786   else {
6787     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6788 */
6789   switch(shCount) {
6790   case 0:
6791     break;
6792   case 1:
6793   case 2:
6794   case 3:
6795     if(sign)
6796       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6797     else
6798       emitCLRC;
6799
6800     if(same) {
6801       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6802       emitpcode(POC_RRF,popGet(AOP(result),offr));
6803     } else {
6804       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6805       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6806       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6807       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6808     }
6809
6810     while(--shCount) {
6811       if(sign)
6812         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6813       else
6814         emitCLRC;
6815       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6816       emitpcode(POC_RRF,popGet(AOP(result),offr));
6817     }
6818     break;
6819   case 4:
6820   case 5:
6821     if(same) {
6822
6823       emitpcode(POC_MOVLW, popGetLit(0xf0));
6824       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6825       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6826
6827       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6828       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6829       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6830       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6831     } else {
6832       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6833       emitpcode(POC_ANDLW, popGetLit(0x0f));
6834       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6835
6836       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6837       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6838       emitpcode(POC_ANDLW, popGetLit(0xf0));
6839       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6840       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6841     }
6842
6843     if(shCount >=5) {
6844       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6845       emitpcode(POC_RRF, popGet(AOP(result),offr));
6846     }
6847
6848     if(sign) {
6849       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6850       emitpcode(POC_BTFSC, 
6851                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6852       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6853     }
6854
6855     break;
6856
6857   case 6:
6858     if(same) {
6859
6860       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6861       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6862
6863       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6864       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6865       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6866       emitpcode(POC_ANDLW,popGetLit(0x03));
6867       if(sign) {
6868         emitpcode(POC_BTFSC, 
6869                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6870         emitpcode(POC_IORLW,popGetLit(0xfc));
6871       }
6872       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6873       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6874       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6875       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6876     } else {
6877       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6878       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6879       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6880       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6881       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6882       emitpcode(POC_ANDLW,popGetLit(0x03));
6883       if(sign) {
6884         emitpcode(POC_BTFSC, 
6885                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6886         emitpcode(POC_IORLW,popGetLit(0xfc));
6887       }
6888       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6889       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6890
6891         
6892     }
6893
6894     break;
6895   case 7:
6896     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6897     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6898     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6899     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6900     if(sign) {
6901       emitSKPNC;
6902       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6903     } else 
6904       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6905   }
6906 }
6907
6908
6909 /*-----------------------------------------------------------------*/
6910 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6911 /*-----------------------------------------------------------------*/
6912 static void shiftLLeftOrResult (operand *left, int offl,
6913                                 operand *result, int offr, int shCount)
6914 {
6915     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6916     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6917     /* shift left accumulator */
6918     AccLsh(shCount);
6919     /* or with result */
6920     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6921     /* back to result */
6922     aopPut(AOP(result),"a",offr);
6923 }
6924
6925 /*-----------------------------------------------------------------*/
6926 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6927 /*-----------------------------------------------------------------*/
6928 static void shiftRLeftOrResult (operand *left, int offl,
6929                                 operand *result, int offr, int shCount)
6930 {
6931     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6932     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6933     /* shift right accumulator */
6934     AccRsh(shCount);
6935     /* or with result */
6936     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6937     /* back to result */
6938     aopPut(AOP(result),"a",offr);
6939 }
6940
6941 /*-----------------------------------------------------------------*/
6942 /* genlshOne - left shift a one byte quantity by known count       */
6943 /*-----------------------------------------------------------------*/
6944 static void genlshOne (operand *result, operand *left, int shCount)
6945 {       
6946     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6947     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6948 }
6949
6950 /*-----------------------------------------------------------------*/
6951 /* genlshTwo - left shift two bytes by known amount != 0           */
6952 /*-----------------------------------------------------------------*/
6953 static void genlshTwo (operand *result,operand *left, int shCount)
6954 {
6955     int size;
6956     
6957     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6958     size = pic14_getDataSize(result);
6959
6960     /* if shCount >= 8 */
6961     if (shCount >= 8) {
6962         shCount -= 8 ;
6963
6964         if (size > 1){
6965             if (shCount)
6966                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6967             else 
6968                 movLeft2Result(left, LSB, result, MSB16);
6969         }
6970         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6971     }
6972
6973     /*  1 <= shCount <= 7 */
6974     else {  
6975         if(size == 1)
6976             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6977         else 
6978             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6979     }
6980 }
6981
6982 /*-----------------------------------------------------------------*/
6983 /* shiftLLong - shift left one long from left to result            */
6984 /* offl = LSB or MSB16                                             */
6985 /*-----------------------------------------------------------------*/
6986 static void shiftLLong (operand *left, operand *result, int offr )
6987 {
6988     char *l;
6989     int size = AOP_SIZE(result);
6990
6991     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6992     if(size >= LSB+offr){
6993         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6994         MOVA(l);
6995         pic14_emitcode("add","a,acc");
6996         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6997             size >= MSB16+offr && offr != LSB )
6998             pic14_emitcode("xch","a,%s",
6999                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7000         else        
7001             aopPut(AOP(result),"a",LSB+offr);
7002     }
7003
7004     if(size >= MSB16+offr){
7005         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7006             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7007             MOVA(l);
7008         }
7009         pic14_emitcode("rlc","a");
7010         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7011             size >= MSB24+offr && offr != LSB)
7012             pic14_emitcode("xch","a,%s",
7013                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7014         else        
7015             aopPut(AOP(result),"a",MSB16+offr);
7016     }
7017
7018     if(size >= MSB24+offr){
7019         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7020             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7021             MOVA(l);
7022         }
7023         pic14_emitcode("rlc","a");
7024         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7025             size >= MSB32+offr && offr != LSB )
7026             pic14_emitcode("xch","a,%s",
7027                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7028         else        
7029             aopPut(AOP(result),"a",MSB24+offr);
7030     }
7031
7032     if(size > MSB32+offr){
7033         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7034             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7035             MOVA(l);    
7036         }
7037         pic14_emitcode("rlc","a");
7038         aopPut(AOP(result),"a",MSB32+offr);
7039     }
7040     if(offr != LSB)
7041         aopPut(AOP(result),zero,LSB);       
7042 }
7043
7044 /*-----------------------------------------------------------------*/
7045 /* genlshFour - shift four byte by a known amount != 0             */
7046 /*-----------------------------------------------------------------*/
7047 static void genlshFour (operand *result, operand *left, int shCount)
7048 {
7049     int size;
7050
7051     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7052     size = AOP_SIZE(result);
7053
7054     /* if shifting more that 3 bytes */
7055     if (shCount >= 24 ) {
7056         shCount -= 24;
7057         if (shCount)
7058             /* lowest order of left goes to the highest
7059             order of the destination */
7060             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7061         else
7062             movLeft2Result(left, LSB, result, MSB32);
7063         aopPut(AOP(result),zero,LSB);
7064         aopPut(AOP(result),zero,MSB16);
7065         aopPut(AOP(result),zero,MSB32);
7066         return;
7067     }
7068
7069     /* more than two bytes */
7070     else if ( shCount >= 16 ) {
7071         /* lower order two bytes goes to higher order two bytes */
7072         shCount -= 16;
7073         /* if some more remaining */
7074         if (shCount)
7075             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7076         else {
7077             movLeft2Result(left, MSB16, result, MSB32);
7078             movLeft2Result(left, LSB, result, MSB24);
7079         }
7080         aopPut(AOP(result),zero,MSB16);
7081         aopPut(AOP(result),zero,LSB);
7082         return;
7083     }    
7084
7085     /* if more than 1 byte */
7086     else if ( shCount >= 8 ) {
7087         /* lower order three bytes goes to higher order  three bytes */
7088         shCount -= 8;
7089         if(size == 2){
7090             if(shCount)
7091                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7092             else
7093                 movLeft2Result(left, LSB, result, MSB16);
7094         }
7095         else{   /* size = 4 */
7096             if(shCount == 0){
7097                 movLeft2Result(left, MSB24, result, MSB32);
7098                 movLeft2Result(left, MSB16, result, MSB24);
7099                 movLeft2Result(left, LSB, result, MSB16);
7100                 aopPut(AOP(result),zero,LSB);
7101             }
7102             else if(shCount == 1)
7103                 shiftLLong(left, result, MSB16);
7104             else{
7105                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7106                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7107                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7108                 aopPut(AOP(result),zero,LSB);
7109             }
7110         }
7111     }
7112
7113     /* 1 <= shCount <= 7 */
7114     else if(shCount <= 2){
7115         shiftLLong(left, result, LSB);
7116         if(shCount == 2)
7117             shiftLLong(result, result, LSB);
7118     }
7119     /* 3 <= shCount <= 7, optimize */
7120     else{
7121         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7122         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7123         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7124     }
7125 }
7126
7127 /*-----------------------------------------------------------------*/
7128 /* genLeftShiftLiteral - left shifting by known count              */
7129 /*-----------------------------------------------------------------*/
7130 static void genLeftShiftLiteral (operand *left,
7131                                  operand *right,
7132                                  operand *result,
7133                                  iCode *ic)
7134 {    
7135     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7136     int size;
7137
7138     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7139     freeAsmop(right,NULL,ic,TRUE);
7140
7141     aopOp(left,ic,FALSE);
7142     aopOp(result,ic,FALSE);
7143
7144     size = getSize(operandType(result));
7145
7146 #if VIEW_SIZE
7147     pic14_emitcode("; shift left ","result %d, left %d",size,
7148              AOP_SIZE(left));
7149 #endif
7150
7151     /* I suppose that the left size >= result size */
7152     if(shCount == 0){
7153         while(size--){
7154             movLeft2Result(left, size, result, size);
7155         }
7156     }
7157
7158     else if(shCount >= (size * 8))
7159         while(size--)
7160             aopPut(AOP(result),zero,size);
7161     else{
7162         switch (size) {
7163             case 1:
7164                 genlshOne (result,left,shCount);
7165                 break;
7166
7167             case 2:
7168             case 3:
7169                 genlshTwo (result,left,shCount);
7170                 break;
7171
7172             case 4:
7173                 genlshFour (result,left,shCount);
7174                 break;
7175         }
7176     }
7177     freeAsmop(left,NULL,ic,TRUE);
7178     freeAsmop(result,NULL,ic,TRUE);
7179 }
7180
7181 /*-----------------------------------------------------------------*
7182  * genMultiAsm - repeat assembly instruction for size of register.
7183  * if endian == 1, then the high byte (i.e base address + size of 
7184  * register) is used first else the low byte is used first;
7185  *-----------------------------------------------------------------*/
7186 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7187 {
7188
7189   int offset = 0;
7190
7191   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7192
7193   if(!reg)
7194     return;
7195
7196   if(!endian) {
7197     endian = 1;
7198   } else {
7199     endian = -1;
7200     offset = size-1;
7201   }
7202
7203   while(size--) {
7204     emitpcode(poc,    popGet(AOP(reg),offset));
7205     offset += endian;
7206   }
7207
7208 }
7209 /*-----------------------------------------------------------------*/
7210 /* genLeftShift - generates code for left shifting                 */
7211 /*-----------------------------------------------------------------*/
7212 static void genLeftShift (iCode *ic)
7213 {
7214   operand *left,*right, *result;
7215   int size, offset;
7216   char *l;
7217   symbol *tlbl , *tlbl1;
7218   pCodeOp *pctemp;
7219
7220   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7221
7222   right = IC_RIGHT(ic);
7223   left  = IC_LEFT(ic);
7224   result = IC_RESULT(ic);
7225
7226   aopOp(right,ic,FALSE);
7227
7228   /* if the shift count is known then do it 
7229      as efficiently as possible */
7230   if (AOP_TYPE(right) == AOP_LIT) {
7231     genLeftShiftLiteral (left,right,result,ic);
7232     return ;
7233   }
7234
7235   /* shift count is unknown then we have to form 
7236      a loop get the loop count in B : Note: we take
7237      only the lower order byte since shifting
7238      more that 32 bits make no sense anyway, ( the
7239      largest size of an object can be only 32 bits ) */  
7240
7241     
7242   aopOp(left,ic,FALSE);
7243   aopOp(result,ic,FALSE);
7244
7245   /* now move the left to the result if they are not the
7246      same */
7247   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7248       AOP_SIZE(result) > 1) {
7249
7250     size = AOP_SIZE(result);
7251     offset=0;
7252     while (size--) {
7253       l = aopGet(AOP(left),offset,FALSE,TRUE);
7254       if (*l == '@' && (IS_AOP_PREG(result))) {
7255
7256         pic14_emitcode("mov","a,%s",l);
7257         aopPut(AOP(result),"a",offset);
7258       } else {
7259         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7260         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7261         //aopPut(AOP(result),l,offset);
7262       }
7263       offset++;
7264     }
7265   }
7266
7267   size = AOP_SIZE(result);
7268
7269   /* if it is only one byte then */
7270   if (size == 1) {
7271     if(optimized_for_speed) {
7272       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7273       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7274       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7275       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7276       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7277       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7278       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7279       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7280       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7281       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7282       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7283       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7284     } else {
7285
7286       tlbl = newiTempLabel(NULL);
7287       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7288         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7289         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7290       }
7291
7292       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7293       emitpcode(POC_RRF,    popGet(AOP(result),0));
7294       emitpLabel(tlbl->key);
7295       emitpcode(POC_RLF,    popGet(AOP(result),0));
7296       emitpcode(POC_ADDLW,  popGetLit(1));
7297       emitSKPC;
7298       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7299     }
7300     goto release ;
7301   }
7302     
7303   if (pic14_sameRegs(AOP(left),AOP(result))) {
7304
7305     tlbl = newiTempLabel(NULL);
7306     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7307     genMultiAsm(POC_RRF, result, size,1);
7308     emitpLabel(tlbl->key);
7309     genMultiAsm(POC_RLF, result, size,0);
7310     emitpcode(POC_ADDLW,  popGetLit(1));
7311     emitSKPC;
7312     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7313     goto release;
7314   }
7315
7316   //tlbl = newiTempLabel(NULL);
7317   //offset = 0 ;   
7318   //tlbl1 = newiTempLabel(NULL);
7319
7320   //reAdjustPreg(AOP(result));    
7321     
7322   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7323   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7324   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7325   //MOVA(l);
7326   //pic14_emitcode("add","a,acc");         
7327   //aopPut(AOP(result),"a",offset++);
7328   //while (--size) {
7329   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7330   //  MOVA(l);
7331   //  pic14_emitcode("rlc","a");         
7332   //  aopPut(AOP(result),"a",offset++);
7333   //}
7334   //reAdjustPreg(AOP(result));
7335
7336   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7337   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7338
7339
7340   tlbl = newiTempLabel(NULL);
7341   tlbl1= newiTempLabel(NULL);
7342
7343   size = AOP_SIZE(result);
7344   offset = 1;
7345
7346   pctemp = popGetTempReg();  /* grab a temporary working register. */
7347
7348   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7349
7350   /* offset should be 0, 1 or 3 */
7351   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7352   emitSKPNZ;
7353   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7354
7355   emitpcode(POC_MOVWF, pctemp);
7356
7357
7358   emitpLabel(tlbl->key);
7359
7360   emitCLRC;
7361   emitpcode(POC_RLF,  popGet(AOP(result),0));
7362   while(--size)
7363     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7364
7365   emitpcode(POC_DECFSZ,  pctemp);
7366   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7367   emitpLabel(tlbl1->key);
7368
7369   popReleaseTempReg(pctemp);
7370
7371
7372  release:
7373   freeAsmop (right,NULL,ic,TRUE);
7374   freeAsmop(left,NULL,ic,TRUE);
7375   freeAsmop(result,NULL,ic,TRUE);
7376 }
7377
7378 /*-----------------------------------------------------------------*/
7379 /* genrshOne - right shift a one byte quantity by known count      */
7380 /*-----------------------------------------------------------------*/
7381 static void genrshOne (operand *result, operand *left,
7382                        int shCount, int sign)
7383 {
7384     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7385     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7386 }
7387
7388 /*-----------------------------------------------------------------*/
7389 /* genrshTwo - right shift two bytes by known amount != 0          */
7390 /*-----------------------------------------------------------------*/
7391 static void genrshTwo (operand *result,operand *left,
7392                        int shCount, int sign)
7393 {
7394   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7395   /* if shCount >= 8 */
7396   if (shCount >= 8) {
7397     shCount -= 8 ;
7398     if (shCount)
7399       shiftR1Left2Result(left, MSB16, result, LSB,
7400                          shCount, sign);
7401     else
7402       movLeft2Result(left, MSB16, result, LSB);
7403
7404     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7405
7406     if(sign) {
7407       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7408       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7409     }
7410   }
7411
7412   /*  1 <= shCount <= 7 */
7413   else
7414     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7415 }
7416
7417 /*-----------------------------------------------------------------*/
7418 /* shiftRLong - shift right one long from left to result           */
7419 /* offl = LSB or MSB16                                             */
7420 /*-----------------------------------------------------------------*/
7421 static void shiftRLong (operand *left, int offl,
7422                         operand *result, int sign)
7423 {
7424     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7425     if(!sign)
7426         pic14_emitcode("clr","c");
7427     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7428     if(sign)
7429         pic14_emitcode("mov","c,acc.7");
7430     pic14_emitcode("rrc","a");
7431     aopPut(AOP(result),"a",MSB32-offl);
7432     if(offl == MSB16)
7433         /* add sign of "a" */
7434         addSign(result, MSB32, sign);
7435
7436     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7437     pic14_emitcode("rrc","a");
7438     aopPut(AOP(result),"a",MSB24-offl);
7439
7440     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7441     pic14_emitcode("rrc","a");
7442     aopPut(AOP(result),"a",MSB16-offl);
7443
7444     if(offl == LSB){
7445         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7446         pic14_emitcode("rrc","a");
7447         aopPut(AOP(result),"a",LSB);
7448     }
7449 }
7450
7451 /*-----------------------------------------------------------------*/
7452 /* genrshFour - shift four byte by a known amount != 0             */
7453 /*-----------------------------------------------------------------*/
7454 static void genrshFour (operand *result, operand *left,
7455                         int shCount, int sign)
7456 {
7457   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7458   /* if shifting more that 3 bytes */
7459   if(shCount >= 24 ) {
7460     shCount -= 24;
7461     if(shCount)
7462       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7463     else
7464       movLeft2Result(left, MSB32, result, LSB);
7465
7466     addSign(result, MSB16, sign);
7467   }
7468   else if(shCount >= 16){
7469     shCount -= 16;
7470     if(shCount)
7471       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7472     else{
7473       movLeft2Result(left, MSB24, result, LSB);
7474       movLeft2Result(left, MSB32, result, MSB16);
7475     }
7476     addSign(result, MSB24, sign);
7477   }
7478   else if(shCount >= 8){
7479     shCount -= 8;
7480     if(shCount == 1)
7481       shiftRLong(left, MSB16, result, sign);
7482     else if(shCount == 0){
7483       movLeft2Result(left, MSB16, result, LSB);
7484       movLeft2Result(left, MSB24, result, MSB16);
7485       movLeft2Result(left, MSB32, result, MSB24);
7486       addSign(result, MSB32, sign);
7487     }
7488     else{
7489       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7490       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7491       /* the last shift is signed */
7492       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7493       addSign(result, MSB32, sign);
7494     }
7495   }
7496   else{   /* 1 <= shCount <= 7 */
7497     if(shCount <= 2){
7498       shiftRLong(left, LSB, result, sign);
7499       if(shCount == 2)
7500         shiftRLong(result, LSB, result, sign);
7501     }
7502     else{
7503       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7504       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7505       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7506     }
7507   }
7508 }
7509
7510 /*-----------------------------------------------------------------*/
7511 /* genRightShiftLiteral - right shifting by known count            */
7512 /*-----------------------------------------------------------------*/
7513 static void genRightShiftLiteral (operand *left,
7514                                   operand *right,
7515                                   operand *result,
7516                                   iCode *ic,
7517                                   int sign)
7518 {    
7519   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7520   int lsize,res_size;
7521
7522   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7523   freeAsmop(right,NULL,ic,TRUE);
7524
7525   aopOp(left,ic,FALSE);
7526   aopOp(result,ic,FALSE);
7527
7528 #if VIEW_SIZE
7529   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7530                  AOP_SIZE(left));
7531 #endif
7532
7533   lsize = pic14_getDataSize(left);
7534   res_size = pic14_getDataSize(result);
7535   /* test the LEFT size !!! */
7536
7537   /* I suppose that the left size >= result size */
7538   if(shCount == 0){
7539     while(res_size--)
7540       movLeft2Result(left, lsize, result, res_size);
7541   }
7542
7543   else if(shCount >= (lsize * 8)){
7544
7545     if(res_size == 1) {
7546       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7547       if(sign) {
7548         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7549         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7550       }
7551     } else {
7552
7553       if(sign) {
7554         emitpcode(POC_MOVLW, popGetLit(0));
7555         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7556         emitpcode(POC_MOVLW, popGetLit(0xff));
7557         while(res_size--)
7558           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7559
7560       } else {
7561
7562         while(res_size--)
7563           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7564       }
7565     }
7566   } else {
7567
7568     switch (res_size) {
7569     case 1:
7570       genrshOne (result,left,shCount,sign);
7571       break;
7572
7573     case 2:
7574       genrshTwo (result,left,shCount,sign);
7575       break;
7576
7577     case 4:
7578       genrshFour (result,left,shCount,sign);
7579       break;
7580     default :
7581       break;
7582     }
7583
7584   }
7585
7586   freeAsmop(left,NULL,ic,TRUE);
7587   freeAsmop(result,NULL,ic,TRUE);
7588 }
7589
7590 /*-----------------------------------------------------------------*/
7591 /* genSignedRightShift - right shift of signed number              */
7592 /*-----------------------------------------------------------------*/
7593 static void genSignedRightShift (iCode *ic)
7594 {
7595   operand *right, *left, *result;
7596   int size, offset;
7597   //  char *l;
7598   symbol *tlbl, *tlbl1 ;
7599   pCodeOp *pctemp;
7600
7601   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7602
7603   /* we do it the hard way put the shift count in b
7604      and loop thru preserving the sign */
7605   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7606
7607   right = IC_RIGHT(ic);
7608   left  = IC_LEFT(ic);
7609   result = IC_RESULT(ic);
7610
7611   aopOp(right,ic,FALSE);  
7612   aopOp(left,ic,FALSE);
7613   aopOp(result,ic,FALSE);
7614
7615
7616   if ( AOP_TYPE(right) == AOP_LIT) {
7617     genRightShiftLiteral (left,right,result,ic,1);
7618     return ;
7619   }
7620   /* shift count is unknown then we have to form 
7621      a loop get the loop count in B : Note: we take
7622      only the lower order byte since shifting
7623      more that 32 bits make no sense anyway, ( the
7624      largest size of an object can be only 32 bits ) */  
7625
7626   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7627   //pic14_emitcode("inc","b");
7628   //freeAsmop (right,NULL,ic,TRUE);
7629   //aopOp(left,ic,FALSE);
7630   //aopOp(result,ic,FALSE);
7631
7632   /* now move the left to the result if they are not the
7633      same */
7634   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7635       AOP_SIZE(result) > 1) {
7636
7637     size = AOP_SIZE(result);
7638     offset=0;
7639     while (size--) { 
7640       /*
7641         l = aopGet(AOP(left),offset,FALSE,TRUE);
7642         if (*l == '@' && IS_AOP_PREG(result)) {
7643
7644         pic14_emitcode("mov","a,%s",l);
7645         aopPut(AOP(result),"a",offset);
7646         } else
7647         aopPut(AOP(result),l,offset);
7648       */
7649       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7650       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7651
7652       offset++;
7653     }
7654   }
7655
7656   /* mov the highest order bit to OVR */    
7657   tlbl = newiTempLabel(NULL);
7658   tlbl1= newiTempLabel(NULL);
7659
7660   size = AOP_SIZE(result);
7661   offset = size - 1;
7662
7663   pctemp = popGetTempReg();  /* grab a temporary working register. */
7664
7665   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7666
7667   /* offset should be 0, 1 or 3 */
7668   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7669   emitSKPNZ;
7670   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7671
7672   emitpcode(POC_MOVWF, pctemp);
7673
7674
7675   emitpLabel(tlbl->key);
7676
7677   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7678   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7679
7680   while(--size) {
7681     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7682   }
7683
7684   emitpcode(POC_DECFSZ,  pctemp);
7685   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7686   emitpLabel(tlbl1->key);
7687
7688   popReleaseTempReg(pctemp);
7689 #if 0
7690   size = AOP_SIZE(result);
7691   offset = size - 1;
7692   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7693   pic14_emitcode("rlc","a");
7694   pic14_emitcode("mov","ov,c");
7695   /* if it is only one byte then */
7696   if (size == 1) {
7697     l = aopGet(AOP(left),0,FALSE,FALSE);
7698     MOVA(l);
7699     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7700     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7701     pic14_emitcode("mov","c,ov");
7702     pic14_emitcode("rrc","a");
7703     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7704     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7705     aopPut(AOP(result),"a",0);
7706     goto release ;
7707   }
7708
7709   reAdjustPreg(AOP(result));
7710   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7711   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7712   pic14_emitcode("mov","c,ov");
7713   while (size--) {
7714     l = aopGet(AOP(result),offset,FALSE,FALSE);
7715     MOVA(l);
7716     pic14_emitcode("rrc","a");         
7717     aopPut(AOP(result),"a",offset--);
7718   }
7719   reAdjustPreg(AOP(result));
7720   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7721   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7722
7723  release:
7724 #endif
7725
7726   freeAsmop(left,NULL,ic,TRUE);
7727   freeAsmop(result,NULL,ic,TRUE);
7728   freeAsmop(right,NULL,ic,TRUE);
7729 }
7730
7731 /*-----------------------------------------------------------------*/
7732 /* genRightShift - generate code for right shifting                */
7733 /*-----------------------------------------------------------------*/
7734 static void genRightShift (iCode *ic)
7735 {
7736     operand *right, *left, *result;
7737     sym_link *retype ;
7738     int size, offset;
7739     char *l;
7740     symbol *tlbl, *tlbl1 ;
7741
7742     /* if signed then we do it the hard way preserve the
7743     sign bit moving it inwards */
7744     retype = getSpec(operandType(IC_RESULT(ic)));
7745     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7746
7747     if (!SPEC_USIGN(retype)) {
7748         genSignedRightShift (ic);
7749         return ;
7750     }
7751
7752     /* signed & unsigned types are treated the same : i.e. the
7753     signed is NOT propagated inwards : quoting from the
7754     ANSI - standard : "for E1 >> E2, is equivalent to division
7755     by 2**E2 if unsigned or if it has a non-negative value,
7756     otherwise the result is implementation defined ", MY definition
7757     is that the sign does not get propagated */
7758
7759     right = IC_RIGHT(ic);
7760     left  = IC_LEFT(ic);
7761     result = IC_RESULT(ic);
7762
7763     aopOp(right,ic,FALSE);
7764
7765     /* if the shift count is known then do it 
7766     as efficiently as possible */
7767     if (AOP_TYPE(right) == AOP_LIT) {
7768         genRightShiftLiteral (left,right,result,ic, 0);
7769         return ;
7770     }
7771
7772     /* shift count is unknown then we have to form 
7773     a loop get the loop count in B : Note: we take
7774     only the lower order byte since shifting
7775     more that 32 bits make no sense anyway, ( the
7776     largest size of an object can be only 32 bits ) */  
7777
7778     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7779     pic14_emitcode("inc","b");
7780     aopOp(left,ic,FALSE);
7781     aopOp(result,ic,FALSE);
7782
7783     /* now move the left to the result if they are not the
7784     same */
7785     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7786         AOP_SIZE(result) > 1) {
7787
7788         size = AOP_SIZE(result);
7789         offset=0;
7790         while (size--) {
7791             l = aopGet(AOP(left),offset,FALSE,TRUE);
7792             if (*l == '@' && IS_AOP_PREG(result)) {
7793
7794                 pic14_emitcode("mov","a,%s",l);
7795                 aopPut(AOP(result),"a",offset);
7796             } else
7797                 aopPut(AOP(result),l,offset);
7798             offset++;
7799         }
7800     }
7801
7802     tlbl = newiTempLabel(NULL);
7803     tlbl1= newiTempLabel(NULL);
7804     size = AOP_SIZE(result);
7805     offset = size - 1;
7806
7807     /* if it is only one byte then */
7808     if (size == 1) {
7809
7810       tlbl = newiTempLabel(NULL);
7811       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7812         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7813         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7814       }
7815
7816       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7817       emitpcode(POC_RLF,    popGet(AOP(result),0));
7818       emitpLabel(tlbl->key);
7819       emitpcode(POC_RRF,    popGet(AOP(result),0));
7820       emitpcode(POC_ADDLW,  popGetLit(1));
7821       emitSKPC;
7822       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7823
7824       goto release ;
7825     }
7826
7827     reAdjustPreg(AOP(result));
7828     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7829     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7830     CLRC;
7831     while (size--) {
7832         l = aopGet(AOP(result),offset,FALSE,FALSE);
7833         MOVA(l);
7834         pic14_emitcode("rrc","a");         
7835         aopPut(AOP(result),"a",offset--);
7836     }
7837     reAdjustPreg(AOP(result));
7838
7839     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7840     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7841
7842 release:
7843     freeAsmop(left,NULL,ic,TRUE);
7844     freeAsmop (right,NULL,ic,TRUE);
7845     freeAsmop(result,NULL,ic,TRUE);
7846 }
7847
7848 /*-----------------------------------------------------------------*/
7849 /* genUnpackBits - generates code for unpacking bits               */
7850 /*-----------------------------------------------------------------*/
7851 static void genUnpackBits (operand *result, char *rname, int ptype)
7852 {    
7853     int shCnt ;
7854     int rlen = 0 ;
7855     sym_link *etype;
7856     int offset = 0 ;
7857
7858     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7859     etype = getSpec(operandType(result));
7860
7861     /* read the first byte  */
7862     switch (ptype) {
7863
7864     case POINTER:
7865     case IPOINTER:
7866         pic14_emitcode("mov","a,@%s",rname);
7867         break;
7868         
7869     case PPOINTER:
7870         pic14_emitcode("movx","a,@%s",rname);
7871         break;
7872         
7873     case FPOINTER:
7874         pic14_emitcode("movx","a,@dptr");
7875         break;
7876
7877     case CPOINTER:
7878         pic14_emitcode("clr","a");
7879         pic14_emitcode("movc","a","@a+dptr");
7880         break;
7881
7882     case GPOINTER:
7883         pic14_emitcode("lcall","__gptrget");
7884         break;
7885     }
7886
7887     /* if we have bitdisplacement then it fits   */
7888     /* into this byte completely or if length is */
7889     /* less than a byte                          */
7890     if ((shCnt = SPEC_BSTR(etype)) || 
7891         (SPEC_BLEN(etype) <= 8))  {
7892
7893         /* shift right acc */
7894         AccRsh(shCnt);
7895
7896         pic14_emitcode("anl","a,#0x%02x",
7897                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7898         aopPut(AOP(result),"a",offset);
7899         return ;
7900     }
7901
7902     /* bit field did not fit in a byte  */
7903     rlen = SPEC_BLEN(etype) - 8;
7904     aopPut(AOP(result),"a",offset++);
7905
7906     while (1)  {
7907
7908         switch (ptype) {
7909         case POINTER:
7910         case IPOINTER:
7911             pic14_emitcode("inc","%s",rname);
7912             pic14_emitcode("mov","a,@%s",rname);
7913             break;
7914             
7915         case PPOINTER:
7916             pic14_emitcode("inc","%s",rname);
7917             pic14_emitcode("movx","a,@%s",rname);
7918             break;
7919
7920         case FPOINTER:
7921             pic14_emitcode("inc","dptr");
7922             pic14_emitcode("movx","a,@dptr");
7923             break;
7924             
7925         case CPOINTER:
7926             pic14_emitcode("clr","a");
7927             pic14_emitcode("inc","dptr");
7928             pic14_emitcode("movc","a","@a+dptr");
7929             break;
7930             
7931         case GPOINTER:
7932             pic14_emitcode("inc","dptr");
7933             pic14_emitcode("lcall","__gptrget");
7934             break;
7935         }
7936
7937         rlen -= 8;            
7938         /* if we are done */
7939         if ( rlen <= 0 )
7940             break ;
7941         
7942         aopPut(AOP(result),"a",offset++);
7943                               
7944     }
7945     
7946     if (rlen) {
7947         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7948         aopPut(AOP(result),"a",offset);        
7949     }
7950     
7951     return ;
7952 }
7953
7954 #if 0
7955 /*-----------------------------------------------------------------*/
7956 /* genDataPointerGet - generates code when ptr offset is known     */
7957 /*-----------------------------------------------------------------*/
7958 static void genDataPointerGet (operand *left, 
7959                                operand *result, 
7960                                iCode *ic)
7961 {
7962   int size , offset = 0;
7963
7964
7965   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7966
7967
7968   /* optimization - most of the time, left and result are the same
7969    * address, but different types. for the pic code, we could omit
7970    * the following
7971    */
7972
7973   aopOp(result,ic,TRUE);
7974
7975   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7976
7977   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7978
7979   size = AOP_SIZE(result);
7980
7981   while (size--) {
7982     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7983     offset++;
7984   }
7985
7986   freeAsmop(left,NULL,ic,TRUE);
7987   freeAsmop(result,NULL,ic,TRUE);
7988 }
7989 #endif
7990 /*-----------------------------------------------------------------*/
7991 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7992 /*-----------------------------------------------------------------*/
7993 static void genNearPointerGet (operand *left, 
7994                                operand *result, 
7995                                iCode *ic)
7996 {
7997     asmop *aop = NULL;
7998     //regs *preg = NULL ;
7999     char *rname ;
8000     sym_link *rtype, *retype;
8001     sym_link *ltype = operandType(left);    
8002     //char buffer[80];
8003
8004     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8005
8006     rtype = operandType(result);
8007     retype= getSpec(rtype);
8008     
8009     aopOp(left,ic,FALSE);
8010     
8011     /* if left is rematerialisable and
8012        result is not bit variable type and
8013        the left is pointer to data space i.e
8014        lower 128 bytes of space */
8015     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8016         !IS_BITVAR(retype)         &&
8017         DCL_TYPE(ltype) == POINTER) {
8018       //genDataPointerGet (left,result,ic);
8019         return ;
8020     }
8021     
8022     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8023
8024         /* if the value is already in a pointer register
8025        then don't need anything more */
8026     if (!AOP_INPREG(AOP(left))) {
8027         /* otherwise get a free pointer register */
8028     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8029 /*
8030         aop = newAsmop(0);
8031         preg = getFreePtr(ic,&aop,FALSE);
8032         pic14_emitcode("mov","%s,%s",
8033                 preg->name,
8034                 aopGet(AOP(left),0,FALSE,TRUE));
8035         rname = preg->name ;
8036 */
8037     rname ="BAD";
8038     } else
8039         rname = aopGet(AOP(left),0,FALSE,FALSE);
8040     
8041     aopOp (result,ic,FALSE);
8042     
8043       /* if bitfield then unpack the bits */
8044     if (IS_BITVAR(retype)) 
8045         genUnpackBits (result,rname,POINTER);
8046     else {
8047         /* we have can just get the values */
8048       int size = AOP_SIZE(result);
8049       int offset = 0 ;  
8050         
8051       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8052
8053       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8054       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8055       while(size--) {
8056         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8057         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8058         if(size)
8059           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8060       }
8061 /*
8062         while (size--) {
8063             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8064
8065                 pic14_emitcode("mov","a,@%s",rname);
8066                 aopPut(AOP(result),"a",offset);
8067             } else {
8068                 sprintf(buffer,"@%s",rname);
8069                 aopPut(AOP(result),buffer,offset);
8070             }
8071             offset++ ;
8072             if (size)
8073                 pic14_emitcode("inc","%s",rname);
8074         }
8075 */
8076     }
8077
8078     /* now some housekeeping stuff */
8079     if (aop) {
8080         /* we had to allocate for this iCode */
8081     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8082         freeAsmop(NULL,aop,ic,TRUE);
8083     } else { 
8084         /* we did not allocate which means left
8085            already in a pointer register, then
8086            if size > 0 && this could be used again
8087            we have to point it back to where it 
8088            belongs */
8089     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8090         if (AOP_SIZE(result) > 1 &&
8091             !OP_SYMBOL(left)->remat &&
8092             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8093               ic->depth )) {
8094             int size = AOP_SIZE(result) - 1;
8095             while (size--)
8096                 pic14_emitcode("dec","%s",rname);
8097         }
8098     }
8099
8100     /* done */
8101     freeAsmop(left,NULL,ic,TRUE);
8102     freeAsmop(result,NULL,ic,TRUE);
8103      
8104 }
8105
8106 /*-----------------------------------------------------------------*/
8107 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8108 /*-----------------------------------------------------------------*/
8109 static void genPagedPointerGet (operand *left, 
8110                                operand *result, 
8111                                iCode *ic)
8112 {
8113     asmop *aop = NULL;
8114     regs *preg = NULL ;
8115     char *rname ;
8116     sym_link *rtype, *retype;    
8117
8118     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8119
8120     rtype = operandType(result);
8121     retype= getSpec(rtype);
8122     
8123     aopOp(left,ic,FALSE);
8124
8125   /* if the value is already in a pointer register
8126        then don't need anything more */
8127     if (!AOP_INPREG(AOP(left))) {
8128         /* otherwise get a free pointer register */
8129         aop = newAsmop(0);
8130         preg = getFreePtr(ic,&aop,FALSE);
8131         pic14_emitcode("mov","%s,%s",
8132                 preg->name,
8133                 aopGet(AOP(left),0,FALSE,TRUE));
8134         rname = preg->name ;
8135     } else
8136         rname = aopGet(AOP(left),0,FALSE,FALSE);
8137     
8138     freeAsmop(left,NULL,ic,TRUE);
8139     aopOp (result,ic,FALSE);
8140
8141     /* if bitfield then unpack the bits */
8142     if (IS_BITVAR(retype)) 
8143         genUnpackBits (result,rname,PPOINTER);
8144     else {
8145         /* we have can just get the values */
8146         int size = AOP_SIZE(result);
8147         int offset = 0 ;        
8148         
8149         while (size--) {
8150             
8151             pic14_emitcode("movx","a,@%s",rname);
8152             aopPut(AOP(result),"a",offset);
8153             
8154             offset++ ;
8155             
8156             if (size)
8157                 pic14_emitcode("inc","%s",rname);
8158         }
8159     }
8160
8161     /* now some housekeeping stuff */
8162     if (aop) {
8163         /* we had to allocate for this iCode */
8164         freeAsmop(NULL,aop,ic,TRUE);
8165     } else { 
8166         /* we did not allocate which means left
8167            already in a pointer register, then
8168            if size > 0 && this could be used again
8169            we have to point it back to where it 
8170            belongs */
8171         if (AOP_SIZE(result) > 1 &&
8172             !OP_SYMBOL(left)->remat &&
8173             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8174               ic->depth )) {
8175             int size = AOP_SIZE(result) - 1;
8176             while (size--)
8177                 pic14_emitcode("dec","%s",rname);
8178         }
8179     }
8180
8181     /* done */
8182     freeAsmop(result,NULL,ic,TRUE);
8183     
8184         
8185 }
8186
8187 /*-----------------------------------------------------------------*/
8188 /* genFarPointerGet - gget value from far space                    */
8189 /*-----------------------------------------------------------------*/
8190 static void genFarPointerGet (operand *left,
8191                               operand *result, iCode *ic)
8192 {
8193     int size, offset ;
8194     sym_link *retype = getSpec(operandType(result));
8195
8196     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8197
8198     aopOp(left,ic,FALSE);
8199
8200     /* if the operand is already in dptr 
8201     then we do nothing else we move the value to dptr */
8202     if (AOP_TYPE(left) != AOP_STR) {
8203         /* if this is remateriazable */
8204         if (AOP_TYPE(left) == AOP_IMMD)
8205             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8206         else { /* we need to get it byte by byte */
8207             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8208             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8209             if (options.model == MODEL_FLAT24)
8210             {
8211                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8212             }
8213         }
8214     }
8215     /* so dptr know contains the address */
8216     freeAsmop(left,NULL,ic,TRUE);
8217     aopOp(result,ic,FALSE);
8218
8219     /* if bit then unpack */
8220     if (IS_BITVAR(retype)) 
8221         genUnpackBits(result,"dptr",FPOINTER);
8222     else {
8223         size = AOP_SIZE(result);
8224         offset = 0 ;
8225
8226         while (size--) {
8227             pic14_emitcode("movx","a,@dptr");
8228             aopPut(AOP(result),"a",offset++);
8229             if (size)
8230                 pic14_emitcode("inc","dptr");
8231         }
8232     }
8233
8234     freeAsmop(result,NULL,ic,TRUE);
8235 }
8236 #if 0
8237 /*-----------------------------------------------------------------*/
8238 /* genCodePointerGet - get value from code space                  */
8239 /*-----------------------------------------------------------------*/
8240 static void genCodePointerGet (operand *left,
8241                                 operand *result, iCode *ic)
8242 {
8243     int size, offset ;
8244     sym_link *retype = getSpec(operandType(result));
8245
8246     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8247
8248     aopOp(left,ic,FALSE);
8249
8250     /* if the operand is already in dptr 
8251     then we do nothing else we move the value to dptr */
8252     if (AOP_TYPE(left) != AOP_STR) {
8253         /* if this is remateriazable */
8254         if (AOP_TYPE(left) == AOP_IMMD)
8255             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8256         else { /* we need to get it byte by byte */
8257             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8258             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8259             if (options.model == MODEL_FLAT24)
8260             {
8261                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8262             }
8263         }
8264     }
8265     /* so dptr know contains the address */
8266     freeAsmop(left,NULL,ic,TRUE);
8267     aopOp(result,ic,FALSE);
8268
8269     /* if bit then unpack */
8270     if (IS_BITVAR(retype)) 
8271         genUnpackBits(result,"dptr",CPOINTER);
8272     else {
8273         size = AOP_SIZE(result);
8274         offset = 0 ;
8275
8276         while (size--) {
8277             pic14_emitcode("clr","a");
8278             pic14_emitcode("movc","a,@a+dptr");
8279             aopPut(AOP(result),"a",offset++);
8280             if (size)
8281                 pic14_emitcode("inc","dptr");
8282         }
8283     }
8284
8285     freeAsmop(result,NULL,ic,TRUE);
8286 }
8287 #endif
8288 /*-----------------------------------------------------------------*/
8289 /* genGenPointerGet - gget value from generic pointer space        */
8290 /*-----------------------------------------------------------------*/
8291 static void genGenPointerGet (operand *left,
8292                               operand *result, iCode *ic)
8293 {
8294   int size, offset ;
8295   sym_link *retype = getSpec(operandType(result));
8296
8297   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8298   aopOp(left,ic,FALSE);
8299   aopOp(result,ic,FALSE);
8300
8301
8302   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8303
8304   /* if the operand is already in dptr 
8305      then we do nothing else we move the value to dptr */
8306   //  if (AOP_TYPE(left) != AOP_STR) {
8307     /* if this is remateriazable */
8308     if (AOP_TYPE(left) == AOP_IMMD) {
8309       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8310       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8311     }
8312     else { /* we need to get it byte by byte */
8313
8314       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8315       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8316
8317       size = AOP_SIZE(result);
8318       offset = 0 ;
8319
8320       while(size--) {
8321         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8322         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8323         if(size)
8324           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8325       }
8326       goto release;
8327     }
8328     //}
8329   /* so dptr know contains the address */
8330
8331   /* if bit then unpack */
8332   //if (IS_BITVAR(retype)) 
8333   //  genUnpackBits(result,"dptr",GPOINTER);
8334
8335  release:
8336   freeAsmop(left,NULL,ic,TRUE);
8337   freeAsmop(result,NULL,ic,TRUE);
8338
8339 }
8340
8341 /*-----------------------------------------------------------------*/
8342 /* genConstPointerGet - get value from const generic pointer space */
8343 /*-----------------------------------------------------------------*/
8344 static void genConstPointerGet (operand *left,
8345                                 operand *result, iCode *ic)
8346 {
8347   //sym_link *retype = getSpec(operandType(result));
8348   symbol *albl = newiTempLabel(NULL);
8349   symbol *blbl = newiTempLabel(NULL);
8350   PIC_OPCODE poc;
8351
8352   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8353   aopOp(left,ic,FALSE);
8354   aopOp(result,ic,FALSE);
8355
8356
8357   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8358
8359   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8360
8361   emitpcode(POC_CALL,popGetLabel(albl->key));
8362   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8363   emitpLabel(albl->key);
8364
8365   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8366     
8367   emitpcode(poc,popGet(AOP(left),1));
8368   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8369   emitpcode(poc,popGet(AOP(left),0));
8370   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8371
8372   emitpLabel(blbl->key);
8373
8374   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8375
8376
8377   freeAsmop(left,NULL,ic,TRUE);
8378   freeAsmop(result,NULL,ic,TRUE);
8379
8380 }
8381 /*-----------------------------------------------------------------*/
8382 /* genPointerGet - generate code for pointer get                   */
8383 /*-----------------------------------------------------------------*/
8384 static void genPointerGet (iCode *ic)
8385 {
8386     operand *left, *result ;
8387     sym_link *type, *etype;
8388     int p_type;
8389
8390     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8391
8392     left = IC_LEFT(ic);
8393     result = IC_RESULT(ic) ;
8394
8395     /* depending on the type of pointer we need to
8396     move it to the correct pointer register */
8397     type = operandType(left);
8398     etype = getSpec(type);
8399
8400     if (IS_PTR_CONST(type))
8401       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8402
8403     /* if left is of type of pointer then it is simple */
8404     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8405         p_type = DCL_TYPE(type);
8406     else {
8407         /* we have to go by the storage class */
8408         p_type = PTR_TYPE(SPEC_OCLS(etype));
8409
8410         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8411
8412         if (SPEC_OCLS(etype)->codesp ) {
8413           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8414           //p_type = CPOINTER ; 
8415         }
8416         else
8417             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8418               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8419                /*p_type = FPOINTER ;*/ 
8420             else
8421                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8422                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8423 /*                  p_type = PPOINTER; */
8424                 else
8425                     if (SPEC_OCLS(etype) == idata )
8426                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8427 /*                      p_type = IPOINTER; */
8428                     else
8429                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8430 /*                      p_type = POINTER ; */
8431     }
8432
8433     /* now that we have the pointer type we assign
8434     the pointer values */
8435     switch (p_type) {
8436
8437     case POINTER:       
8438     case IPOINTER:
8439         genNearPointerGet (left,result,ic);
8440         break;
8441
8442     case PPOINTER:
8443         genPagedPointerGet(left,result,ic);
8444         break;
8445
8446     case FPOINTER:
8447         genFarPointerGet (left,result,ic);
8448         break;
8449
8450     case CPOINTER:
8451         genConstPointerGet (left,result,ic);
8452         //pic14_emitcodePointerGet (left,result,ic);
8453         break;
8454
8455     case GPOINTER:
8456       if (IS_PTR_CONST(type))
8457         genConstPointerGet (left,result,ic);
8458       else
8459         genGenPointerGet (left,result,ic);
8460       break;
8461     }
8462
8463 }
8464
8465 /*-----------------------------------------------------------------*/
8466 /* genPackBits - generates code for packed bit storage             */
8467 /*-----------------------------------------------------------------*/
8468 static void genPackBits (sym_link    *etype ,
8469                          operand *right ,
8470                          char *rname, int p_type)
8471 {
8472     int shCount = 0 ;
8473     int offset = 0  ;
8474     int rLen = 0 ;
8475     int blen, bstr ;   
8476     char *l ;
8477
8478     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8479     blen = SPEC_BLEN(etype);
8480     bstr = SPEC_BSTR(etype);
8481
8482     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8483     MOVA(l);   
8484
8485     /* if the bit lenth is less than or    */
8486     /* it exactly fits a byte then         */
8487     if (SPEC_BLEN(etype) <= 8 )  {
8488         shCount = SPEC_BSTR(etype) ;
8489
8490         /* shift left acc */
8491         AccLsh(shCount);
8492
8493         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8494
8495
8496             switch (p_type) {
8497                 case POINTER:
8498                     pic14_emitcode ("mov","b,a");
8499                     pic14_emitcode("mov","a,@%s",rname);
8500                     break;
8501
8502                 case FPOINTER:
8503                     pic14_emitcode ("mov","b,a");
8504                     pic14_emitcode("movx","a,@dptr");
8505                     break;
8506
8507                 case GPOINTER:
8508                     pic14_emitcode ("push","b");
8509                     pic14_emitcode ("push","acc");
8510                     pic14_emitcode ("lcall","__gptrget");
8511                     pic14_emitcode ("pop","b");
8512                     break;
8513             }
8514
8515             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8516                       ((unsigned char)(0xFF << (blen+bstr)) | 
8517                        (unsigned char)(0xFF >> (8-bstr)) ) );
8518             pic14_emitcode ("orl","a,b");
8519             if (p_type == GPOINTER)
8520                 pic14_emitcode("pop","b");
8521         }
8522     }
8523
8524     switch (p_type) {
8525         case POINTER:
8526             pic14_emitcode("mov","@%s,a",rname);
8527             break;
8528
8529         case FPOINTER:
8530             pic14_emitcode("movx","@dptr,a");
8531             break;
8532
8533         case GPOINTER:
8534             DEBUGpic14_emitcode(";lcall","__gptrput");
8535             break;
8536     }
8537
8538     /* if we r done */
8539     if ( SPEC_BLEN(etype) <= 8 )
8540         return ;
8541
8542     pic14_emitcode("inc","%s",rname);
8543     rLen = SPEC_BLEN(etype) ;     
8544
8545     /* now generate for lengths greater than one byte */
8546     while (1) {
8547
8548         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8549
8550         rLen -= 8 ;
8551         if (rLen <= 0 )
8552             break ;
8553
8554         switch (p_type) {
8555             case POINTER:
8556                 if (*l == '@') {
8557                     MOVA(l);
8558                     pic14_emitcode("mov","@%s,a",rname);
8559                 } else
8560                     pic14_emitcode("mov","@%s,%s",rname,l);
8561                 break;
8562
8563             case FPOINTER:
8564                 MOVA(l);
8565                 pic14_emitcode("movx","@dptr,a");
8566                 break;
8567
8568             case GPOINTER:
8569                 MOVA(l);
8570                 DEBUGpic14_emitcode(";lcall","__gptrput");
8571                 break;  
8572         }   
8573         pic14_emitcode ("inc","%s",rname);
8574     }
8575
8576     MOVA(l);
8577
8578     /* last last was not complete */
8579     if (rLen)   {
8580         /* save the byte & read byte */
8581         switch (p_type) {
8582             case POINTER:
8583                 pic14_emitcode ("mov","b,a");
8584                 pic14_emitcode("mov","a,@%s",rname);
8585                 break;
8586
8587             case FPOINTER:
8588                 pic14_emitcode ("mov","b,a");
8589                 pic14_emitcode("movx","a,@dptr");
8590                 break;
8591
8592             case GPOINTER:
8593                 pic14_emitcode ("push","b");
8594                 pic14_emitcode ("push","acc");
8595                 pic14_emitcode ("lcall","__gptrget");
8596                 pic14_emitcode ("pop","b");
8597                 break;
8598         }
8599
8600         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8601         pic14_emitcode ("orl","a,b");
8602     }
8603
8604     if (p_type == GPOINTER)
8605         pic14_emitcode("pop","b");
8606
8607     switch (p_type) {
8608
8609     case POINTER:
8610         pic14_emitcode("mov","@%s,a",rname);
8611         break;
8612         
8613     case FPOINTER:
8614         pic14_emitcode("movx","@dptr,a");
8615         break;
8616         
8617     case GPOINTER:
8618         DEBUGpic14_emitcode(";lcall","__gptrput");
8619         break;                  
8620     }
8621 }
8622 /*-----------------------------------------------------------------*/
8623 /* genDataPointerSet - remat pointer to data space                 */
8624 /*-----------------------------------------------------------------*/
8625 static void genDataPointerSet(operand *right,
8626                               operand *result,
8627                               iCode *ic)
8628 {
8629     int size, offset = 0 ;
8630     char *l, buffer[256];
8631
8632     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8633     aopOp(right,ic,FALSE);
8634     
8635     l = aopGet(AOP(result),0,FALSE,TRUE);
8636     size = AOP_SIZE(right);
8637 /*
8638     if ( AOP_TYPE(result) == AOP_PCODE) {
8639       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8640               AOP(result)->aopu.pcop->name,
8641               PCOI(AOP(result)->aopu.pcop)->offset);
8642     }
8643 */
8644
8645     // tsd, was l+1 - the underline `_' prefix was being stripped
8646     while (size--) {
8647       if (offset) {
8648         sprintf(buffer,"(%s + %d)",l,offset);
8649         fprintf(stderr,"oops  %s\n",buffer);
8650       } else
8651         sprintf(buffer,"%s",l);
8652
8653         if (AOP_TYPE(right) == AOP_LIT) {
8654           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8655           lit = lit >> (8*offset);
8656           if(lit&0xff) {
8657             pic14_emitcode("movlw","%d",lit);
8658             pic14_emitcode("movwf","%s",buffer);
8659
8660             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8661             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8662             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8663
8664           } else {
8665             pic14_emitcode("clrf","%s",buffer);
8666             //emitpcode(POC_CLRF, popRegFromString(buffer));
8667             emitpcode(POC_CLRF, popGet(AOP(result),0));
8668           }
8669         }else {
8670           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8671           pic14_emitcode("movwf","%s",buffer);
8672
8673           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8674           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8675           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8676
8677         }
8678
8679         offset++;
8680     }
8681
8682     freeAsmop(right,NULL,ic,TRUE);
8683     freeAsmop(result,NULL,ic,TRUE);
8684 }
8685
8686 /*-----------------------------------------------------------------*/
8687 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8688 /*-----------------------------------------------------------------*/
8689 static void genNearPointerSet (operand *right,
8690                                operand *result, 
8691                                iCode *ic)
8692 {
8693   asmop *aop = NULL;
8694   char *l;
8695   sym_link *retype;
8696   sym_link *ptype = operandType(result);
8697
8698     
8699   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8700   retype= getSpec(operandType(right));
8701
8702   aopOp(result,ic,FALSE);
8703
8704     
8705   /* if the result is rematerializable &
8706      in data space & not a bit variable */
8707   //if (AOP_TYPE(result) == AOP_IMMD &&
8708   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8709       DCL_TYPE(ptype) == POINTER   &&
8710       !IS_BITVAR(retype)) {
8711     genDataPointerSet (right,result,ic);
8712     freeAsmop(result,NULL,ic,TRUE);
8713     return;
8714   }
8715
8716   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8717   aopOp(right,ic,FALSE);
8718   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8719
8720   /* if the value is already in a pointer register
8721      then don't need anything more */
8722   if (!AOP_INPREG(AOP(result))) {
8723     /* otherwise get a free pointer register */
8724     //aop = newAsmop(0);
8725     //preg = getFreePtr(ic,&aop,FALSE);
8726     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8727     //pic14_emitcode("mov","%s,%s",
8728     //         preg->name,
8729     //         aopGet(AOP(result),0,FALSE,TRUE));
8730     //rname = preg->name ;
8731     //pic14_emitcode("movwf","fsr");
8732     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8733     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8734     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8735     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8736     goto release;
8737
8738   }// else
8739   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8740
8741
8742   /* if bitfield then unpack the bits */
8743   if (IS_BITVAR(retype)) {
8744     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8745            "The programmer is obviously confused");
8746     //genPackBits (retype,right,rname,POINTER);
8747     exit(1);
8748   }
8749   else {
8750     /* we have can just get the values */
8751     int size = AOP_SIZE(right);
8752     int offset = 0 ;    
8753
8754     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8755     while (size--) {
8756       l = aopGet(AOP(right),offset,FALSE,TRUE);
8757       if (*l == '@' ) {
8758         //MOVA(l);
8759         //pic14_emitcode("mov","@%s,a",rname);
8760         pic14_emitcode("movf","indf,w ;1");
8761       } else {
8762
8763         if (AOP_TYPE(right) == AOP_LIT) {
8764           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8765           if(lit) {
8766             pic14_emitcode("movlw","%s",l);
8767             pic14_emitcode("movwf","indf ;2");
8768           } else 
8769             pic14_emitcode("clrf","indf");
8770         }else {
8771           pic14_emitcode("movf","%s,w",l);
8772           pic14_emitcode("movwf","indf ;2");
8773         }
8774         //pic14_emitcode("mov","@%s,%s",rname,l);
8775       }
8776       if (size)
8777         pic14_emitcode("incf","fsr,f ;3");
8778       //pic14_emitcode("inc","%s",rname);
8779       offset++;
8780     }
8781   }
8782
8783   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8784   /* now some housekeeping stuff */
8785   if (aop) {
8786     /* we had to allocate for this iCode */
8787     freeAsmop(NULL,aop,ic,TRUE);
8788   } else { 
8789     /* we did not allocate which means left
8790        already in a pointer register, then
8791        if size > 0 && this could be used again
8792        we have to point it back to where it 
8793        belongs */
8794     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8795     if (AOP_SIZE(right) > 1 &&
8796         !OP_SYMBOL(result)->remat &&
8797         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8798           ic->depth )) {
8799       int size = AOP_SIZE(right) - 1;
8800       while (size--)
8801         pic14_emitcode("decf","fsr,f");
8802       //pic14_emitcode("dec","%s",rname);
8803     }
8804   }
8805
8806   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8807   /* done */
8808  release:
8809   freeAsmop(right,NULL,ic,TRUE);
8810   freeAsmop(result,NULL,ic,TRUE);
8811 }
8812
8813 /*-----------------------------------------------------------------*/
8814 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8815 /*-----------------------------------------------------------------*/
8816 static void genPagedPointerSet (operand *right,
8817                                operand *result, 
8818                                iCode *ic)
8819 {
8820     asmop *aop = NULL;
8821     regs *preg = NULL ;
8822     char *rname , *l;
8823     sym_link *retype;
8824        
8825     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8826
8827     retype= getSpec(operandType(right));
8828     
8829     aopOp(result,ic,FALSE);
8830     
8831     /* if the value is already in a pointer register
8832        then don't need anything more */
8833     if (!AOP_INPREG(AOP(result))) {
8834         /* otherwise get a free pointer register */
8835         aop = newAsmop(0);
8836         preg = getFreePtr(ic,&aop,FALSE);
8837         pic14_emitcode("mov","%s,%s",
8838                 preg->name,
8839                 aopGet(AOP(result),0,FALSE,TRUE));
8840         rname = preg->name ;
8841     } else
8842         rname = aopGet(AOP(result),0,FALSE,FALSE);
8843     
8844     freeAsmop(result,NULL,ic,TRUE);
8845     aopOp (right,ic,FALSE);
8846
8847     /* if bitfield then unpack the bits */
8848     if (IS_BITVAR(retype)) 
8849         genPackBits (retype,right,rname,PPOINTER);
8850     else {
8851         /* we have can just get the values */
8852         int size = AOP_SIZE(right);
8853         int offset = 0 ;        
8854         
8855         while (size--) {
8856             l = aopGet(AOP(right),offset,FALSE,TRUE);
8857             
8858             MOVA(l);
8859             pic14_emitcode("movx","@%s,a",rname);
8860
8861             if (size)
8862                 pic14_emitcode("inc","%s",rname);
8863
8864             offset++;
8865         }
8866     }
8867     
8868     /* now some housekeeping stuff */
8869     if (aop) {
8870         /* we had to allocate for this iCode */
8871         freeAsmop(NULL,aop,ic,TRUE);
8872     } else { 
8873         /* we did not allocate which means left
8874            already in a pointer register, then
8875            if size > 0 && this could be used again
8876            we have to point it back to where it 
8877            belongs */
8878         if (AOP_SIZE(right) > 1 &&
8879             !OP_SYMBOL(result)->remat &&
8880             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8881               ic->depth )) {
8882             int size = AOP_SIZE(right) - 1;
8883             while (size--)
8884                 pic14_emitcode("dec","%s",rname);
8885         }
8886     }
8887
8888     /* done */
8889     freeAsmop(right,NULL,ic,TRUE);
8890     
8891         
8892 }
8893
8894 /*-----------------------------------------------------------------*/
8895 /* genFarPointerSet - set value from far space                     */
8896 /*-----------------------------------------------------------------*/
8897 static void genFarPointerSet (operand *right,
8898                               operand *result, iCode *ic)
8899 {
8900     int size, offset ;
8901     sym_link *retype = getSpec(operandType(right));
8902
8903     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8904     aopOp(result,ic,FALSE);
8905
8906     /* if the operand is already in dptr 
8907     then we do nothing else we move the value to dptr */
8908     if (AOP_TYPE(result) != AOP_STR) {
8909         /* if this is remateriazable */
8910         if (AOP_TYPE(result) == AOP_IMMD)
8911             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8912         else { /* we need to get it byte by byte */
8913             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8914             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8915             if (options.model == MODEL_FLAT24)
8916             {
8917                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8918             }
8919         }
8920     }
8921     /* so dptr know contains the address */
8922     freeAsmop(result,NULL,ic,TRUE);
8923     aopOp(right,ic,FALSE);
8924
8925     /* if bit then unpack */
8926     if (IS_BITVAR(retype)) 
8927         genPackBits(retype,right,"dptr",FPOINTER);
8928     else {
8929         size = AOP_SIZE(right);
8930         offset = 0 ;
8931
8932         while (size--) {
8933             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8934             MOVA(l);
8935             pic14_emitcode("movx","@dptr,a");
8936             if (size)
8937                 pic14_emitcode("inc","dptr");
8938         }
8939     }
8940
8941     freeAsmop(right,NULL,ic,TRUE);
8942 }
8943
8944 /*-----------------------------------------------------------------*/
8945 /* genGenPointerSet - set value from generic pointer space         */
8946 /*-----------------------------------------------------------------*/
8947 static void genGenPointerSet (operand *right,
8948                               operand *result, iCode *ic)
8949 {
8950   int size, offset ;
8951   sym_link *retype = getSpec(operandType(right));
8952
8953   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8954
8955   aopOp(result,ic,FALSE);
8956   aopOp(right,ic,FALSE);
8957   size = AOP_SIZE(right);
8958
8959   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8960
8961   /* if the operand is already in dptr 
8962      then we do nothing else we move the value to dptr */
8963   if (AOP_TYPE(result) != AOP_STR) {
8964     /* if this is remateriazable */
8965     if (AOP_TYPE(result) == AOP_IMMD) {
8966       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8967       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8968     }
8969     else { /* we need to get it byte by byte */
8970       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8971       size = AOP_SIZE(right);
8972       offset = 0 ;
8973
8974       /* hack hack! see if this the FSR. If so don't load W */
8975       if(AOP_TYPE(right) != AOP_ACC) {
8976
8977         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8978         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8979
8980         //if(size==2)
8981         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8982         //if(size==4) {
8983         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8984         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8985         //}
8986
8987         while(size--) {
8988           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8989           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8990           
8991           if(size)
8992             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8993         }
8994
8995
8996         goto release;
8997       } 
8998
8999       if(aopIdx(AOP(result),0) != 4) {
9000
9001         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9002         goto release;
9003       }
9004
9005       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9006       goto release;
9007
9008     }
9009   }
9010   /* so dptr know contains the address */
9011
9012
9013   /* if bit then unpack */
9014   if (IS_BITVAR(retype)) 
9015     genPackBits(retype,right,"dptr",GPOINTER);
9016   else {
9017     size = AOP_SIZE(right);
9018     offset = 0 ;
9019
9020   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9021
9022     while (size--) {
9023
9024       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9025       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9026
9027       if (AOP_TYPE(right) == AOP_LIT) 
9028         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9029       else
9030         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9031
9032       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9033
9034       offset++;
9035     }
9036   }
9037
9038  release:
9039   freeAsmop(right,NULL,ic,TRUE);
9040   freeAsmop(result,NULL,ic,TRUE);
9041 }
9042
9043 /*-----------------------------------------------------------------*/
9044 /* genPointerSet - stores the value into a pointer location        */
9045 /*-----------------------------------------------------------------*/
9046 static void genPointerSet (iCode *ic)
9047 {    
9048     operand *right, *result ;
9049     sym_link *type, *etype;
9050     int p_type;
9051
9052     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9053
9054     right = IC_RIGHT(ic);
9055     result = IC_RESULT(ic) ;
9056
9057     /* depending on the type of pointer we need to
9058     move it to the correct pointer register */
9059     type = operandType(result);
9060     etype = getSpec(type);
9061     /* if left is of type of pointer then it is simple */
9062     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9063         p_type = DCL_TYPE(type);
9064     }
9065     else {
9066         /* we have to go by the storage class */
9067         p_type = PTR_TYPE(SPEC_OCLS(etype));
9068
9069 /*      if (SPEC_OCLS(etype)->codesp ) { */
9070 /*          p_type = CPOINTER ;  */
9071 /*      } */
9072 /*      else */
9073 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9074 /*              p_type = FPOINTER ; */
9075 /*          else */
9076 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9077 /*                  p_type = PPOINTER ; */
9078 /*              else */
9079 /*                  if (SPEC_OCLS(etype) == idata ) */
9080 /*                      p_type = IPOINTER ; */
9081 /*                  else */
9082 /*                      p_type = POINTER ; */
9083     }
9084
9085     /* now that we have the pointer type we assign
9086     the pointer values */
9087     switch (p_type) {
9088
9089     case POINTER:
9090     case IPOINTER:
9091         genNearPointerSet (right,result,ic);
9092         break;
9093
9094     case PPOINTER:
9095         genPagedPointerSet (right,result,ic);
9096         break;
9097
9098     case FPOINTER:
9099         genFarPointerSet (right,result,ic);
9100         break;
9101
9102     case GPOINTER:
9103         genGenPointerSet (right,result,ic);
9104         break;
9105
9106     default:
9107       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9108               "genPointerSet: illegal pointer type");
9109     }
9110 }
9111
9112 /*-----------------------------------------------------------------*/
9113 /* genIfx - generate code for Ifx statement                        */
9114 /*-----------------------------------------------------------------*/
9115 static void genIfx (iCode *ic, iCode *popIc)
9116 {
9117   operand *cond = IC_COND(ic);
9118   int isbit =0;
9119
9120   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9121
9122   aopOp(cond,ic,FALSE);
9123
9124   /* get the value into acc */
9125   if (AOP_TYPE(cond) != AOP_CRY)
9126     pic14_toBoolean(cond);
9127   else
9128     isbit = 1;
9129   /* the result is now in the accumulator */
9130   freeAsmop(cond,NULL,ic,TRUE);
9131
9132   /* if there was something to be popped then do it */
9133   if (popIc)
9134     genIpop(popIc);
9135
9136   /* if the condition is  a bit variable */
9137   if (isbit && IS_ITEMP(cond) && 
9138       SPIL_LOC(cond)) {
9139     genIfxJump(ic,SPIL_LOC(cond)->rname);
9140     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9141   }
9142   else {
9143     if (isbit && !IS_ITEMP(cond))
9144       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9145     else
9146       genIfxJump(ic,"a");
9147   }
9148   ic->generated = 1;
9149
9150 }
9151
9152 /*-----------------------------------------------------------------*/
9153 /* genAddrOf - generates code for address of                       */
9154 /*-----------------------------------------------------------------*/
9155 static void genAddrOf (iCode *ic)
9156 {
9157   operand *right, *result, *left;
9158   int size, offset ;
9159
9160   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9161
9162
9163   //aopOp(IC_RESULT(ic),ic,FALSE);
9164
9165   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9166   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9167   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9168
9169   DEBUGpic14_AopType(__LINE__,left,right,result);
9170
9171   size = AOP_SIZE(IC_RESULT(ic));
9172   offset = 0;
9173
9174   while (size--) {
9175     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9176     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9177     offset++;
9178   }
9179
9180   freeAsmop(left,NULL,ic,FALSE);
9181   freeAsmop(result,NULL,ic,TRUE);
9182
9183 }
9184
9185 #if 0
9186 /*-----------------------------------------------------------------*/
9187 /* genFarFarAssign - assignment when both are in far space         */
9188 /*-----------------------------------------------------------------*/
9189 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9190 {
9191     int size = AOP_SIZE(right);
9192     int offset = 0;
9193     char *l ;
9194     /* first push the right side on to the stack */
9195     while (size--) {
9196         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9197         MOVA(l);
9198         pic14_emitcode ("push","acc");
9199     }
9200     
9201     freeAsmop(right,NULL,ic,FALSE);
9202     /* now assign DPTR to result */
9203     aopOp(result,ic,FALSE);
9204     size = AOP_SIZE(result);
9205     while (size--) {
9206         pic14_emitcode ("pop","acc");
9207         aopPut(AOP(result),"a",--offset);
9208     }
9209     freeAsmop(result,NULL,ic,FALSE);
9210         
9211 }
9212 #endif
9213
9214 /*-----------------------------------------------------------------*/
9215 /* genAssign - generate code for assignment                        */
9216 /*-----------------------------------------------------------------*/
9217 static void genAssign (iCode *ic)
9218 {
9219   operand *result, *right;
9220   int size, offset,know_W;
9221   unsigned long lit = 0L;
9222
9223   result = IC_RESULT(ic);
9224   right  = IC_RIGHT(ic) ;
9225
9226   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9227
9228   /* if they are the same */
9229   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9230     return ;
9231
9232   aopOp(right,ic,FALSE);
9233   aopOp(result,ic,TRUE);
9234
9235   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9236
9237   /* if they are the same registers */
9238   if (pic14_sameRegs(AOP(right),AOP(result)))
9239     goto release;
9240
9241   /* if the result is a bit */
9242   if (AOP_TYPE(result) == AOP_CRY) {
9243
9244     /* if the right size is a literal then
9245        we know what the value is */
9246     if (AOP_TYPE(right) == AOP_LIT) {
9247           
9248       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9249                   popGet(AOP(result),0));
9250
9251       if (((int) operandLitValue(right))) 
9252         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9253                        AOP(result)->aopu.aop_dir,
9254                        AOP(result)->aopu.aop_dir);
9255       else
9256         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9257                        AOP(result)->aopu.aop_dir,
9258                        AOP(result)->aopu.aop_dir);
9259       goto release;
9260     }
9261
9262     /* the right is also a bit variable */
9263     if (AOP_TYPE(right) == AOP_CRY) {
9264       emitpcode(POC_BCF,    popGet(AOP(result),0));
9265       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9266       emitpcode(POC_BSF,    popGet(AOP(result),0));
9267
9268       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9269                      AOP(result)->aopu.aop_dir,
9270                      AOP(result)->aopu.aop_dir);
9271       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9272                      AOP(right)->aopu.aop_dir,
9273                      AOP(right)->aopu.aop_dir);
9274       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9275                      AOP(result)->aopu.aop_dir,
9276                      AOP(result)->aopu.aop_dir);
9277       goto release ;
9278     }
9279
9280     /* we need to or */
9281     emitpcode(POC_BCF,    popGet(AOP(result),0));
9282     pic14_toBoolean(right);
9283     emitSKPZ;
9284     emitpcode(POC_BSF,    popGet(AOP(result),0));
9285     //aopPut(AOP(result),"a",0);
9286     goto release ;
9287   }
9288
9289   /* bit variables done */
9290   /* general case */
9291   size = AOP_SIZE(result);
9292   offset = 0 ;
9293   if(AOP_TYPE(right) == AOP_LIT)
9294     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9295
9296   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9297   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9298     if(aopIdx(AOP(result),0) == 4) {
9299   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9300       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9301       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9302       goto release;
9303     } else
9304       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9305   }
9306
9307   know_W=-1;
9308   while (size--) {
9309   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9310     if(AOP_TYPE(right) == AOP_LIT) {
9311       if(lit&0xff) {
9312         if(know_W != (lit&0xff))
9313           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9314         know_W = lit&0xff;
9315         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9316       } else
9317         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9318
9319       lit >>= 8;
9320
9321     } else if (AOP_TYPE(right) == AOP_CRY) {
9322       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9323       if(offset == 0) {
9324         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9325         emitpcode(POC_INCF, popGet(AOP(result),0));
9326       }
9327     } else {
9328   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9329       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9330       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9331     }
9332             
9333     offset++;
9334   }
9335
9336     
9337  release:
9338   freeAsmop (right,NULL,ic,FALSE);
9339   freeAsmop (result,NULL,ic,TRUE);
9340 }   
9341
9342 /*-----------------------------------------------------------------*/
9343 /* genJumpTab - genrates code for jump table                       */
9344 /*-----------------------------------------------------------------*/
9345 static void genJumpTab (iCode *ic)
9346 {
9347     symbol *jtab;
9348     char *l;
9349
9350     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9351
9352     aopOp(IC_JTCOND(ic),ic,FALSE);
9353     /* get the condition into accumulator */
9354     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9355     MOVA(l);
9356     /* multiply by three */
9357     pic14_emitcode("add","a,acc");
9358     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9359
9360     jtab = newiTempLabel(NULL);
9361     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9362     pic14_emitcode("jmp","@a+dptr");
9363     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9364
9365     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9366     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9367     emitSKPNC;
9368     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9369     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9370     emitpLabel(jtab->key);
9371
9372     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9373
9374     /* now generate the jump labels */
9375     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9376          jtab = setNextItem(IC_JTLABELS(ic))) {
9377         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9378         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9379         
9380     }
9381
9382 }
9383
9384 /*-----------------------------------------------------------------*/
9385 /* genMixedOperation - gen code for operators between mixed types  */
9386 /*-----------------------------------------------------------------*/
9387 /*
9388   TSD - Written for the PIC port - but this unfortunately is buggy.
9389   This routine is good in that it is able to efficiently promote 
9390   types to different (larger) sizes. Unfortunately, the temporary
9391   variables that are optimized out by this routine are sometimes
9392   used in other places. So until I know how to really parse the 
9393   iCode tree, I'm going to not be using this routine :(.
9394 */
9395 static int genMixedOperation (iCode *ic)
9396 {
9397 #if 0
9398   operand *result = IC_RESULT(ic);
9399   sym_link *ctype = operandType(IC_LEFT(ic));
9400   operand *right = IC_RIGHT(ic);
9401   int ret = 0;
9402   int big,small;
9403   int offset;
9404
9405   iCode *nextic;
9406   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9407
9408   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9409
9410   nextic = ic->next;
9411   if(!nextic)
9412     return 0;
9413
9414   nextright = IC_RIGHT(nextic);
9415   nextleft  = IC_LEFT(nextic);
9416   nextresult = IC_RESULT(nextic);
9417
9418   aopOp(right,ic,FALSE);
9419   aopOp(result,ic,FALSE);
9420   aopOp(nextright,  nextic, FALSE);
9421   aopOp(nextleft,   nextic, FALSE);
9422   aopOp(nextresult, nextic, FALSE);
9423
9424   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9425
9426     operand *t = right;
9427     right = nextright;
9428     nextright = t; 
9429
9430     pic14_emitcode(";remove right +","");
9431
9432   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9433 /*
9434     operand *t = right;
9435     right = nextleft;
9436     nextleft = t; 
9437 */
9438     pic14_emitcode(";remove left +","");
9439   } else
9440     return 0;
9441
9442   big = AOP_SIZE(nextleft);
9443   small = AOP_SIZE(nextright);
9444
9445   switch(nextic->op) {
9446
9447   case '+':
9448     pic14_emitcode(";optimize a +","");
9449     /* if unsigned or not an integral type */
9450     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9451       pic14_emitcode(";add a bit to something","");
9452     } else {
9453
9454       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9455
9456       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9457         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9458         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9459       } else
9460         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9461
9462       offset = 0;
9463       while(--big) {
9464
9465         offset++;
9466
9467         if(--small) {
9468           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9469             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9470             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9471           }
9472
9473           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9474           emitSKPNC;
9475           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9476                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9477                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9478           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9479           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9480
9481         } else {
9482           pic14_emitcode("rlf","known_zero,w");
9483
9484           /*
9485             if right is signed
9486               btfsc  right,7
9487                addlw ff
9488           */
9489           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9490             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9492           } else {
9493             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9494           }
9495         }
9496       }
9497       ret = 1;
9498     }
9499   }
9500   ret = 1;
9501
9502 release:
9503   freeAsmop(right,NULL,ic,TRUE);
9504   freeAsmop(result,NULL,ic,TRUE);
9505   freeAsmop(nextright,NULL,ic,TRUE);
9506   freeAsmop(nextleft,NULL,ic,TRUE);
9507   if(ret)
9508     nextic->generated = 1;
9509
9510   return ret;
9511 #else
9512   return 0;
9513 #endif
9514 }
9515 /*-----------------------------------------------------------------*/
9516 /* genCast - gen code for casting                                  */
9517 /*-----------------------------------------------------------------*/
9518 static void genCast (iCode *ic)
9519 {
9520     operand *result = IC_RESULT(ic);
9521     sym_link *ctype = operandType(IC_LEFT(ic));
9522     sym_link *rtype = operandType(IC_RIGHT(ic));
9523     operand *right = IC_RIGHT(ic);
9524     int size, offset ;
9525
9526     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9527     /* if they are equivalent then do nothing */
9528     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9529         return ;
9530
9531     aopOp(right,ic,FALSE) ;
9532     aopOp(result,ic,FALSE);
9533
9534     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9535
9536     /* if the result is a bit */
9537     if (AOP_TYPE(result) == AOP_CRY) {
9538         /* if the right size is a literal then
9539         we know what the value is */
9540       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9541         if (AOP_TYPE(right) == AOP_LIT) {
9542
9543           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9544                       popGet(AOP(result),0));
9545
9546             if (((int) operandLitValue(right))) 
9547               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9548                        AOP(result)->aopu.aop_dir,
9549                        AOP(result)->aopu.aop_dir);
9550             else
9551               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9552                        AOP(result)->aopu.aop_dir,
9553                        AOP(result)->aopu.aop_dir);
9554
9555             goto release;
9556         }
9557
9558         /* the right is also a bit variable */
9559         if (AOP_TYPE(right) == AOP_CRY) {
9560
9561           emitCLRC;
9562           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9563
9564           pic14_emitcode("clrc","");
9565           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9566                    AOP(right)->aopu.aop_dir,
9567                    AOP(right)->aopu.aop_dir);
9568             aopPut(AOP(result),"c",0);
9569             goto release ;
9570         }
9571
9572         /* we need to or */
9573         if (AOP_TYPE(right) == AOP_REG) {
9574           emitpcode(POC_BCF,    popGet(AOP(result),0));
9575           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9576           emitpcode(POC_BSF,    popGet(AOP(result),0));
9577         }
9578         pic14_toBoolean(right);
9579         aopPut(AOP(result),"a",0);
9580         goto release ;
9581     }
9582
9583     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9584       int offset = 1;
9585       size = AOP_SIZE(result);
9586
9587       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9588
9589       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9590       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9591       emitpcode(POC_INCF,   popGet(AOP(result),0));
9592
9593       while (size--)
9594         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9595
9596       goto release;
9597     }
9598
9599     /* if they are the same size : or less */
9600     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9601
9602         /* if they are in the same place */
9603       if (pic14_sameRegs(AOP(right),AOP(result)))
9604         goto release;
9605
9606       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9607       if (IS_PTR_CONST(rtype))
9608         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9609       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9610         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9611
9612       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9613         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9614         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9615         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9616         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9617         if(AOP_SIZE(result) <2)
9618           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9619
9620       } else {
9621
9622         /* if they in different places then copy */
9623         size = AOP_SIZE(result);
9624         offset = 0 ;
9625         while (size--) {
9626           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9627           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9628
9629           //aopPut(AOP(result),
9630           // aopGet(AOP(right),offset,FALSE,FALSE),
9631           // offset);
9632
9633           offset++;
9634         }
9635       }
9636       goto release;
9637     }
9638
9639
9640     /* if the result is of type pointer */
9641     if (IS_PTR(ctype)) {
9642
9643         int p_type;
9644         sym_link *type = operandType(right);
9645         sym_link *etype = getSpec(type);
9646       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9647
9648         /* pointer to generic pointer */
9649         if (IS_GENPTR(ctype)) {
9650             char *l = zero;
9651             
9652             if (IS_PTR(type)) 
9653                 p_type = DCL_TYPE(type);
9654             else {
9655                 /* we have to go by the storage class */
9656                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9657
9658 /*              if (SPEC_OCLS(etype)->codesp )  */
9659 /*                  p_type = CPOINTER ;  */
9660 /*              else */
9661 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9662 /*                      p_type = FPOINTER ; */
9663 /*                  else */
9664 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9665 /*                          p_type = PPOINTER; */
9666 /*                      else */
9667 /*                          if (SPEC_OCLS(etype) == idata ) */
9668 /*                              p_type = IPOINTER ; */
9669 /*                          else */
9670 /*                              p_type = POINTER ; */
9671             }
9672                 
9673             /* the first two bytes are known */
9674       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9675             size = GPTRSIZE - 1; 
9676             offset = 0 ;
9677             while (size--) {
9678               if(offset < AOP_SIZE(right)) {
9679       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9680                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9681                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9682                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9683                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9684                 } else { 
9685                   aopPut(AOP(result),
9686                          aopGet(AOP(right),offset,FALSE,FALSE),
9687                          offset);
9688                 }
9689               } else 
9690                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9691               offset++;
9692             }
9693             /* the last byte depending on type */
9694             switch (p_type) {
9695             case IPOINTER:
9696             case POINTER:
9697                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9698                 break;
9699             case FPOINTER:
9700               pic14_emitcode(";BUG!? ","%d",__LINE__);
9701                 l = one;
9702                 break;
9703             case CPOINTER:
9704               pic14_emitcode(";BUG!? ","%d",__LINE__);
9705                 l = "#0x02";
9706                 break;                          
9707             case PPOINTER:
9708               pic14_emitcode(";BUG!? ","%d",__LINE__);
9709                 l = "#0x03";
9710                 break;
9711                 
9712             default:
9713                 /* this should never happen */
9714                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9715                        "got unknown pointer type");
9716                 exit(1);
9717             }
9718             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9719             goto release ;
9720         }
9721         
9722         /* just copy the pointers */
9723         size = AOP_SIZE(result);
9724         offset = 0 ;
9725         while (size--) {
9726             aopPut(AOP(result),
9727                    aopGet(AOP(right),offset,FALSE,FALSE),
9728                    offset);
9729             offset++;
9730         }
9731         goto release ;
9732     }
9733     
9734
9735
9736     /* so we now know that the size of destination is greater
9737     than the size of the source.
9738     Now, if the next iCode is an operator then we might be
9739     able to optimize the operation without performing a cast.
9740     */
9741     if(genMixedOperation(ic))
9742       goto release;
9743
9744     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9745     
9746     /* we move to result for the size of source */
9747     size = AOP_SIZE(right);
9748     offset = 0 ;
9749     while (size--) {
9750       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9751       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9752       offset++;
9753     }
9754
9755     /* now depending on the sign of the destination */
9756     size = AOP_SIZE(result) - AOP_SIZE(right);
9757     /* if unsigned or not an integral type */
9758     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9759       while (size--)
9760         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9761     } else {
9762       /* we need to extend the sign :{ */
9763
9764       if(size == 1) {
9765         /* Save one instruction of casting char to int */
9766         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9767         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9768         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9769       } else {
9770         emitpcodeNULLop(POC_CLRW);
9771
9772         if(offset)
9773           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9774         else
9775           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9776         
9777         emitpcode(POC_MOVLW,   popGetLit(0xff));
9778
9779         while (size--)
9780           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9781       }
9782     }
9783
9784 release:
9785     freeAsmop(right,NULL,ic,TRUE);
9786     freeAsmop(result,NULL,ic,TRUE);
9787
9788 }
9789
9790 /*-----------------------------------------------------------------*/
9791 /* genDjnz - generate decrement & jump if not zero instrucion      */
9792 /*-----------------------------------------------------------------*/
9793 static int genDjnz (iCode *ic, iCode *ifx)
9794 {
9795     symbol *lbl, *lbl1;
9796     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9797
9798     if (!ifx)
9799         return 0;
9800     
9801     /* if the if condition has a false label
9802        then we cannot save */
9803     if (IC_FALSE(ifx))
9804         return 0;
9805
9806     /* if the minus is not of the form 
9807        a = a - 1 */
9808     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9809         !IS_OP_LITERAL(IC_RIGHT(ic)))
9810         return 0;
9811
9812     if (operandLitValue(IC_RIGHT(ic)) != 1)
9813         return 0;
9814
9815     /* if the size of this greater than one then no
9816        saving */
9817     if (getSize(operandType(IC_RESULT(ic))) > 1)
9818         return 0;
9819
9820     /* otherwise we can save BIG */
9821     lbl = newiTempLabel(NULL);
9822     lbl1= newiTempLabel(NULL);
9823
9824     aopOp(IC_RESULT(ic),ic,FALSE);
9825     
9826     if (IS_AOP_PREG(IC_RESULT(ic))) {
9827         pic14_emitcode("dec","%s",
9828                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9829         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9830         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9831     } else {    
9832
9833
9834       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9835       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9836
9837       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9838       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9839
9840     }
9841 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9842 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9843 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9844 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9845
9846     
9847     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9848     ifx->generated = 1;
9849     return 1;
9850 }
9851
9852 /*-----------------------------------------------------------------*/
9853 /* genReceive - generate code for a receive iCode                  */
9854 /*-----------------------------------------------------------------*/
9855 static void genReceive (iCode *ic)
9856 {    
9857   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9858
9859   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9860       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9861         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9862
9863     int size = getSize(operandType(IC_RESULT(ic)));
9864     int offset =  fReturnSizePic - size;
9865     while (size--) {
9866       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9867                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9868       offset++;
9869     }
9870     aopOp(IC_RESULT(ic),ic,FALSE);  
9871     size = AOP_SIZE(IC_RESULT(ic));
9872     offset = 0;
9873     while (size--) {
9874       pic14_emitcode ("pop","acc");
9875       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9876     }
9877         
9878   } else {
9879     _G.accInUse++;
9880     aopOp(IC_RESULT(ic),ic,FALSE);  
9881     _G.accInUse--;
9882     assignResultValue(IC_RESULT(ic));   
9883   }
9884
9885   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9886 }
9887
9888 /*-----------------------------------------------------------------*/
9889 /* genpic14Code - generate code for pic14 based controllers        */
9890 /*-----------------------------------------------------------------*/
9891 /*
9892  * At this point, ralloc.c has gone through the iCode and attempted
9893  * to optimize in a way suitable for a PIC. Now we've got to generate
9894  * PIC instructions that correspond to the iCode.
9895  *
9896  * Once the instructions are generated, we'll pass through both the
9897  * peep hole optimizer and the pCode optimizer.
9898  *-----------------------------------------------------------------*/
9899
9900 void genpic14Code (iCode *lic)
9901 {
9902     iCode *ic;
9903     int cln = 0;
9904
9905     lineHead = lineCurr = NULL;
9906
9907     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9908     addpBlock(pb);
9909
9910     /* if debug information required */
9911     if (options.debug && currFunc) { 
9912       if (currFunc) {
9913         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9914         _G.debugLine = 1;
9915         if (IS_STATIC(currFunc->etype)) {
9916           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9917           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9918         } else {
9919           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9920           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9921         }
9922         _G.debugLine = 0;
9923       }
9924     }
9925
9926
9927     for (ic = lic ; ic ; ic = ic->next ) {
9928
9929       DEBUGpic14_emitcode(";ic","");
9930         if ( cln != ic->lineno ) {
9931             if ( options.debug ) {
9932                 _G.debugLine = 1;
9933                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9934                          FileBaseName(ic->filename),ic->lineno,
9935                          ic->level,ic->block);
9936                 _G.debugLine = 0;
9937             }
9938             /*
9939               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9940               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9941               printCLine(ic->filename, ic->lineno));
9942             */
9943             addpCode2pBlock(pb,
9944                             newpCodeCSource(ic->lineno, 
9945                                             ic->filename, 
9946                                             printCLine(ic->filename, ic->lineno)));
9947
9948             cln = ic->lineno ;
9949         }
9950         /* if the result is marked as
9951            spilt and rematerializable or code for
9952            this has already been generated then
9953            do nothing */
9954         if (resultRemat(ic) || ic->generated ) 
9955             continue ;
9956         
9957         /* depending on the operation */
9958         switch (ic->op) {
9959         case '!' :
9960             genNot(ic);
9961             break;
9962             
9963         case '~' :
9964             genCpl(ic);
9965             break;
9966             
9967         case UNARYMINUS:
9968             genUminus (ic);
9969             break;
9970             
9971         case IPUSH:
9972             genIpush (ic);
9973             break;
9974             
9975         case IPOP:
9976             /* IPOP happens only when trying to restore a 
9977                spilt live range, if there is an ifx statement
9978                following this pop then the if statement might
9979                be using some of the registers being popped which
9980                would destory the contents of the register so
9981                we need to check for this condition and handle it */
9982             if (ic->next            && 
9983                 ic->next->op == IFX &&
9984                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9985                 genIfx (ic->next,ic);
9986             else
9987                 genIpop (ic);
9988             break; 
9989             
9990         case CALL:
9991             genCall (ic);
9992             break;
9993             
9994         case PCALL:
9995             genPcall (ic);
9996             break;
9997             
9998         case FUNCTION:
9999             genFunction (ic);
10000             break;
10001             
10002         case ENDFUNCTION:
10003             genEndFunction (ic);
10004             break;
10005             
10006         case RETURN:
10007             genRet (ic);
10008             break;
10009             
10010         case LABEL:
10011             genLabel (ic);
10012             break;
10013             
10014         case GOTO:
10015             genGoto (ic);
10016             break;
10017             
10018         case '+' :
10019             genPlus (ic) ;
10020             break;
10021             
10022         case '-' :
10023             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10024                 genMinus (ic);
10025             break;
10026             
10027         case '*' :
10028             genMult (ic);
10029             break;
10030             
10031         case '/' :
10032             genDiv (ic) ;
10033             break;
10034             
10035         case '%' :
10036             genMod (ic);
10037             break;
10038             
10039         case '>' :
10040             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10041             break;
10042             
10043         case '<' :
10044             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10045             break;
10046             
10047         case LE_OP:
10048         case GE_OP:
10049         case NE_OP:
10050             
10051             /* note these two are xlated by algebraic equivalence
10052                during parsing SDCC.y */
10053             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10054                    "got '>=' or '<=' shouldn't have come here");
10055             break;      
10056             
10057         case EQ_OP:
10058             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10059             break;          
10060             
10061         case AND_OP:
10062             genAndOp (ic);
10063             break;
10064             
10065         case OR_OP:
10066             genOrOp (ic);
10067             break;
10068             
10069         case '^' :
10070             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10071             break;
10072             
10073         case '|' :
10074                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10075             break;
10076             
10077         case BITWISEAND:
10078             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10079             break;
10080             
10081         case INLINEASM:
10082             genInline (ic);
10083             break;
10084             
10085         case RRC:
10086             genRRC (ic);
10087             break;
10088             
10089         case RLC:
10090             genRLC (ic);
10091             break;
10092             
10093         case GETHBIT:
10094             genGetHbit (ic);
10095             break;
10096             
10097         case LEFT_OP:
10098             genLeftShift (ic);
10099             break;
10100             
10101         case RIGHT_OP:
10102             genRightShift (ic);
10103             break;
10104             
10105         case GET_VALUE_AT_ADDRESS:
10106             genPointerGet(ic);
10107             break;
10108             
10109         case '=' :
10110             if (POINTER_SET(ic))
10111                 genPointerSet(ic);
10112             else
10113                 genAssign(ic);
10114             break;
10115             
10116         case IFX:
10117             genIfx (ic,NULL);
10118             break;
10119             
10120         case ADDRESS_OF:
10121             genAddrOf (ic);
10122             break;
10123             
10124         case JUMPTABLE:
10125             genJumpTab (ic);
10126             break;
10127             
10128         case CAST:
10129             genCast (ic);
10130             break;
10131             
10132         case RECEIVE:
10133             genReceive(ic);
10134             break;
10135             
10136         case SEND:
10137             addSet(&_G.sendSet,ic);
10138             break;
10139
10140         default :
10141             ic = ic;
10142         }
10143     }
10144     
10145
10146     /* now we are ready to call the 
10147        peep hole optimizer */
10148     if (!options.nopeep) {
10149       peepHole (&lineHead);
10150     }
10151     /* now do the actual printing */
10152     printLine (lineHead,codeOutFile);
10153
10154 #ifdef PCODE_DEBUG
10155     DFPRINTF((stderr,"printing pBlock\n\n"));
10156     printpBlock(stdout,pb);
10157 #endif
10158
10159     return;
10160 }