]> git.gag.com Git - fw/sdcc/blob - src/pic/gen.c
inline assembly was generated as plain text, now it is assembled into pCodes.
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
41 #else
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
51 #endif
52 #endif
53 #endif
54 #endif
55
56 #include "common.h"
57 #include "SDCCpeeph.h"
58 #include "ralloc.h"
59 #include "pcode.h"
60 #include "gen.h"
61
62
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
66 pCode *AssembleLine(char *line);
67 extern void printpBlock(FILE *of, pBlock *pb);
68
69 static int labelOffset=0;
70 extern int debug_verbose;
71 static int optimized_for_speed = 0;
72
73 /* max_key keeps track of the largest label number used in 
74    a function. This is then used to adjust the label offset
75    for the next function.
76 */
77 static int max_key=0;
78 static int GpsuedoStkPtr=0;
79
80 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
81 unsigned int pic14aopLiteral (value *val, int offset);
82 const char *AopType(short type);
83 static iCode *ifxForOp ( operand *op, iCode *ic );
84
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
86
87 /* this is the down and dirty file with all kinds of 
88    kludgy & hacky stuff. This is what it is all about
89    CODE GENERATION for a specific MCU . some of the
90    routines may be reusable, will have to see */
91
92 static char *zero = "#0x00";
93 static char *one  = "#0x01";
94 static char *spname = "sp";
95
96 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
97 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
98 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
99 static char **fReturn = fReturnpic14;
100
101 static char *accUse[] = {"a","b"};
102
103 //static short rbank = -1;
104
105 static struct {
106     short r0Pushed;
107     short r1Pushed;
108     short accInUse;
109     short inLine;
110     short debugLine;
111     short nRegsSaved;
112     set *sendSet;
113 } _G;
114
115 /* Resolved ifx structure. This structure stores information
116    about an iCode ifx that makes it easier to generate code.
117 */
118 typedef struct resolvedIfx {
119   symbol *lbl;     /* pointer to a label */
120   int condition;   /* true or false ifx */
121   int generated;   /* set true when the code associated with the ifx
122                     * is generated */
123 } resolvedIfx;
124
125 extern int pic14_ptrRegReq ;
126 extern int pic14_nRegs;
127 extern FILE *codeOutFile;
128 static void saverbank (int, iCode *,bool);
129
130 static lineNode *lineHead = NULL;
131 static lineNode *lineCurr = NULL;
132
133 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
134 0xE0, 0xC0, 0x80, 0x00};
135 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
136 0x07, 0x03, 0x01, 0x00};
137
138 static  pBlock *pb;
139
140 /*-----------------------------------------------------------------*/
141 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
142 /*                 exponent of 2 is returned, otherwise -1 is      */
143 /*                 returned.                                       */
144 /* note that this is similar to the function `powof2' in SDCCsymt  */
145 /* if(n == 2^y)                                                    */
146 /*   return y;                                                     */
147 /* return -1;                                                      */
148 /*-----------------------------------------------------------------*/
149 static int my_powof2 (unsigned long num)
150 {
151   if(num) {
152     if( (num & (num-1)) == 0) {
153       int nshifts = -1;
154       while(num) {
155         num>>=1;
156         nshifts++;
157       }
158       return nshifts;
159     }
160   }
161
162   return -1;
163 }
164
165 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 {
167
168   DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
169                        line_no,
170                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
171                        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
172                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
173                        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
174                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
175                        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
176                        ((result) ? AOP_SIZE(result) : 0));
177
178 }
179
180 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 {
182
183   DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
184                        line_no,
185                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
186                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
187                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
188                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
189                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
190                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
191
192 }
193
194 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 {
196     va_list ap;
197     char lb[INITIAL_INLINEASM];  
198     char *lbp = lb;
199
200     if(!debug_verbose)
201       return;
202
203     va_start(ap,fmt);   
204
205     if (inst && *inst) {
206         if (fmt && *fmt)
207             sprintf(lb,"%s\t",inst);
208         else
209             sprintf(lb,"%s",inst);
210         vsprintf(lb+(strlen(lb)),fmt,ap);
211     }  else
212         vsprintf(lb,fmt,ap);
213
214     while (isspace(*lbp)) lbp++;
215
216     if (lbp && *lbp) 
217         lineCurr = (lineCurr ?
218                     connectLine(lineCurr,newLineNode(lb)) :
219                     (lineHead = newLineNode(lb)));
220     lineCurr->isInline = _G.inLine;
221     lineCurr->isDebug  = _G.debugLine;
222
223     addpCode2pBlock(pb,newpCodeCharP(lb));
224
225     va_end(ap);
226 }
227
228
229 void emitpLabel(int key)
230 {
231   addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 }
233
234 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
235 {
236
237   if(pcop)
238     addpCode2pBlock(pb,newpCode(poc,pcop));
239   else
240     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
241 }
242
243 void emitpcodeNULLop(PIC_OPCODE poc)
244 {
245
246   addpCode2pBlock(pb,newpCode(poc,NULL));
247
248 }
249
250 /*-----------------------------------------------------------------*/
251 /* pic14_emitcode - writes the code into a file : for now it is simple    */
252 /*-----------------------------------------------------------------*/
253 void pic14_emitcode (char *inst,char *fmt, ...)
254 {
255     va_list ap;
256     char lb[INITIAL_INLINEASM];  
257     char *lbp = lb;
258
259     va_start(ap,fmt);   
260
261     if (inst && *inst) {
262         if (fmt && *fmt)
263             sprintf(lb,"%s\t",inst);
264         else
265             sprintf(lb,"%s",inst);
266         vsprintf(lb+(strlen(lb)),fmt,ap);
267     }  else
268         vsprintf(lb,fmt,ap);
269
270     while (isspace(*lbp)) lbp++;
271
272     if (lbp && *lbp) 
273         lineCurr = (lineCurr ?
274                     connectLine(lineCurr,newLineNode(lb)) :
275                     (lineHead = newLineNode(lb)));
276     lineCurr->isInline = _G.inLine;
277     lineCurr->isDebug  = _G.debugLine;
278
279     if(debug_verbose)
280       addpCode2pBlock(pb,newpCodeCharP(lb));
281
282     va_end(ap);
283 }
284
285
286 /*-----------------------------------------------------------------*/
287 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
288 /*-----------------------------------------------------------------*/
289 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
290 {
291     bool r0iu = FALSE , r1iu = FALSE;
292     bool r0ou = FALSE , r1ou = FALSE;
293
294     /* the logic: if r0 & r1 used in the instruction
295     then we are in trouble otherwise */
296
297     /* first check if r0 & r1 are used by this
298     instruction, in which case we are in trouble */
299     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
301     {
302         goto endOfWorld;      
303     }
304
305     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
307
308     /* if no usage of r0 then return it */
309     if (!r0iu && !r0ou) {
310         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311         (*aopp)->type = AOP_R0;
312         
313         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314     }
315
316     /* if no usage of r1 then return it */
317     if (!r1iu && !r1ou) {
318         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319         (*aopp)->type = AOP_R1;
320
321         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322     }    
323
324     /* now we know they both have usage */
325     /* if r0 not used in this instruction */
326     if (!r0iu) {
327         /* push it if not already pushed */
328         if (!_G.r0Pushed) {
329           //pic14_emitcode ("push","%s",
330           //          pic14_regWithIdx(R0_IDX)->dname);
331             _G.r0Pushed++ ;
332         }
333         
334         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335         (*aopp)->type = AOP_R0;
336
337         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338     }
339
340     /* if r1 not used then */
341
342     if (!r1iu) {
343         /* push it if not already pushed */
344         if (!_G.r1Pushed) {
345           //pic14_emitcode ("push","%s",
346           //          pic14_regWithIdx(R1_IDX)->dname);
347             _G.r1Pushed++ ;
348         }
349         
350         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351         (*aopp)->type = AOP_R1;
352         return pic14_regWithIdx(R1_IDX);
353     }
354
355 endOfWorld :
356     /* I said end of world but not quite end of world yet */
357     /* if this is a result then we can push it on the stack*/
358     if (result) {
359         (*aopp)->type = AOP_STK;    
360         return NULL;
361     }
362
363     /* other wise this is true end of the world */
364     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365            "getFreePtr should never reach here");
366     exit(0);
367 }
368
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp                                  */
371 /*-----------------------------------------------------------------*/
372 asmop *newAsmop (short type)
373 {
374     asmop *aop;
375
376     aop = Safe_calloc(1,sizeof(asmop));
377     aop->type = type;
378     return aop;
379 }
380
381 static void genSetDPTR(int n)
382 {
383     if (!n)
384     {
385         pic14_emitcode(";", "Select standard DPTR");
386         pic14_emitcode("mov", "dps, #0x00");
387     }
388     else
389     {
390         pic14_emitcode(";", "Select alternate DPTR");
391         pic14_emitcode("mov", "dps, #0x01");
392     }
393 }
394
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for  */
397 /*              generating code                                    */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
400 {
401   if(!resIfx) 
402     return;
403
404   //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
405
406   resIfx->condition = 1;    /* assume that the ifx is true */
407   resIfx->generated = 0;    /* indicate that the ifx has not been used */
408
409   if(!ifx) {
410     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
411 /*
412     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
413                         __FUNCTION__,__LINE__,resIfx->lbl->key);
414 */
415   } else {
416     if(IC_TRUE(ifx)) {
417       resIfx->lbl = IC_TRUE(ifx);
418     } else {
419       resIfx->lbl = IC_FALSE(ifx);
420       resIfx->condition = 0;
421     }
422 /*
423     if(IC_TRUE(ifx)) 
424       DEBUGpic14_emitcode("; ***","ifx true is non-null");
425     if(IC_FALSE(ifx)) 
426       DEBUGpic14_emitcode("; ***","ifx false is non-null");
427 */
428   }
429
430   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
431
432 }
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type               */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
437 {
438
439     return PTR_TYPE(SPEC_OCLS(etype));
440
441 }
442
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol                                   */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
447 {
448     asmop *aop;
449     memmap *space= SPEC_OCLS(sym->etype);
450
451     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452     /* if already has one */
453     if (sym->aop)
454         return sym->aop;
455
456     /* assign depending on the storage class */
457     /* if it is on the stack or indirectly addressable */
458     /* space we need to assign either r0 or r1 to it   */    
459     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
460         sym->aop = aop = newAsmop(0);
461         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
462         aop->size = getSize(sym->type);
463
464         /* now assign the address of the variable to 
465         the pointer register */
466         if (aop->type != AOP_STK) {
467
468             if (sym->onStack) {
469                     if ( _G.accInUse )
470                         pic14_emitcode("push","acc");
471
472                     pic14_emitcode("mov","a,_bp");
473                     pic14_emitcode("add","a,#0x%02x",
474                              ((sym->stack < 0) ?
475                               ((char)(sym->stack - _G.nRegsSaved )) :
476                               ((char)sym->stack)) & 0xff);
477                     pic14_emitcode("mov","%s,a",
478                              aop->aopu.aop_ptr->name);
479
480                     if ( _G.accInUse )
481                         pic14_emitcode("pop","acc");
482             } else
483                 pic14_emitcode("mov","%s,#%s",
484                          aop->aopu.aop_ptr->name,
485                          sym->rname);
486             aop->paged = space->paged;
487         } else
488             aop->aopu.aop_stk = sym->stack;
489         return aop;
490     }
491     
492     if (sym->onStack && options.stack10bit)
493     {
494         /* It's on the 10 bit stack, which is located in
495          * far data space.
496          */
497          
498       //DEBUGpic14_emitcode(";","%d",__LINE__);
499
500         if ( _G.accInUse )
501                 pic14_emitcode("push","acc");
502
503         pic14_emitcode("mov","a,_bp");
504         pic14_emitcode("add","a,#0x%02x",
505                  ((sym->stack < 0) ?
506                    ((char)(sym->stack - _G.nRegsSaved )) :
507                    ((char)sym->stack)) & 0xff);
508         
509         genSetDPTR(1);
510         pic14_emitcode ("mov","dpx1,#0x40");
511         pic14_emitcode ("mov","dph1,#0x00");
512         pic14_emitcode ("mov","dpl1, a");
513         genSetDPTR(0);
514         
515         if ( _G.accInUse )
516             pic14_emitcode("pop","acc");
517             
518         sym->aop = aop = newAsmop(AOP_DPTR2);
519         aop->size = getSize(sym->type); 
520         return aop;
521     }
522
523     //DEBUGpic14_emitcode(";","%d",__LINE__);
524     /* if in bit space */
525     if (IN_BITSPACE(space)) {
526         sym->aop = aop = newAsmop (AOP_CRY);
527         aop->aopu.aop_dir = sym->rname ;
528         aop->size = getSize(sym->type);
529         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
530         return aop;
531     }
532     /* if it is in direct space */
533     if (IN_DIRSPACE(space)) {
534         sym->aop = aop = newAsmop (AOP_DIR);
535         aop->aopu.aop_dir = sym->rname ;
536         aop->size = getSize(sym->type);
537         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
538         return aop;
539     }
540
541     /* special case for a function */
542     if (IS_FUNC(sym->type)) {   
543         sym->aop = aop = newAsmop(AOP_IMMD);    
544         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
545         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
546         strcpy(aop->aopu.aop_immd,sym->rname);
547         aop->size = FPTRSIZE; 
548         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
549         return aop;
550     }
551
552
553     /* only remaining is far space */
554     /* in which case DPTR gets the address */
555     sym->aop = aop = newAsmop(AOP_PCODE);
556
557     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
558     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559     PCOI(aop->aopu.pcop)->index = 0;
560
561     DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
562                         sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
563
564     allocDirReg (IC_LEFT(ic));
565
566     aop->size = FPTRSIZE; 
567 /*
568     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569     sym->aop = aop = newAsmop(AOP_DPTR);
570     pic14_emitcode ("mov","dptr,#%s", sym->rname);
571     aop->size = getSize(sym->type);
572
573     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
574 */
575
576     /* if it is in code space */
577     if (IN_CODESPACE(space))
578         aop->code = 1;
579
580     return aop;     
581 }
582
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object                           */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
587 {
588   symbol *sym = OP_SYMBOL(op);
589   iCode *ic = NULL;
590   asmop *aop = newAsmop(AOP_PCODE);
591   int val = 0;
592   int offset = 0;
593
594   ic = sym->rematiCode;
595
596   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597   if(IS_OP_POINTER(op)) {
598     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
599   }
600   for (;;) {
601     if (ic->op == '+') {
602       val += (int) operandLitValue(IC_RIGHT(ic));
603     } else if (ic->op == '-') {
604       val -= (int) operandLitValue(IC_RIGHT(ic));
605     } else
606       break;
607         
608     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
609   }
610
611   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
613   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614   PCOI(aop->aopu.pcop)->index = val;
615
616   DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
617                       OP_SYMBOL(IC_LEFT(ic))->rname,
618                       val, IS_PTR_CONST(operandType(op)));
619
620   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
621
622   allocDirReg (IC_LEFT(ic));
623
624   return aop;        
625 }
626
627 int aopIdx (asmop *aop, int offset)
628 {
629   if(!aop)
630     return -1;
631
632   if(aop->type !=  AOP_REG)
633     return -2;
634         
635   return aop->aopu.aop_reg[offset]->rIdx;
636
637 }
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common       */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
642 {
643     symbol *sym1, *sym2;
644     int i;
645
646     /* if they have registers in common */
647     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
648         return FALSE ;
649
650     sym1 = OP_SYMBOL(op1);
651     sym2 = OP_SYMBOL(op2);
652
653     if (sym1->nRegs == 0 || sym2->nRegs == 0)
654         return FALSE ;
655
656     for (i = 0 ; i < sym1->nRegs ; i++) {
657         int j;
658         if (!sym1->regs[i])
659             continue ;
660
661         for (j = 0 ; j < sym2->nRegs ;j++ ) {
662             if (!sym2->regs[j])
663                 continue ;
664
665             if (sym2->regs[j] == sym1->regs[i])
666                 return TRUE ;
667         }
668     }
669
670     return FALSE ;
671 }
672
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent                                        */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
677 {
678     symbol *sym1, *sym2;
679
680     /* if they not symbols */
681     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
682         return FALSE;
683
684     sym1 = OP_SYMBOL(op1);
685     sym2 = OP_SYMBOL(op2);
686
687     /* if both are itemps & one is spilt
688        and the other is not then false */
689     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690         sym1->isspilt != sym2->isspilt )
691         return FALSE ;
692
693     /* if they are the same */
694     if (sym1 == sym2)
695         return TRUE ;
696
697     if (strcmp(sym1->rname,sym2->rname) == 0)
698         return TRUE;
699
700
701     /* if left is a tmp & right is not */
702     if (IS_ITEMP(op1)  && 
703         !IS_ITEMP(op2) &&
704         sym1->isspilt  &&
705         (sym1->usl.spillLoc == sym2))
706         return TRUE;
707
708     if (IS_ITEMP(op2)  && 
709         !IS_ITEMP(op1) &&
710         sym2->isspilt  &&
711         sym1->level > 0 &&
712         (sym2->usl.spillLoc == sym1))
713         return TRUE ;
714
715     return FALSE ;
716 }
717
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers                   */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 {
723     int i;
724
725     if (aop1 == aop2)
726         return TRUE ;
727
728     if (aop1->type != AOP_REG ||
729         aop2->type != AOP_REG )
730         return FALSE ;
731
732     if (aop1->size != aop2->size )
733         return FALSE ;
734
735     for (i = 0 ; i < aop1->size ; i++ )
736         if (aop1->aopu.aop_reg[i] !=
737             aop2->aopu.aop_reg[i] )
738             return FALSE ;
739
740     return TRUE ;
741 }
742
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand  :                    */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
747 {
748     asmop *aop;
749     symbol *sym;
750     int i;
751
752     if (!op)
753         return ;
754
755     //    DEBUGpic14_emitcode(";","%d",__LINE__);
756     /* if this a literal */
757     if (IS_OP_LITERAL(op)) {
758         op->aop = aop = newAsmop(AOP_LIT);
759         aop->aopu.aop_lit = op->operand.valOperand;
760         aop->size = getSize(operandType(op));
761         return;
762     }
763
764     {
765       sym_link *type = operandType(op);
766       if(IS_PTR_CONST(type))
767         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
768     }
769
770     /* if already has a asmop then continue */
771     if (op->aop)
772         return ;
773
774     /* if the underlying symbol has a aop */
775     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776       DEBUGpic14_emitcode(";","%d",__LINE__);
777         op->aop = OP_SYMBOL(op)->aop;
778         return;
779     }
780
781     /* if this is a true symbol */
782     if (IS_TRUE_SYMOP(op)) {    
783       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
785       return ;
786     }
787
788     /* this is a temporary : this has
789     only four choices :
790     a) register
791     b) spillocation
792     c) rematerialize 
793     d) conditional   
794     e) can be a return use only */
795
796     sym = OP_SYMBOL(op);
797
798
799     /* if the type is a conditional */
800     if (sym->regType == REG_CND) {
801         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
802         aop->size = 0;
803         return;
804     }
805
806     /* if it is spilt then two situations
807     a) is rematerialize 
808     b) has a spill location */
809     if (sym->isspilt || sym->nRegs == 0) {
810
811       DEBUGpic14_emitcode(";","%d",__LINE__);
812         /* rematerialize it NOW */
813         if (sym->remat) {
814
815             sym->aop = op->aop = aop =
816                                       aopForRemat (op);
817             aop->size = getSize(sym->type);
818             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
819             return;
820         }
821
822         if (sym->accuse) {
823             int i;
824             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825             aop->size = getSize(sym->type);
826             for ( i = 0 ; i < 2 ; i++ )
827                 aop->aopu.aop_str[i] = accUse[i];
828             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
829             return;  
830         }
831
832         if (sym->ruonly ) {
833           /*
834           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
835           aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
836           //allocDirReg (IC_LEFT(ic));
837           aop->size = getSize(sym->type);
838           */
839
840           unsigned i;
841
842           aop = op->aop = sym->aop = newAsmop(AOP_STR);
843           aop->size = getSize(sym->type);
844           for ( i = 0 ; i < fReturnSizePic ; i++ )
845             aop->aopu.aop_str[i] = fReturn[i];
846
847           DEBUGpic14_emitcode(";","%d",__LINE__);
848           return;
849         }
850
851         /* else spill location  */
852         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
853             /* force a new aop if sizes differ */
854             sym->usl.spillLoc->aop = NULL;
855         }
856         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
857                             __FUNCTION__,__LINE__,
858                             sym->usl.spillLoc->rname,
859                             sym->rname, sym->usl.spillLoc->offset);
860
861         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
862         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
863         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
864                                           getSize(sym->type), 
865                                           sym->usl.spillLoc->offset);
866         aop->size = getSize(sym->type);
867
868         return;
869     }
870
871     {
872       sym_link *type = operandType(op);
873       if(IS_PTR_CONST(type)) 
874         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
875     }
876
877     /* must be in a register */
878     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
879     sym->aop = op->aop = aop = newAsmop(AOP_REG);
880     aop->size = sym->nRegs;
881     for ( i = 0 ; i < sym->nRegs ;i++)
882         aop->aopu.aop_reg[i] = sym->regs[i];
883 }
884
885 /*-----------------------------------------------------------------*/
886 /* freeAsmop - free up the asmop given to an operand               */
887 /*----------------------------------------------------------------*/
888 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
889 {   
890     asmop *aop ;
891
892     if (!op)
893         aop = aaop;
894     else 
895         aop = op->aop;
896
897     if (!aop)
898         return ;
899
900     if (aop->freed)
901         goto dealloc; 
902
903     aop->freed = 1;
904
905     /* depending on the asmop type only three cases need work AOP_RO
906        , AOP_R1 && AOP_STK */
907 #if 0
908     switch (aop->type) {
909         case AOP_R0 :
910             if (_G.r0Pushed ) {
911                 if (pop) {
912                     pic14_emitcode ("pop","ar0");     
913                     _G.r0Pushed--;
914                 }
915             }
916             bitVectUnSetBit(ic->rUsed,R0_IDX);
917             break;
918
919         case AOP_R1 :
920             if (_G.r1Pushed ) {
921                 if (pop) {
922                     pic14_emitcode ("pop","ar1");
923                     _G.r1Pushed--;
924                 }
925             }
926             bitVectUnSetBit(ic->rUsed,R1_IDX);          
927             break;
928
929         case AOP_STK :
930         {
931             int sz = aop->size;    
932             int stk = aop->aopu.aop_stk + aop->size;
933             bitVectUnSetBit(ic->rUsed,R0_IDX);
934             bitVectUnSetBit(ic->rUsed,R1_IDX);          
935
936             getFreePtr(ic,&aop,FALSE);
937             
938             if (options.stack10bit)
939             {
940                 /* I'm not sure what to do here yet... */
941                 /* #STUB */
942                 fprintf(stderr, 
943                         "*** Warning: probably generating bad code for "
944                         "10 bit stack mode.\n");
945             }
946             
947             if (stk) {
948                 pic14_emitcode ("mov","a,_bp");
949                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
950                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
951             } else {
952                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
953             }
954
955             while (sz--) {
956                 pic14_emitcode("pop","acc");
957                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
958                 if (!sz) break;
959                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
960             }
961             op->aop = aop;
962             freeAsmop(op,NULL,ic,TRUE);
963             if (_G.r0Pushed) {
964                 pic14_emitcode("pop","ar0");
965                 _G.r0Pushed--;
966             }
967
968             if (_G.r1Pushed) {
969                 pic14_emitcode("pop","ar1");
970                 _G.r1Pushed--;
971             }       
972         }
973     }
974 #endif
975
976 dealloc:
977     /* all other cases just dealloc */
978     if (op ) {
979         op->aop = NULL;
980         if (IS_SYMOP(op)) {
981             OP_SYMBOL(op)->aop = NULL;    
982             /* if the symbol has a spill */
983             if (SPIL_LOC(op))
984                 SPIL_LOC(op)->aop = NULL;
985         }
986     }
987 }
988
989 /*-----------------------------------------------------------------*/
990 /* aopGet - for fetching value of the aop                          */
991 /*-----------------------------------------------------------------*/
992 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
993 {
994     char *s = buffer ;
995     char *rs;
996
997     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
998     /* offset is greater than
999     size then zero */
1000     if (offset > (aop->size - 1) &&
1001         aop->type != AOP_LIT)
1002         return zero;
1003
1004     /* depending on type */
1005     switch (aop->type) {
1006         
1007     case AOP_R0:
1008     case AOP_R1:
1009         DEBUGpic14_emitcode(";","%d",__LINE__);
1010         /* if we need to increment it */       
1011         while (offset > aop->coff) {        
1012             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1013             aop->coff++;
1014         }
1015         
1016         while (offset < aop->coff) {
1017             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1018             aop->coff--;
1019         }
1020         
1021         aop->coff = offset ;
1022         if (aop->paged) {
1023             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1024             return (dname ? "acc" : "a");
1025         }       
1026         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1027         rs = Safe_calloc(1,strlen(s)+1);
1028         strcpy(rs,s);   
1029         return rs;
1030         
1031     case AOP_DPTR:
1032     case AOP_DPTR2:
1033         DEBUGpic14_emitcode(";","%d",__LINE__);
1034     if (aop->type == AOP_DPTR2)
1035     {
1036         genSetDPTR(1);
1037     }
1038     
1039         while (offset > aop->coff) {
1040             pic14_emitcode ("inc","dptr");
1041             aop->coff++;
1042         }
1043         
1044         while (offset < aop->coff) {        
1045             pic14_emitcode("lcall","__decdptr");
1046             aop->coff--;
1047         }
1048         
1049         aop->coff = offset;
1050         if (aop->code) {
1051             pic14_emitcode("clr","a");
1052             pic14_emitcode("movc","a,@a+dptr");
1053         }
1054     else {
1055             pic14_emitcode("movx","a,@dptr");
1056     }
1057             
1058     if (aop->type == AOP_DPTR2)
1059     {
1060         genSetDPTR(0);
1061     }
1062             
1063     return (dname ? "acc" : "a");
1064         
1065         
1066     case AOP_IMMD:
1067         if (bit16) 
1068             sprintf (s,"%s",aop->aopu.aop_immd);
1069         else
1070             if (offset) 
1071                 sprintf(s,"(%s >> %d)",
1072                         aop->aopu.aop_immd,
1073                         offset*8);
1074             else
1075                 sprintf(s,"%s",
1076                         aop->aopu.aop_immd);
1077         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1078         rs = Safe_calloc(1,strlen(s)+1);
1079         strcpy(rs,s);   
1080         return rs;
1081         
1082     case AOP_DIR:
1083       if (offset) {
1084         sprintf(s,"(%s + %d)",
1085                 aop->aopu.aop_dir,
1086                 offset);
1087         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1088       } else
1089             sprintf(s,"%s",aop->aopu.aop_dir);
1090         rs = Safe_calloc(1,strlen(s)+1);
1091         strcpy(rs,s);   
1092         return rs;
1093         
1094     case AOP_REG:
1095       //if (dname) 
1096       //    return aop->aopu.aop_reg[offset]->dname;
1097       //else
1098             return aop->aopu.aop_reg[offset]->name;
1099         
1100     case AOP_CRY:
1101       //pic14_emitcode(";","%d",__LINE__);
1102       return aop->aopu.aop_dir;
1103         
1104     case AOP_ACC:
1105         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1106         return "AOP_accumulator_bug";
1107
1108     case AOP_LIT:
1109         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1110         rs = Safe_calloc(1,strlen(s)+1);
1111         strcpy(rs,s);   
1112         return rs;
1113         
1114     case AOP_STR:
1115         DEBUGpic14_emitcode(";","%d",__LINE__);
1116         aop->coff = offset ;
1117         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1118             dname)
1119             return "acc";
1120         
1121         return aop->aopu.aop_str[offset];
1122         
1123     case AOP_PCODE:
1124       {
1125         pCodeOp *pcop = aop->aopu.pcop;
1126         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1127         if(pcop->name) {
1128           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1129           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1130           sprintf(s,"%s", pcop->name);
1131         } else
1132           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1133
1134       }
1135       rs = Safe_calloc(1,strlen(s)+1);
1136       strcpy(rs,s);   
1137       return rs;
1138
1139     }
1140
1141     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1142            "aopget got unsupported aop->type");
1143     exit(0);
1144 }
1145
1146
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp                  */
1149 /*-----------------------------------------------------------------*/
1150 pCodeOp *popGetTempReg(void)
1151 {
1152
1153   pCodeOp *pcop;
1154
1155   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1156   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1157     PCOR(pcop)->r->wasUsed=1;
1158     PCOR(pcop)->r->isFree=0;
1159   }
1160
1161   return pcop;
1162 }
1163
1164 /*-----------------------------------------------------------------*/
1165 /* popGetTempReg - create a new temporary pCodeOp                  */
1166 /*-----------------------------------------------------------------*/
1167 void popReleaseTempReg(pCodeOp *pcop)
1168 {
1169
1170   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1171     PCOR(pcop)->r->isFree = 1;
1172
1173 }
1174 /*-----------------------------------------------------------------*/
1175 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1176 /*-----------------------------------------------------------------*/
1177 pCodeOp *popGetLabel(unsigned int key)
1178 {
1179
1180   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1181
1182   if(key>max_key)
1183     max_key = key;
1184
1185   return newpCodeOpLabel(NULL,key+100+labelOffset);
1186 }
1187
1188 /*-----------------------------------------------------------------*/
1189 /* popCopyReg - copy a pcode operator                              */
1190 /*-----------------------------------------------------------------*/
1191 pCodeOp *popCopyReg(pCodeOpReg *pc)
1192 {
1193   pCodeOpReg *pcor;
1194
1195   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1196   pcor->pcop.type = pc->pcop.type;
1197   if(pc->pcop.name) {
1198     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1199       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1200   } else
1201     pcor->pcop.name = NULL;
1202
1203   pcor->r = pc->r;
1204   pcor->rIdx = pc->rIdx;
1205   pcor->r->wasUsed=1;
1206
1207   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1208
1209   return PCOP(pcor);
1210 }
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion              */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetLit(unsigned int lit)
1215 {
1216
1217   return newpCodeOpLit(lit);
1218 }
1219
1220
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion         */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1225 {
1226
1227   return newpCodeOpImmd(name, offset,index, 0);
1228 }
1229
1230
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion              */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str)
1235 {
1236   pCodeOp *pcop;
1237
1238
1239   if(!str) {
1240     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1241     exit (1);
1242   }
1243
1244   pcop = newpCodeOp(str,PO_STR);
1245
1246   return pcop;
1247 }
1248
1249 /*-----------------------------------------------------------------*/
1250 /* popRegFromString -                                              */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popRegFromString(char *str, int size, int offset)
1253 {
1254
1255   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256   pcop->type = PO_DIR;
1257
1258   DEBUGpic14_emitcode(";","%d",__LINE__);
1259
1260   if(!str)
1261     str = "BAD_STRING";
1262
1263   pcop->name = Safe_calloc(1,strlen(str)+1);
1264   strcpy(pcop->name,str);
1265
1266   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1267
1268   PCOR(pcop)->r = dirregWithName(pcop->name);
1269   if(PCOR(pcop)->r == NULL) {
1270     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1271     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1272     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1273   } else {
1274     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1275   }
1276   PCOR(pcop)->instance = offset;
1277
1278   return pcop;
1279 }
1280
1281 pCodeOp *popRegFromIdx(int rIdx)
1282 {
1283   pCodeOp *pcop;
1284
1285   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1286                        __FUNCTION__,__LINE__,rIdx);
1287
1288   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1289
1290   PCOR(pcop)->rIdx = rIdx;
1291   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1292   PCOR(pcop)->r->isFree = 0;
1293   PCOR(pcop)->r->wasUsed = 1;
1294
1295   pcop->type = PCOR(pcop)->r->pc_type;
1296
1297
1298   return pcop;
1299 }
1300 /*-----------------------------------------------------------------*/
1301 /* popGet - asm operator to pcode operator conversion              */
1302 /*-----------------------------------------------------------------*/
1303 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1304 {
1305   //char *s = buffer ;
1306     //char *rs;
1307
1308     pCodeOp *pcop;
1309
1310     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1311     /* offset is greater than
1312     size then zero */
1313
1314     if (offset > (aop->size - 1) &&
1315         aop->type != AOP_LIT)
1316       return NULL;  //zero;
1317
1318     /* depending on type */
1319     switch (aop->type) {
1320         
1321     case AOP_R0:
1322     case AOP_R1:
1323     case AOP_DPTR:
1324     case AOP_DPTR2:
1325     case AOP_ACC:
1326         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1327         return NULL;
1328         
1329     case AOP_IMMD:
1330       DEBUGpic14_emitcode(";","%d",__LINE__);
1331       return popGetImmd(aop->aopu.aop_immd,offset,0);
1332
1333     case AOP_DIR:
1334       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1335 #if 0
1336         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1337         pcop->type = PO_DIR;
1338
1339         /*
1340         if (offset)
1341             sprintf(s,"(%s + %d)",
1342                     aop->aopu.aop_dir,
1343                     offset);
1344         else
1345             sprintf(s,"%s",aop->aopu.aop_dir);
1346         pcop->name = Safe_calloc(1,strlen(s)+1);
1347         strcpy(pcop->name,s);   
1348         */
1349         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1350         strcpy(pcop->name,aop->aopu.aop_dir);   
1351         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1352         if(PCOR(pcop)->r == NULL) {
1353           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1354           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1355           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1356         } else {
1357           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1358         }
1359         PCOR(pcop)->instance = offset;
1360
1361         return pcop;
1362 #endif
1363         
1364     case AOP_REG:
1365       {
1366         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1367
1368         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1369         PCOR(pcop)->rIdx = rIdx;
1370         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1371         PCOR(pcop)->r->wasUsed=1;
1372         PCOR(pcop)->r->isFree=0;
1373
1374         PCOR(pcop)->instance = offset;
1375         pcop->type = PCOR(pcop)->r->pc_type;
1376         //rs = aop->aopu.aop_reg[offset]->name;
1377         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1378         return pcop;
1379       }
1380
1381     case AOP_CRY:
1382       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1383       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1384       //if(PCOR(pcop)->r == NULL)
1385       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1386       return pcop;
1387         
1388     case AOP_LIT:
1389       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1390
1391     case AOP_STR:
1392       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1393       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1394       /*
1395       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1396       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1397       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1398       pcop->type = PCOR(pcop)->r->pc_type;
1399       pcop->name = PCOR(pcop)->r->name;
1400
1401       return pcop;
1402       */
1403
1404     case AOP_PCODE:
1405       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1406                           __LINE__, 
1407                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1408       pcop = pCodeOpCopy(aop->aopu.pcop);
1409       PCOI(pcop)->offset = offset;
1410       return pcop;
1411     }
1412
1413     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1414            "popGet got unsupported aop->type");
1415     exit(0);
1416 }
1417 /*-----------------------------------------------------------------*/
1418 /* aopPut - puts a string for a aop                                */
1419 /*-----------------------------------------------------------------*/
1420 void aopPut (asmop *aop, char *s, int offset)
1421 {
1422     char *d = buffer ;
1423     symbol *lbl ;
1424
1425     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1426
1427     if (aop->size && offset > ( aop->size - 1)) {
1428         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1429                "aopPut got offset > aop->size");
1430         exit(0);
1431     }
1432
1433     /* will assign value to value */
1434     /* depending on where it is ofcourse */
1435     switch (aop->type) {
1436     case AOP_DIR:
1437       if (offset) {
1438         sprintf(d,"(%s + %d)",
1439                 aop->aopu.aop_dir,offset);
1440         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1441
1442       } else
1443             sprintf(d,"%s",aop->aopu.aop_dir);
1444         
1445         if (strcmp(d,s)) {
1446           DEBUGpic14_emitcode(";","%d",__LINE__);
1447           if(strcmp(s,"W"))
1448             pic14_emitcode("movf","%s,w",s);
1449           pic14_emitcode("movwf","%s",d);
1450
1451           if(strcmp(s,"W")) {
1452             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1453             if(offset >= aop->size) {
1454               emitpcode(POC_CLRF,popGet(aop,offset));
1455               break;
1456             } else
1457               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1458           }
1459
1460           emitpcode(POC_MOVWF,popGet(aop,offset));
1461
1462
1463         }
1464         break;
1465         
1466     case AOP_REG:
1467       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1468         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1469           /*
1470             if (*s == '@'           ||
1471                 strcmp(s,"r0") == 0 ||
1472                 strcmp(s,"r1") == 0 ||
1473                 strcmp(s,"r2") == 0 ||
1474                 strcmp(s,"r3") == 0 ||
1475                 strcmp(s,"r4") == 0 ||
1476                 strcmp(s,"r5") == 0 ||
1477                 strcmp(s,"r6") == 0 || 
1478                 strcmp(s,"r7") == 0 )
1479                 pic14_emitcode("mov","%s,%s  ; %d",
1480                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1481             else
1482           */
1483
1484           if(strcmp(s,"W")==0 )
1485             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1486
1487           pic14_emitcode("movwf","%s",
1488                    aop->aopu.aop_reg[offset]->name);
1489
1490           if(strcmp(s,zero)==0) {
1491             emitpcode(POC_CLRF,popGet(aop,offset));
1492
1493           } else if(strcmp(s,"W")==0) {
1494             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1495             pcop->type = PO_GPR_REGISTER;
1496
1497             PCOR(pcop)->rIdx = -1;
1498             PCOR(pcop)->r = NULL;
1499
1500             DEBUGpic14_emitcode(";","%d",__LINE__);
1501             pcop->name = Safe_strdup(s);
1502             emitpcode(POC_MOVFW,pcop);
1503             emitpcode(POC_MOVWF,popGet(aop,offset));
1504           } else if(strcmp(s,one)==0) {
1505             emitpcode(POC_CLRF,popGet(aop,offset));
1506             emitpcode(POC_INCF,popGet(aop,offset));
1507           } else {
1508             emitpcode(POC_MOVWF,popGet(aop,offset));
1509           }
1510         }
1511         break;
1512         
1513     case AOP_DPTR:
1514     case AOP_DPTR2:
1515     
1516     if (aop->type == AOP_DPTR2)
1517     {
1518         genSetDPTR(1);
1519     }
1520     
1521         if (aop->code) {
1522             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1523                    "aopPut writting to code space");
1524             exit(0);
1525         }
1526         
1527         while (offset > aop->coff) {
1528             aop->coff++;
1529             pic14_emitcode ("inc","dptr");
1530         }
1531         
1532         while (offset < aop->coff) {
1533             aop->coff-- ;
1534             pic14_emitcode("lcall","__decdptr");
1535         }
1536         
1537         aop->coff = offset;
1538         
1539         /* if not in accumulater */
1540         MOVA(s);        
1541         
1542         pic14_emitcode ("movx","@dptr,a");
1543         
1544     if (aop->type == AOP_DPTR2)
1545     {
1546         genSetDPTR(0);
1547     }
1548         break;
1549         
1550     case AOP_R0:
1551     case AOP_R1:
1552         while (offset > aop->coff) {
1553             aop->coff++;
1554             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1555         }
1556         while (offset < aop->coff) {
1557             aop->coff-- ;
1558             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559         }
1560         aop->coff = offset;
1561         
1562         if (aop->paged) {
1563             MOVA(s);           
1564             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565             
1566         } else
1567             if (*s == '@') {
1568                 MOVA(s);
1569                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1570             } else
1571                 if (strcmp(s,"r0") == 0 ||
1572                     strcmp(s,"r1") == 0 ||
1573                     strcmp(s,"r2") == 0 ||
1574                     strcmp(s,"r3") == 0 ||
1575                     strcmp(s,"r4") == 0 ||
1576                     strcmp(s,"r5") == 0 ||
1577                     strcmp(s,"r6") == 0 || 
1578                     strcmp(s,"r7") == 0 ) {
1579                     char buffer[10];
1580                     sprintf(buffer,"a%s",s);
1581                     pic14_emitcode("mov","@%s,%s",
1582                              aop->aopu.aop_ptr->name,buffer);
1583                 } else
1584                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585         
1586         break;
1587         
1588     case AOP_STK:
1589         if (strcmp(s,"a") == 0)
1590             pic14_emitcode("push","acc");
1591         else
1592             pic14_emitcode("push","%s",s);
1593         
1594         break;
1595         
1596     case AOP_CRY:
1597         /* if bit variable */
1598         if (!aop->aopu.aop_dir) {
1599             pic14_emitcode("clr","a");
1600             pic14_emitcode("rlc","a");
1601         } else {
1602             if (s == zero) 
1603                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1604             else
1605                 if (s == one)
1606                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1607                 else
1608                     if (!strcmp(s,"c"))
1609                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1610                     else {
1611                         lbl = newiTempLabel(NULL);
1612                         
1613                         if (strcmp(s,"a")) {
1614                             MOVA(s);
1615                         }
1616                         pic14_emitcode("clr","c");
1617                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1618                         pic14_emitcode("cpl","c");
1619                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1620                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621                     }
1622         }
1623         break;
1624         
1625     case AOP_STR:
1626         aop->coff = offset;
1627         if (strcmp(aop->aopu.aop_str[offset],s))
1628             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629         break;
1630         
1631     case AOP_ACC:
1632         aop->coff = offset;
1633         if (!offset && (strcmp(s,"acc") == 0))
1634             break;
1635         
1636         if (strcmp(aop->aopu.aop_str[offset],s))
1637             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1638         break;
1639
1640     default :
1641         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1642                "aopPut got unsupported aop->type");
1643         exit(0);    
1644     }    
1645
1646 }
1647
1648 /*-----------------------------------------------------------------*/
1649 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1650 /*-----------------------------------------------------------------*/
1651 void mov2w (asmop *aop, int offset)
1652 {
1653
1654   if(!aop)
1655     return;
1656
1657   if ( aop->type == AOP_PCODE ||
1658        aop->type == AOP_LIT )
1659     emitpcode(POC_MOVLW,popGet(aop,offset));
1660   else
1661     emitpcode(POC_MOVFW,popGet(aop,offset));
1662
1663 }
1664
1665 /*-----------------------------------------------------------------*/
1666 /* reAdjustPreg - points a register back to where it should        */
1667 /*-----------------------------------------------------------------*/
1668 static void reAdjustPreg (asmop *aop)
1669 {
1670     int size ;
1671
1672     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1673     aop->coff = 0;
1674     if ((size = aop->size) <= 1)
1675         return ;
1676     size-- ;
1677     switch (aop->type) {
1678         case AOP_R0 :
1679         case AOP_R1 :
1680             while (size--)
1681                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1682             break;          
1683         case AOP_DPTR :
1684         case AOP_DPTR2:
1685             if (aop->type == AOP_DPTR2)
1686             {
1687                 genSetDPTR(1);
1688             } 
1689             while (size--)
1690             {
1691                 pic14_emitcode("lcall","__decdptr");
1692             }
1693                 
1694             if (aop->type == AOP_DPTR2)
1695             {
1696                 genSetDPTR(0);
1697             }                
1698             break;  
1699
1700     }   
1701
1702 }
1703
1704 /*-----------------------------------------------------------------*/
1705 /* genNotFloat - generates not for float operations              */
1706 /*-----------------------------------------------------------------*/
1707 static void genNotFloat (operand *op, operand *res)
1708 {
1709     int size, offset;
1710     char *l;
1711     symbol *tlbl ;
1712
1713     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1714     /* we will put 127 in the first byte of 
1715     the result */
1716     aopPut(AOP(res),"#127",0);
1717     size = AOP_SIZE(op) - 1;
1718     offset = 1;
1719
1720     l = aopGet(op->aop,offset++,FALSE,FALSE);
1721     MOVA(l);    
1722
1723     while(size--) {
1724         pic14_emitcode("orl","a,%s",
1725                  aopGet(op->aop,
1726                         offset++,FALSE,FALSE));
1727     }
1728     tlbl = newiTempLabel(NULL);
1729
1730     tlbl = newiTempLabel(NULL);
1731     aopPut(res->aop,one,1);
1732     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1733     aopPut(res->aop,zero,1);
1734     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1735
1736     size = res->aop->size - 2;
1737     offset = 2;    
1738     /* put zeros in the rest */
1739     while (size--) 
1740         aopPut(res->aop,zero,offset++);
1741 }
1742
1743 #if 0
1744 /*-----------------------------------------------------------------*/
1745 /* opIsGptr: returns non-zero if the passed operand is             */   
1746 /* a generic pointer type.                                         */
1747 /*-----------------------------------------------------------------*/ 
1748 static int opIsGptr(operand *op)
1749 {
1750     sym_link *type = operandType(op);
1751     
1752     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1753     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1754     {
1755         return 1;
1756     }
1757     return 0;        
1758 }
1759 #endif
1760
1761 /*-----------------------------------------------------------------*/
1762 /* pic14_getDataSize - get the operand data size                         */
1763 /*-----------------------------------------------------------------*/
1764 int pic14_getDataSize(operand *op)
1765 {
1766     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1767
1768
1769     return AOP_SIZE(op);
1770
1771     // tsd- in the pic port, the genptr size is 1, so this code here
1772     // fails. ( in the 8051 port, the size was 4).
1773 #if 0
1774     int size;
1775     size = AOP_SIZE(op);
1776     if (size == GPTRSIZE)
1777     {
1778         sym_link *type = operandType(op);
1779         if (IS_GENPTR(type))
1780         {
1781             /* generic pointer; arithmetic operations
1782              * should ignore the high byte (pointer type).
1783              */
1784             size--;
1785     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1786         }
1787     }
1788     return size;
1789 #endif
1790 }
1791
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_outAcc - output Acc                                             */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_outAcc(operand *result)
1796 {
1797   int size,offset;
1798   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1799   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1800
1801
1802   size = pic14_getDataSize(result);
1803   if(size){
1804     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1805     size--;
1806     offset = 1;
1807     /* unsigned or positive */
1808     while(size--)
1809       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1810   }
1811
1812 }
1813
1814 /*-----------------------------------------------------------------*/
1815 /* pic14_outBitC - output a bit C                                        */
1816 /*-----------------------------------------------------------------*/
1817 void pic14_outBitC(operand *result)
1818 {
1819
1820     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1821     /* if the result is bit */
1822     if (AOP_TYPE(result) == AOP_CRY) 
1823         aopPut(AOP(result),"c",0);
1824     else {
1825         pic14_emitcode("clr","a  ; %d", __LINE__);
1826         pic14_emitcode("rlc","a");
1827         pic14_outAcc(result);
1828     }
1829 }
1830
1831 /*-----------------------------------------------------------------*/
1832 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1833 /*-----------------------------------------------------------------*/
1834 void pic14_toBoolean(operand *oper)
1835 {
1836     int size = AOP_SIZE(oper) - 1;
1837     int offset = 1;
1838
1839     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1840
1841     if ( AOP_TYPE(oper) != AOP_ACC) {
1842       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1843     }
1844     while (size--) {
1845       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1846     }
1847 }
1848
1849
1850 /*-----------------------------------------------------------------*/
1851 /* genNot - generate code for ! operation                          */
1852 /*-----------------------------------------------------------------*/
1853 static void genNot (iCode *ic)
1854 {
1855   symbol *tlbl;
1856   sym_link *optype = operandType(IC_LEFT(ic));
1857   int size;
1858
1859   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1860   /* assign asmOps to operand & result */
1861   aopOp (IC_LEFT(ic),ic,FALSE);
1862   aopOp (IC_RESULT(ic),ic,TRUE);
1863
1864   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1865   /* if in bit space then a special case */
1866   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1867     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1868       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1869       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1870     } else {
1871       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1872       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1873       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1874     }
1875     goto release;
1876   }
1877
1878   /* if type float then do float */
1879   if (IS_FLOAT(optype)) {
1880     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1881     goto release;
1882   }
1883
1884   size = AOP_SIZE(IC_RESULT(ic));
1885   if(size == 1) {
1886     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1887     emitpcode(POC_ANDLW,popGetLit(1));
1888     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1889     goto release;
1890   }
1891   pic14_toBoolean(IC_LEFT(ic));
1892
1893   tlbl = newiTempLabel(NULL);
1894   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1895   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1896   pic14_outBitC(IC_RESULT(ic));
1897
1898  release:    
1899   /* release the aops */
1900   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1901   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1902 }
1903
1904
1905 /*-----------------------------------------------------------------*/
1906 /* genCpl - generate code for complement                           */
1907 /*-----------------------------------------------------------------*/
1908 static void genCpl (iCode *ic)
1909 {
1910     int offset = 0;
1911     int size ;
1912
1913
1914     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1915     /* assign asmOps to operand & result */
1916     aopOp (IC_LEFT(ic),ic,FALSE);
1917     aopOp (IC_RESULT(ic),ic,TRUE);
1918
1919     /* if both are in bit space then 
1920     a special case */
1921     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1922         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1923
1924         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1925         pic14_emitcode("cpl","c"); 
1926         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1927         goto release; 
1928     } 
1929
1930     size = AOP_SIZE(IC_RESULT(ic));
1931     while (size--) {
1932         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1933         MOVA(l);       
1934         pic14_emitcode("cpl","a");
1935         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1936     }
1937
1938
1939 release:
1940     /* release the aops */
1941     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1942     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1943 }
1944
1945 /*-----------------------------------------------------------------*/
1946 /* genUminusFloat - unary minus for floating points                */
1947 /*-----------------------------------------------------------------*/
1948 static void genUminusFloat(operand *op,operand *result)
1949 {
1950     int size ,offset =0 ;
1951     char *l;
1952
1953     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1954     /* for this we just need to flip the 
1955     first it then copy the rest in place */
1956     size = AOP_SIZE(op) - 1;
1957     l = aopGet(AOP(op),3,FALSE,FALSE);
1958
1959     MOVA(l);    
1960
1961     pic14_emitcode("cpl","acc.7");
1962     aopPut(AOP(result),"a",3);    
1963
1964     while(size--) {
1965         aopPut(AOP(result),
1966                aopGet(AOP(op),offset,FALSE,FALSE),
1967                offset);
1968         offset++;
1969     }          
1970 }
1971
1972 /*-----------------------------------------------------------------*/
1973 /* genUminus - unary minus code generation                         */
1974 /*-----------------------------------------------------------------*/
1975 static void genUminus (iCode *ic)
1976 {
1977   int size, i;
1978   sym_link *optype, *rtype;
1979
1980
1981   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1982   /* assign asmops */
1983   aopOp(IC_LEFT(ic),ic,FALSE);
1984   aopOp(IC_RESULT(ic),ic,TRUE);
1985
1986   /* if both in bit space then special
1987      case */
1988   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1989       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1990
1991     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1992     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1993     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1994
1995     goto release; 
1996   } 
1997
1998   optype = operandType(IC_LEFT(ic));
1999   rtype = operandType(IC_RESULT(ic));
2000
2001   /* if float then do float stuff */
2002   if (IS_FLOAT(optype)) {
2003     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2004     goto release;
2005   }
2006
2007   /* otherwise subtract from zero by taking the 2's complement */
2008   size = AOP_SIZE(IC_LEFT(ic));
2009
2010   for(i=0; i<size; i++) {
2011     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2012       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2013     else {
2014       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2015       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2016     }
2017   }
2018
2019   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2020   for(i=1; i<size; i++) {
2021     emitSKPNZ;
2022     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2023   }
2024
2025  release:
2026   /* release the aops */
2027   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2028   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2029 }
2030
2031 /*-----------------------------------------------------------------*/
2032 /* saveRegisters - will look for a call and save the registers     */
2033 /*-----------------------------------------------------------------*/
2034 static void saveRegisters(iCode *lic) 
2035 {
2036     int i;
2037     iCode *ic;
2038     bitVect *rsave;
2039     sym_link *dtype;
2040
2041     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2042     /* look for call */
2043     for (ic = lic ; ic ; ic = ic->next) 
2044         if (ic->op == CALL || ic->op == PCALL)
2045             break;
2046
2047     if (!ic) {
2048         fprintf(stderr,"found parameter push with no function call\n");
2049         return ;
2050     }
2051
2052     /* if the registers have been saved already then
2053     do nothing */
2054     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2055         return ;
2056
2057     /* find the registers in use at this time 
2058     and push them away to safety */
2059     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2060                           ic->rUsed);
2061
2062     ic->regsSaved = 1;
2063     if (options.useXstack) {
2064         if (bitVectBitValue(rsave,R0_IDX))
2065             pic14_emitcode("mov","b,r0");
2066         pic14_emitcode("mov","r0,%s",spname);
2067         for (i = 0 ; i < pic14_nRegs ; i++) {
2068             if (bitVectBitValue(rsave,i)) {
2069                 if (i == R0_IDX)
2070                     pic14_emitcode("mov","a,b");
2071                 else
2072                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2073                 pic14_emitcode("movx","@r0,a");
2074                 pic14_emitcode("inc","r0");
2075             }
2076         }
2077         pic14_emitcode("mov","%s,r0",spname);
2078         if (bitVectBitValue(rsave,R0_IDX))
2079             pic14_emitcode("mov","r0,b");           
2080     }// else
2081     //for (i = 0 ; i < pic14_nRegs ; i++) {
2082     //    if (bitVectBitValue(rsave,i))
2083     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2084     //}
2085
2086     dtype = operandType(IC_LEFT(ic));
2087     if (currFunc && dtype && 
2088         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2089         IFFUNC_ISISR(currFunc->type) &&
2090         !ic->bankSaved) 
2091
2092         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2093
2094 }
2095 /*-----------------------------------------------------------------*/
2096 /* unsaveRegisters - pop the pushed registers                      */
2097 /*-----------------------------------------------------------------*/
2098 static void unsaveRegisters (iCode *ic)
2099 {
2100     int i;
2101     bitVect *rsave;
2102
2103     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2104     /* find the registers in use at this time 
2105     and push them away to safety */
2106     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2107                           ic->rUsed);
2108     
2109     if (options.useXstack) {
2110         pic14_emitcode("mov","r0,%s",spname);   
2111         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2112             if (bitVectBitValue(rsave,i)) {
2113                 pic14_emitcode("dec","r0");
2114                 pic14_emitcode("movx","a,@r0");
2115                 if (i == R0_IDX)
2116                     pic14_emitcode("mov","b,a");
2117                 else
2118                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2119             }       
2120
2121         }
2122         pic14_emitcode("mov","%s,r0",spname);
2123         if (bitVectBitValue(rsave,R0_IDX))
2124             pic14_emitcode("mov","r0,b");
2125     } //else
2126     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2127     //    if (bitVectBitValue(rsave,i))
2128     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2129     //}
2130
2131 }  
2132
2133
2134 /*-----------------------------------------------------------------*/
2135 /* pushSide -                                                      */
2136 /*-----------------------------------------------------------------*/
2137 static void pushSide(operand * oper, int size)
2138 {
2139 #if 0
2140         int offset = 0;
2141     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2142         while (size--) {
2143                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2144                 if (AOP_TYPE(oper) != AOP_REG &&
2145                     AOP_TYPE(oper) != AOP_DIR &&
2146                     strcmp(l,"a") ) {
2147                         pic14_emitcode("mov","a,%s",l);
2148                         pic14_emitcode("push","acc");
2149                 } else
2150                         pic14_emitcode("push","%s",l);
2151         }
2152 #endif
2153 }
2154
2155 /*-----------------------------------------------------------------*/
2156 /* assignResultValue -                                             */
2157 /*-----------------------------------------------------------------*/
2158 static void assignResultValue(operand * oper)
2159 {
2160   int size = AOP_SIZE(oper);
2161
2162   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2163
2164   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2165
2166   if(!GpsuedoStkPtr) {
2167     /* The last byte in the assignment is in W */
2168     size--;
2169     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2170     GpsuedoStkPtr++;
2171   }
2172
2173   while (size--) {
2174     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2175     GpsuedoStkPtr++;
2176     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2177   }
2178 }
2179
2180
2181 /*-----------------------------------------------------------------*/
2182 /* genIpush - genrate code for pushing this gets a little complex  */
2183 /*-----------------------------------------------------------------*/
2184 static void genIpush (iCode *ic)
2185 {
2186
2187   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2188 #if 0
2189     int size, offset = 0 ;
2190     char *l;
2191
2192
2193     /* if this is not a parm push : ie. it is spill push 
2194     and spill push is always done on the local stack */
2195     if (!ic->parmPush) {
2196
2197         /* and the item is spilt then do nothing */
2198         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2199             return ;
2200
2201         aopOp(IC_LEFT(ic),ic,FALSE);
2202         size = AOP_SIZE(IC_LEFT(ic));
2203         /* push it on the stack */
2204         while(size--) {
2205             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2206             if (*l == '#') {
2207                 MOVA(l);
2208                 l = "acc";
2209             }
2210             pic14_emitcode("push","%s",l);
2211         }
2212         return ;        
2213     }
2214
2215     /* this is a paramter push: in this case we call
2216     the routine to find the call and save those
2217     registers that need to be saved */   
2218     saveRegisters(ic);
2219
2220     /* then do the push */
2221     aopOp(IC_LEFT(ic),ic,FALSE);
2222
2223
2224         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2225     size = AOP_SIZE(IC_LEFT(ic));
2226
2227     while (size--) {
2228         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2229         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2230             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2231             strcmp(l,"a") ) {
2232             pic14_emitcode("mov","a,%s",l);
2233             pic14_emitcode("push","acc");
2234         } else
2235             pic14_emitcode("push","%s",l);
2236     }       
2237
2238     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2239 #endif
2240 }
2241
2242 /*-----------------------------------------------------------------*/
2243 /* genIpop - recover the registers: can happen only for spilling   */
2244 /*-----------------------------------------------------------------*/
2245 static void genIpop (iCode *ic)
2246 {
2247   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2248 #if 0
2249     int size,offset ;
2250
2251
2252     /* if the temp was not pushed then */
2253     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2254         return ;
2255
2256     aopOp(IC_LEFT(ic),ic,FALSE);
2257     size = AOP_SIZE(IC_LEFT(ic));
2258     offset = (size-1);
2259     while (size--) 
2260         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2261                                    FALSE,TRUE));
2262
2263     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2264 #endif
2265 }
2266
2267 /*-----------------------------------------------------------------*/
2268 /* unsaverbank - restores the resgister bank from stack            */
2269 /*-----------------------------------------------------------------*/
2270 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2271 {
2272   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2273 #if 0
2274     int i;
2275     asmop *aop ;
2276     regs *r = NULL;
2277
2278     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2279     if (popPsw) {
2280         if (options.useXstack) {
2281             aop = newAsmop(0);
2282             r = getFreePtr(ic,&aop,FALSE);
2283             
2284             
2285             pic14_emitcode("mov","%s,_spx",r->name);
2286             pic14_emitcode("movx","a,@%s",r->name);
2287             pic14_emitcode("mov","psw,a");
2288             pic14_emitcode("dec","%s",r->name);
2289             
2290         }else
2291             pic14_emitcode ("pop","psw");
2292     }
2293
2294     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2295         if (options.useXstack) {       
2296             pic14_emitcode("movx","a,@%s",r->name);
2297             //pic14_emitcode("mov","(%s+%d),a",
2298             //       regspic14[i].base,8*bank+regspic14[i].offset);
2299             pic14_emitcode("dec","%s",r->name);
2300
2301         } else 
2302           pic14_emitcode("pop",""); //"(%s+%d)",
2303         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2304     }
2305
2306     if (options.useXstack) {
2307
2308         pic14_emitcode("mov","_spx,%s",r->name);
2309         freeAsmop(NULL,aop,ic,TRUE);
2310
2311     }
2312 #endif 
2313 }
2314
2315 /*-----------------------------------------------------------------*/
2316 /* saverbank - saves an entire register bank on the stack          */
2317 /*-----------------------------------------------------------------*/
2318 static void saverbank (int bank, iCode *ic, bool pushPsw)
2319 {
2320   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2321 #if 0
2322     int i;
2323     asmop *aop ;
2324     regs *r = NULL;
2325
2326     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2327     if (options.useXstack) {
2328
2329         aop = newAsmop(0);
2330         r = getFreePtr(ic,&aop,FALSE);  
2331         pic14_emitcode("mov","%s,_spx",r->name);
2332
2333     }
2334
2335     for (i = 0 ; i < pic14_nRegs ;i++) {
2336         if (options.useXstack) {
2337             pic14_emitcode("inc","%s",r->name);
2338             //pic14_emitcode("mov","a,(%s+%d)",
2339             //         regspic14[i].base,8*bank+regspic14[i].offset);
2340             pic14_emitcode("movx","@%s,a",r->name);           
2341         } else 
2342           pic14_emitcode("push","");// "(%s+%d)",
2343                      //regspic14[i].base,8*bank+regspic14[i].offset);
2344     }
2345     
2346     if (pushPsw) {
2347         if (options.useXstack) {
2348             pic14_emitcode("mov","a,psw");
2349             pic14_emitcode("movx","@%s,a",r->name);     
2350             pic14_emitcode("inc","%s",r->name);
2351             pic14_emitcode("mov","_spx,%s",r->name);       
2352             freeAsmop (NULL,aop,ic,TRUE);
2353             
2354         } else
2355             pic14_emitcode("push","psw");
2356         
2357         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2358     }
2359     ic->bankSaved = 1;
2360 #endif
2361 }
2362
2363 /*-----------------------------------------------------------------*/
2364 /* genCall - generates a call statement                            */
2365 /*-----------------------------------------------------------------*/
2366 static void genCall (iCode *ic)
2367 {
2368   sym_link *dtype;   
2369
2370   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2371
2372   /* if caller saves & we have not saved then */
2373   if (!ic->regsSaved)
2374     saveRegisters(ic);
2375
2376   /* if we are calling a function that is not using
2377      the same register bank then we need to save the
2378      destination registers on the stack */
2379   dtype = operandType(IC_LEFT(ic));
2380   if (currFunc && dtype && 
2381       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2382       IFFUNC_ISISR(currFunc->type) &&
2383       !ic->bankSaved) 
2384
2385     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2386
2387   /* if send set is not empty the assign */
2388   if (_G.sendSet) {
2389     iCode *sic;
2390     /* For the Pic port, there is no data stack.
2391      * So parameters passed to functions are stored
2392      * in registers. (The pCode optimizer will get
2393      * rid of most of these :).
2394      */
2395     int psuedoStkPtr=-1; 
2396     int firstTimeThruLoop = 1;
2397
2398     _G.sendSet = reverseSet(_G.sendSet);
2399
2400     /* First figure how many parameters are getting passed */
2401     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2402          sic = setNextItem(_G.sendSet)) {
2403
2404       aopOp(IC_LEFT(sic),sic,FALSE);
2405       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2406       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2407     }
2408
2409     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2410          sic = setNextItem(_G.sendSet)) {
2411       int size, offset = 0;
2412
2413       aopOp(IC_LEFT(sic),sic,FALSE);
2414       size = AOP_SIZE(IC_LEFT(sic));
2415
2416       while (size--) {
2417         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2418                              AopType(AOP_TYPE(IC_LEFT(sic))));
2419
2420         if(!firstTimeThruLoop) {
2421           /* If this is not the first time we've been through the loop
2422            * then we need to save the parameter in a temporary
2423            * register. The last byte of the last parameter is
2424            * passed in W. */
2425           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2426
2427         }
2428         firstTimeThruLoop=0;
2429
2430         //if (strcmp(l,fReturn[offset])) {
2431         mov2w (AOP(IC_LEFT(sic)),  offset);
2432 /*
2433         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2434              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2435           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2436         else
2437           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2438 */
2439         //}
2440         offset++;
2441       }
2442       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2443     }
2444     _G.sendSet = NULL;
2445   }
2446   /* make the call */
2447   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2448                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2449                                       OP_SYMBOL(IC_LEFT(ic))->name));
2450
2451   GpsuedoStkPtr=0;
2452   /* if we need assign a result value */
2453   if ((IS_ITEMP(IC_RESULT(ic)) && 
2454        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2455         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2456       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2457
2458     _G.accInUse++;
2459     aopOp(IC_RESULT(ic),ic,FALSE);
2460     _G.accInUse--;
2461
2462     assignResultValue(IC_RESULT(ic));
2463
2464     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2465                          AopType(AOP_TYPE(IC_RESULT(ic))));
2466                 
2467     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2468   }
2469
2470   /* adjust the stack for parameters if 
2471      required */
2472   if (ic->parmBytes) {
2473     int i;
2474     if (ic->parmBytes > 3) {
2475       pic14_emitcode("mov","a,%s",spname);
2476       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2477       pic14_emitcode("mov","%s,a",spname);
2478     } else 
2479       for ( i = 0 ; i <  ic->parmBytes ;i++)
2480         pic14_emitcode("dec","%s",spname);
2481
2482   }
2483
2484   /* if register bank was saved then pop them */
2485   if (ic->bankSaved)
2486     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2487
2488   /* if we hade saved some registers then unsave them */
2489   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2490     unsaveRegisters (ic);
2491
2492
2493 }
2494
2495 /*-----------------------------------------------------------------*/
2496 /* genPcall - generates a call by pointer statement                */
2497 /*-----------------------------------------------------------------*/
2498 static void genPcall (iCode *ic)
2499 {
2500     sym_link *dtype;
2501     symbol *rlbl = newiTempLabel(NULL);
2502
2503
2504     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2505     /* if caller saves & we have not saved then */
2506     if (!ic->regsSaved)
2507         saveRegisters(ic);
2508
2509     /* if we are calling a function that is not using
2510     the same register bank then we need to save the
2511     destination registers on the stack */
2512     dtype = operandType(IC_LEFT(ic));
2513     if (currFunc && dtype && 
2514         IFFUNC_ISISR(currFunc->type) &&
2515         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2516         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2517
2518
2519     /* push the return address on to the stack */
2520     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2521     pic14_emitcode("push","acc");    
2522     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2523     pic14_emitcode("push","acc");
2524     
2525     if (options.model == MODEL_FLAT24)
2526     {
2527         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2528         pic14_emitcode("push","acc");    
2529     }
2530
2531     /* now push the calling address */
2532     aopOp(IC_LEFT(ic),ic,FALSE);
2533
2534     pushSide(IC_LEFT(ic), FPTRSIZE);
2535
2536     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2537
2538     /* if send set is not empty the assign */
2539     if (_G.sendSet) {
2540         iCode *sic ;
2541
2542         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2543              sic = setNextItem(_G.sendSet)) {
2544             int size, offset = 0;
2545             aopOp(IC_LEFT(sic),sic,FALSE);
2546             size = AOP_SIZE(IC_LEFT(sic));
2547             while (size--) {
2548                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2549                                 FALSE,FALSE);
2550                 if (strcmp(l,fReturn[offset]))
2551                     pic14_emitcode("mov","%s,%s",
2552                              fReturn[offset],
2553                              l);
2554                 offset++;
2555             }
2556             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2557         }
2558         _G.sendSet = NULL;
2559     }
2560
2561     pic14_emitcode("ret","");
2562     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2563
2564
2565     /* if we need assign a result value */
2566     if ((IS_ITEMP(IC_RESULT(ic)) &&
2567          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2568           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2569         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2570
2571         _G.accInUse++;
2572         aopOp(IC_RESULT(ic),ic,FALSE);
2573         _G.accInUse--;
2574         
2575         assignResultValue(IC_RESULT(ic));
2576
2577         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2578     }
2579
2580     /* adjust the stack for parameters if 
2581     required */
2582     if (ic->parmBytes) {
2583         int i;
2584         if (ic->parmBytes > 3) {
2585             pic14_emitcode("mov","a,%s",spname);
2586             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2587             pic14_emitcode("mov","%s,a",spname);
2588         } else 
2589             for ( i = 0 ; i <  ic->parmBytes ;i++)
2590                 pic14_emitcode("dec","%s",spname);
2591
2592     }
2593
2594     /* if register bank was saved then unsave them */
2595     if (currFunc && dtype && 
2596         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2597         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2598
2599     /* if we hade saved some registers then
2600     unsave them */
2601     if (ic->regsSaved)
2602         unsaveRegisters (ic);
2603
2604 }
2605
2606 /*-----------------------------------------------------------------*/
2607 /* resultRemat - result  is rematerializable                       */
2608 /*-----------------------------------------------------------------*/
2609 static int resultRemat (iCode *ic)
2610 {
2611   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2612   if (SKIP_IC(ic) || ic->op == IFX)
2613     return 0;
2614
2615   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2616     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2617     if (sym->remat && !POINTER_SET(ic)) 
2618       return 1;
2619   }
2620
2621   return 0;
2622 }
2623
2624 #if defined(__BORLANDC__) || defined(_MSC_VER)
2625 #define STRCASECMP stricmp
2626 #else
2627 #define STRCASECMP strcasecmp
2628 #endif
2629
2630 #if 0
2631 /*-----------------------------------------------------------------*/
2632 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2633 /*-----------------------------------------------------------------*/
2634 static bool inExcludeList(char *s)
2635 {
2636   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2637     int i =0;
2638     
2639     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2640     if (options.excludeRegs[i] &&
2641     STRCASECMP(options.excludeRegs[i],"none") == 0)
2642         return FALSE ;
2643
2644     for ( i = 0 ; options.excludeRegs[i]; i++) {
2645         if (options.excludeRegs[i] &&
2646         STRCASECMP(s,options.excludeRegs[i]) == 0)
2647             return TRUE;
2648     }
2649     return FALSE ;
2650 }
2651 #endif
2652
2653 /*-----------------------------------------------------------------*/
2654 /* genFunction - generated code for function entry                 */
2655 /*-----------------------------------------------------------------*/
2656 static void genFunction (iCode *ic)
2657 {
2658     symbol *sym;
2659     sym_link *ftype;
2660
2661     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2662
2663     labelOffset += (max_key+4);
2664     max_key=0;
2665     GpsuedoStkPtr=0;
2666     _G.nRegsSaved = 0;
2667     /* create the function header */
2668     pic14_emitcode(";","-----------------------------------------");
2669     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2670     pic14_emitcode(";","-----------------------------------------");
2671
2672     pic14_emitcode("","%s:",sym->rname);
2673     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2674
2675     ftype = operandType(IC_LEFT(ic));
2676
2677     /* if critical function then turn interrupts off */
2678     if (IFFUNC_ISCRITICAL(ftype))
2679         pic14_emitcode("clr","ea");
2680
2681     /* here we need to generate the equates for the
2682        register bank if required */
2683 #if 0
2684     if (FUNC_REGBANK(ftype) != rbank) {
2685         int i ;
2686
2687         rbank = FUNC_REGBANK(ftype);
2688         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2689             if (strcmp(regspic14[i].base,"0") == 0)
2690                 pic14_emitcode("","%s = 0x%02x",
2691                          regspic14[i].dname,
2692                          8*rbank+regspic14[i].offset);
2693             else
2694                 pic14_emitcode ("","%s = %s + 0x%02x",
2695                           regspic14[i].dname,
2696                           regspic14[i].base,
2697                           8*rbank+regspic14[i].offset);
2698         }
2699     }
2700 #endif
2701
2702     /* if this is an interrupt service routine then
2703     save acc, b, dpl, dph  */
2704     if (IFFUNC_ISISR(sym->type)) {
2705       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2706       emitpcodeNULLop(POC_NOP);
2707       emitpcodeNULLop(POC_NOP);
2708       emitpcodeNULLop(POC_NOP);
2709       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2710       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2711       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2712       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2713
2714       pBlockConvert2ISR(pb);
2715 #if 0  
2716         if (!inExcludeList("acc"))          
2717             pic14_emitcode ("push","acc");      
2718         if (!inExcludeList("b"))
2719             pic14_emitcode ("push","b");
2720         if (!inExcludeList("dpl"))
2721             pic14_emitcode ("push","dpl");
2722         if (!inExcludeList("dph"))
2723             pic14_emitcode ("push","dph");
2724         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2725         {
2726             pic14_emitcode ("push", "dpx");
2727             /* Make sure we're using standard DPTR */
2728             pic14_emitcode ("push", "dps");
2729             pic14_emitcode ("mov", "dps, #0x00");
2730             if (options.stack10bit)
2731             {   
2732                 /* This ISR could conceivably use DPTR2. Better save it. */
2733                 pic14_emitcode ("push", "dpl1");
2734                 pic14_emitcode ("push", "dph1");
2735                 pic14_emitcode ("push", "dpx1");
2736             }
2737         }
2738         /* if this isr has no bank i.e. is going to
2739            run with bank 0 , then we need to save more
2740            registers :-) */
2741         if (!FUNC_REGBANK(sym->type)) {
2742
2743             /* if this function does not call any other
2744                function then we can be economical and
2745                save only those registers that are used */
2746             if (! IFFUNC_HASFCALL(sym->type)) {
2747                 int i;
2748
2749                 /* if any registers used */
2750                 if (sym->regsUsed) {
2751                     /* save the registers used */
2752                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2753                         if (bitVectBitValue(sym->regsUsed,i) ||
2754                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2755                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2756                     }
2757                 }
2758                 
2759             } else {
2760                 /* this function has  a function call cannot
2761                    determines register usage so we will have the
2762                    entire bank */
2763                 saverbank(0,ic,FALSE);
2764             }       
2765         }
2766 #endif
2767     } else {
2768         /* if callee-save to be used for this function
2769            then save the registers being used in this function */
2770         if (IFFUNC_CALLEESAVES(sym->type)) {
2771             int i;
2772             
2773             /* if any registers used */
2774             if (sym->regsUsed) {
2775                 /* save the registers used */
2776                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2777                     if (bitVectBitValue(sym->regsUsed,i) ||
2778                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2779                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2780                         _G.nRegsSaved++;
2781                     }
2782                 }
2783             }
2784         }
2785     }
2786
2787     /* set the register bank to the desired value */
2788     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2789         pic14_emitcode("push","psw");
2790         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2791     }
2792
2793     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2794
2795         if (options.useXstack) {
2796             pic14_emitcode("mov","r0,%s",spname);
2797             pic14_emitcode("mov","a,_bp");
2798             pic14_emitcode("movx","@r0,a");
2799             pic14_emitcode("inc","%s",spname);
2800         }
2801         else
2802         {
2803             /* set up the stack */
2804             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2805         }
2806         pic14_emitcode ("mov","_bp,%s",spname);
2807     }
2808
2809     /* adjust the stack for the function */
2810     if (sym->stack) {
2811
2812         int i = sym->stack;
2813         if (i > 256 ) 
2814             werror(W_STACK_OVERFLOW,sym->name);
2815
2816         if (i > 3 && sym->recvSize < 4) {              
2817
2818             pic14_emitcode ("mov","a,sp");
2819             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2820             pic14_emitcode ("mov","sp,a");
2821            
2822         }
2823         else
2824             while(i--)
2825                 pic14_emitcode("inc","sp");
2826     }
2827
2828      if (sym->xstack) {
2829
2830         pic14_emitcode ("mov","a,_spx");
2831         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2832         pic14_emitcode ("mov","_spx,a");
2833     }    
2834
2835 }
2836
2837 /*-----------------------------------------------------------------*/
2838 /* genEndFunction - generates epilogue for functions               */
2839 /*-----------------------------------------------------------------*/
2840 static void genEndFunction (iCode *ic)
2841 {
2842     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2843
2844     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2845
2846     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2847     {
2848         pic14_emitcode ("mov","%s,_bp",spname);
2849     }
2850
2851     /* if use external stack but some variables were
2852     added to the local stack then decrement the
2853     local stack */
2854     if (options.useXstack && sym->stack) {      
2855         pic14_emitcode("mov","a,sp");
2856         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2857         pic14_emitcode("mov","sp,a");
2858     }
2859
2860
2861     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2862         if (options.useXstack) {
2863             pic14_emitcode("mov","r0,%s",spname);
2864             pic14_emitcode("movx","a,@r0");
2865             pic14_emitcode("mov","_bp,a");
2866             pic14_emitcode("dec","%s",spname);
2867         }
2868         else
2869         {
2870             pic14_emitcode ("pop","_bp");
2871         }
2872     }
2873
2874     /* restore the register bank  */    
2875     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2876         pic14_emitcode ("pop","psw");
2877
2878     if (IFFUNC_ISISR(sym->type)) {
2879
2880         /* now we need to restore the registers */
2881         /* if this isr has no bank i.e. is going to
2882            run with bank 0 , then we need to save more
2883            registers :-) */
2884         if (!FUNC_REGBANK(sym->type)) {
2885             
2886             /* if this function does not call any other
2887                function then we can be economical and
2888                save only those registers that are used */
2889             if (! IFFUNC_HASFCALL(sym->type)) {
2890                 int i;
2891                 
2892                 /* if any registers used */
2893                 if (sym->regsUsed) {
2894                     /* save the registers used */
2895                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2896                         if (bitVectBitValue(sym->regsUsed,i) ||
2897                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2898                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2899                     }
2900                 }
2901                 
2902             } else {
2903                 /* this function has  a function call cannot
2904                    determines register usage so we will have the
2905                    entire bank */
2906                 unsaverbank(0,ic,FALSE);
2907             }       
2908         }
2909 #if 0
2910         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2911         {
2912             if (options.stack10bit)
2913             {
2914                 pic14_emitcode ("pop", "dpx1");
2915                 pic14_emitcode ("pop", "dph1");
2916                 pic14_emitcode ("pop", "dpl1");
2917             }   
2918             pic14_emitcode ("pop", "dps");
2919             pic14_emitcode ("pop", "dpx");
2920         }
2921         if (!inExcludeList("dph"))
2922             pic14_emitcode ("pop","dph");
2923         if (!inExcludeList("dpl"))
2924             pic14_emitcode ("pop","dpl");
2925         if (!inExcludeList("b"))
2926             pic14_emitcode ("pop","b");
2927         if (!inExcludeList("acc"))
2928             pic14_emitcode ("pop","acc");
2929
2930         if (IFFUNC_ISCRITICAL(sym->type))
2931             pic14_emitcode("setb","ea");
2932 #endif
2933
2934         /* if debug then send end of function */
2935 /*      if (options.debug && currFunc) { */
2936         if (currFunc) {
2937             _G.debugLine = 1;
2938             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2939                      FileBaseName(ic->filename),currFunc->lastLine,
2940                      ic->level,ic->block); 
2941             if (IS_STATIC(currFunc->etype))         
2942                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2943             else
2944                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2945             _G.debugLine = 0;
2946         }
2947         
2948         pic14_emitcode ("reti","");
2949
2950         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2951         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2952         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2953         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2954         emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
2955         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2956
2957         emitpcodeNULLop(POC_RETFIE);
2958
2959     }
2960     else {
2961         if (IFFUNC_ISCRITICAL(sym->type))
2962             pic14_emitcode("setb","ea");
2963         
2964         if (IFFUNC_CALLEESAVES(sym->type)) {
2965             int i;
2966             
2967             /* if any registers used */
2968             if (sym->regsUsed) {
2969                 /* save the registers used */
2970                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2971                     if (bitVectBitValue(sym->regsUsed,i) ||
2972                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2973                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2974                 }
2975             }
2976             
2977         }
2978
2979         /* if debug then send end of function */
2980         if (currFunc) {
2981             _G.debugLine = 1;
2982             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2983                      FileBaseName(ic->filename),currFunc->lastLine,
2984                      ic->level,ic->block); 
2985             if (IS_STATIC(currFunc->etype))         
2986                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2987             else
2988                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2989             _G.debugLine = 0;
2990         }
2991
2992         pic14_emitcode ("return","");
2993         emitpcodeNULLop(POC_RETURN);
2994
2995         /* Mark the end of a function */
2996         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2997     }
2998
2999 }
3000
3001 /*-----------------------------------------------------------------*/
3002 /* genRet - generate code for return statement                     */
3003 /*-----------------------------------------------------------------*/
3004 static void genRet (iCode *ic)
3005 {
3006   int size,offset = 0 , pushed = 0;
3007     
3008   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3009   /* if we have no return value then
3010      just generate the "ret" */
3011   if (!IC_LEFT(ic)) 
3012     goto jumpret;       
3013     
3014   /* we have something to return then
3015      move the return value into place */
3016   aopOp(IC_LEFT(ic),ic,FALSE);
3017   size = AOP_SIZE(IC_LEFT(ic));
3018     
3019   while (size--) {
3020     char *l ;
3021     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3022       /* #NOCHANGE */
3023       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3024                  FALSE,TRUE);
3025       pic14_emitcode("push","%s",l);
3026       pushed++;
3027     } else {
3028       l = aopGet(AOP(IC_LEFT(ic)),offset,
3029                  FALSE,FALSE);
3030       if (strcmp(fReturn[offset],l)) {
3031         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3032             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3033           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3034         }else {
3035           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3036         }
3037         if(size) {
3038           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3039         }
3040         offset++;
3041       }
3042     }
3043   }    
3044
3045   if (pushed) {
3046     while(pushed) {
3047       pushed--;
3048       if (strcmp(fReturn[pushed],"a"))
3049         pic14_emitcode("pop",fReturn[pushed]);
3050       else
3051         pic14_emitcode("pop","acc");
3052     }
3053   }
3054   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3055     
3056  jumpret:
3057   /* generate a jump to the return label
3058      if the next is not the return statement */
3059   if (!(ic->next && ic->next->op == LABEL &&
3060         IC_LABEL(ic->next) == returnLabel)) {
3061         
3062     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3063     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3064   }
3065     
3066 }
3067
3068 /*-----------------------------------------------------------------*/
3069 /* genLabel - generates a label                                    */
3070 /*-----------------------------------------------------------------*/
3071 static void genLabel (iCode *ic)
3072 {
3073     /* special case never generate */
3074     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3075     if (IC_LABEL(ic) == entryLabel)
3076         return ;
3077
3078     emitpLabel(IC_LABEL(ic)->key);
3079     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3080 }
3081
3082 /*-----------------------------------------------------------------*/
3083 /* genGoto - generates a goto                                      */
3084 /*-----------------------------------------------------------------*/
3085 //tsd
3086 static void genGoto (iCode *ic)
3087 {
3088   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3089   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3090 }
3091
3092
3093 /*-----------------------------------------------------------------*/
3094 /* genMultbits :- multiplication of bits                           */
3095 /*-----------------------------------------------------------------*/
3096 static void genMultbits (operand *left, 
3097                          operand *right, 
3098                          operand *result)
3099 {
3100   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3101
3102   if(!pic14_sameRegs(AOP(result),AOP(right)))
3103     emitpcode(POC_BSF,  popGet(AOP(result),0));
3104
3105   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3106   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3107   emitpcode(POC_BCF,  popGet(AOP(result),0));
3108
3109 }
3110
3111
3112 /*-----------------------------------------------------------------*/
3113 /* genMultOneByte : 8 bit multiplication & division                */
3114 /*-----------------------------------------------------------------*/
3115 static void genMultOneByte (operand *left,
3116                             operand *right,
3117                             operand *result)
3118 {
3119   sym_link *opetype = operandType(result);
3120
3121   // symbol *lbl ;
3122   int size,offset;
3123
3124   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3125   DEBUGpic14_AopType(__LINE__,left,right,result);
3126   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3127
3128   /* (if two literals, the value is computed before) */
3129   /* if one literal, literal on the right */
3130   if (AOP_TYPE(left) == AOP_LIT){
3131     operand *t = right;
3132     right = left;
3133     left = t;
3134   }
3135
3136   size = AOP_SIZE(result);
3137   if(size == 1) {
3138
3139     if (AOP_TYPE(right) == AOP_LIT){
3140       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3141                      aopGet(AOP(right),0,FALSE,FALSE), 
3142                      aopGet(AOP(left),0,FALSE,FALSE), 
3143                      aopGet(AOP(result),0,FALSE,FALSE));
3144       pic14_emitcode("call","genMultLit");
3145     } else {
3146       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3147                      aopGet(AOP(right),0,FALSE,FALSE), 
3148                      aopGet(AOP(left),0,FALSE,FALSE), 
3149                      aopGet(AOP(result),0,FALSE,FALSE));
3150       pic14_emitcode("call","genMult8X8_8");
3151
3152     }
3153     genMult8X8_8 (left, right,result);
3154
3155
3156     /* signed or unsigned */
3157     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3158     //l = aopGet(AOP(left),0,FALSE,FALSE);
3159     //MOVA(l);       
3160     //pic14_emitcode("mul","ab");
3161     /* if result size = 1, mul signed = mul unsigned */
3162     //aopPut(AOP(result),"a",0);
3163
3164   } else {  // (size > 1)
3165
3166     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3167                    aopGet(AOP(right),0,FALSE,FALSE), 
3168                    aopGet(AOP(left),0,FALSE,FALSE), 
3169                    aopGet(AOP(result),0,FALSE,FALSE));
3170
3171     if (SPEC_USIGN(opetype)){
3172       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3173       genUMult8X8_16 (left, right, result, NULL);
3174
3175       if (size > 2) {
3176         /* for filling the MSBs */
3177         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3178         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3179       }
3180     }
3181     else{
3182       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3183
3184       pic14_emitcode("mov","a,b");
3185
3186       /* adjust the MSB if left or right neg */
3187
3188       /* if one literal */
3189       if (AOP_TYPE(right) == AOP_LIT){
3190         pic14_emitcode("multiply ","right is a lit");
3191         /* AND literal negative */
3192         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3193           /* adjust MSB (c==0 after mul) */
3194           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3195         }
3196       }
3197       else{
3198         genSMult8X8_16 (left, right, result, NULL);
3199       }
3200
3201       if(size > 2){
3202         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3203         /* get the sign */
3204         pic14_emitcode("rlc","a");
3205         pic14_emitcode("subb","a,acc");
3206       }
3207     }
3208
3209     size -= 2;   
3210     offset = 2;
3211     if (size > 0)
3212       while (size--)
3213         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3214     //aopPut(AOP(result),"a",offset++);
3215   }
3216 }
3217
3218 /*-----------------------------------------------------------------*/
3219 /* genMult - generates code for multiplication                     */
3220 /*-----------------------------------------------------------------*/
3221 static void genMult (iCode *ic)
3222 {
3223     operand *left = IC_LEFT(ic);
3224     operand *right = IC_RIGHT(ic);
3225     operand *result= IC_RESULT(ic);   
3226
3227     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3228     /* assign the amsops */
3229     aopOp (left,ic,FALSE);
3230     aopOp (right,ic,FALSE);
3231     aopOp (result,ic,TRUE);
3232
3233   DEBUGpic14_AopType(__LINE__,left,right,result);
3234
3235     /* special cases first */
3236     /* both are bits */
3237     if (AOP_TYPE(left) == AOP_CRY &&
3238         AOP_TYPE(right)== AOP_CRY) {
3239         genMultbits(left,right,result);
3240         goto release ;
3241     }
3242
3243     /* if both are of size == 1 */
3244     if (AOP_SIZE(left) == 1 &&
3245         AOP_SIZE(right) == 1 ) {
3246         genMultOneByte(left,right,result);
3247         goto release ;
3248     }
3249
3250     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3251
3252     /* should have been converted to function call */
3253     //assert(0) ;
3254
3255 release :
3256     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3257     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258     freeAsmop(result,NULL,ic,TRUE); 
3259 }
3260
3261 /*-----------------------------------------------------------------*/
3262 /* genDivbits :- division of bits                                  */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivbits (operand *left, 
3265                         operand *right, 
3266                         operand *result)
3267 {
3268
3269     char *l;
3270
3271     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3272     /* the result must be bit */    
3273     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3274     l = aopGet(AOP(left),0,FALSE,FALSE);
3275
3276     MOVA(l);    
3277
3278     pic14_emitcode("div","ab");
3279     pic14_emitcode("rrc","a");
3280     aopPut(AOP(result),"c",0);
3281 }
3282
3283 /*-----------------------------------------------------------------*/
3284 /* genDivOneByte : 8 bit division                                  */
3285 /*-----------------------------------------------------------------*/
3286 static void genDivOneByte (operand *left,
3287                            operand *right,
3288                            operand *result)
3289 {
3290     sym_link *opetype = operandType(result);
3291     char *l ;
3292     symbol *lbl ;
3293     int size,offset;
3294
3295     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3296     size = AOP_SIZE(result) - 1;
3297     offset = 1;
3298     /* signed or unsigned */
3299     if (SPEC_USIGN(opetype)) {
3300         /* unsigned is easy */
3301         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3302         l = aopGet(AOP(left),0,FALSE,FALSE);
3303         MOVA(l);        
3304         pic14_emitcode("div","ab");
3305         aopPut(AOP(result),"a",0);
3306         while (size--)
3307             aopPut(AOP(result),zero,offset++);
3308         return ;
3309     }
3310
3311     /* signed is a little bit more difficult */
3312
3313     /* save the signs of the operands */
3314     l = aopGet(AOP(left),0,FALSE,FALSE);    
3315     MOVA(l);    
3316     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3317     pic14_emitcode("push","acc"); /* save it on the stack */
3318
3319     /* now sign adjust for both left & right */
3320     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3321     MOVA(l);       
3322     lbl = newiTempLabel(NULL);
3323     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3324     pic14_emitcode("cpl","a");   
3325     pic14_emitcode("inc","a");
3326     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3327     pic14_emitcode("mov","b,a");
3328
3329     /* sign adjust left side */
3330     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3331     MOVA(l);
3332
3333     lbl = newiTempLabel(NULL);
3334     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3335     pic14_emitcode("cpl","a");
3336     pic14_emitcode("inc","a");
3337     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3338
3339     /* now the division */
3340     pic14_emitcode("div","ab");
3341     /* we are interested in the lower order
3342     only */
3343     pic14_emitcode("mov","b,a");
3344     lbl = newiTempLabel(NULL);
3345     pic14_emitcode("pop","acc");   
3346     /* if there was an over flow we don't 
3347     adjust the sign of the result */
3348     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3349     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3350     CLRC;
3351     pic14_emitcode("clr","a");
3352     pic14_emitcode("subb","a,b");
3353     pic14_emitcode("mov","b,a");
3354     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3355
3356     /* now we are done */
3357     aopPut(AOP(result),"b",0);
3358     if(size > 0){
3359         pic14_emitcode("mov","c,b.7");
3360         pic14_emitcode("subb","a,acc");   
3361     }
3362     while (size--)
3363         aopPut(AOP(result),"a",offset++);
3364
3365 }
3366
3367 /*-----------------------------------------------------------------*/
3368 /* genDiv - generates code for division                            */
3369 /*-----------------------------------------------------------------*/
3370 static void genDiv (iCode *ic)
3371 {
3372     operand *left = IC_LEFT(ic);
3373     operand *right = IC_RIGHT(ic);
3374     operand *result= IC_RESULT(ic);   
3375
3376     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3377     /* assign the amsops */
3378     aopOp (left,ic,FALSE);
3379     aopOp (right,ic,FALSE);
3380     aopOp (result,ic,TRUE);
3381
3382     /* special cases first */
3383     /* both are bits */
3384     if (AOP_TYPE(left) == AOP_CRY &&
3385         AOP_TYPE(right)== AOP_CRY) {
3386         genDivbits(left,right,result);
3387         goto release ;
3388     }
3389
3390     /* if both are of size == 1 */
3391     if (AOP_SIZE(left) == 1 &&
3392         AOP_SIZE(right) == 1 ) {
3393         genDivOneByte(left,right,result);
3394         goto release ;
3395     }
3396
3397     /* should have been converted to function call */
3398     assert(0);
3399 release :
3400     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3401     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402     freeAsmop(result,NULL,ic,TRUE); 
3403 }
3404
3405 /*-----------------------------------------------------------------*/
3406 /* genModbits :- modulus of bits                                   */
3407 /*-----------------------------------------------------------------*/
3408 static void genModbits (operand *left, 
3409                         operand *right, 
3410                         operand *result)
3411 {
3412
3413     char *l;
3414
3415     /* the result must be bit */    
3416     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3417     l = aopGet(AOP(left),0,FALSE,FALSE);
3418
3419     MOVA(l);       
3420
3421     pic14_emitcode("div","ab");
3422     pic14_emitcode("mov","a,b");
3423     pic14_emitcode("rrc","a");
3424     aopPut(AOP(result),"c",0);
3425 }
3426
3427 /*-----------------------------------------------------------------*/
3428 /* genModOneByte : 8 bit modulus                                   */
3429 /*-----------------------------------------------------------------*/
3430 static void genModOneByte (operand *left,
3431                            operand *right,
3432                            operand *result)
3433 {
3434     sym_link *opetype = operandType(result);
3435     char *l ;
3436     symbol *lbl ;
3437
3438     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3439     /* signed or unsigned */
3440     if (SPEC_USIGN(opetype)) {
3441         /* unsigned is easy */
3442         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3443         l = aopGet(AOP(left),0,FALSE,FALSE);
3444         MOVA(l);    
3445         pic14_emitcode("div","ab");
3446         aopPut(AOP(result),"b",0);
3447         return ;
3448     }
3449
3450     /* signed is a little bit more difficult */
3451
3452     /* save the signs of the operands */
3453     l = aopGet(AOP(left),0,FALSE,FALSE);    
3454     MOVA(l);
3455
3456     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3457     pic14_emitcode("push","acc"); /* save it on the stack */
3458
3459     /* now sign adjust for both left & right */
3460     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3461     MOVA(l);
3462
3463     lbl = newiTempLabel(NULL);
3464     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3465     pic14_emitcode("cpl","a");   
3466     pic14_emitcode("inc","a");
3467     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3468     pic14_emitcode("mov","b,a"); 
3469
3470     /* sign adjust left side */
3471     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3472     MOVA(l);
3473
3474     lbl = newiTempLabel(NULL);
3475     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3476     pic14_emitcode("cpl","a");   
3477     pic14_emitcode("inc","a");
3478     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3479
3480     /* now the multiplication */
3481     pic14_emitcode("div","ab");
3482     /* we are interested in the lower order
3483     only */
3484     lbl = newiTempLabel(NULL);
3485     pic14_emitcode("pop","acc");   
3486     /* if there was an over flow we don't 
3487     adjust the sign of the result */
3488     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3489     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3490     CLRC ;
3491     pic14_emitcode("clr","a");
3492     pic14_emitcode("subb","a,b");
3493     pic14_emitcode("mov","b,a");
3494     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3495
3496     /* now we are done */
3497     aopPut(AOP(result),"b",0);
3498
3499 }
3500
3501 /*-----------------------------------------------------------------*/
3502 /* genMod - generates code for division                            */
3503 /*-----------------------------------------------------------------*/
3504 static void genMod (iCode *ic)
3505 {
3506     operand *left = IC_LEFT(ic);
3507     operand *right = IC_RIGHT(ic);
3508     operand *result= IC_RESULT(ic);  
3509
3510     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3511     /* assign the amsops */
3512     aopOp (left,ic,FALSE);
3513     aopOp (right,ic,FALSE);
3514     aopOp (result,ic,TRUE);
3515
3516     /* special cases first */
3517     /* both are bits */
3518     if (AOP_TYPE(left) == AOP_CRY &&
3519         AOP_TYPE(right)== AOP_CRY) {
3520         genModbits(left,right,result);
3521         goto release ;
3522     }
3523
3524     /* if both are of size == 1 */
3525     if (AOP_SIZE(left) == 1 &&
3526         AOP_SIZE(right) == 1 ) {
3527         genModOneByte(left,right,result);
3528         goto release ;
3529     }
3530
3531     /* should have been converted to function call */
3532     assert(0);
3533
3534 release :
3535     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3536     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537     freeAsmop(result,NULL,ic,TRUE); 
3538 }
3539
3540 /*-----------------------------------------------------------------*/
3541 /* genIfxJump :- will create a jump depending on the ifx           */
3542 /*-----------------------------------------------------------------*/
3543 /*
3544   note: May need to add parameter to indicate when a variable is in bit space.
3545 */
3546 static void genIfxJump (iCode *ic, char *jval)
3547 {
3548
3549     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3550     /* if true label then we jump if condition
3551     supplied is true */
3552     if ( IC_TRUE(ic) ) {
3553
3554         if(strcmp(jval,"a") == 0)
3555           emitSKPZ;
3556         else if (strcmp(jval,"c") == 0)
3557           emitSKPC;
3558         else {
3559           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3560           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3561         }
3562
3563         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3564         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3565
3566     }
3567     else {
3568         /* false label is present */
3569         if(strcmp(jval,"a") == 0)
3570           emitSKPNZ;
3571         else if (strcmp(jval,"c") == 0)
3572           emitSKPNC;
3573         else {
3574           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3575           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3576         }
3577
3578         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3579         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3580
3581     }
3582
3583
3584     /* mark the icode as generated */
3585     ic->generated = 1;
3586 }
3587
3588 /*-----------------------------------------------------------------*/
3589 /* genSkip                                                         */
3590 /*-----------------------------------------------------------------*/
3591 static void genSkip(iCode *ifx,int status_bit)
3592 {
3593   if(!ifx)
3594     return;
3595
3596   if ( IC_TRUE(ifx) ) {
3597     switch(status_bit) {
3598     case 'z':
3599       emitSKPNZ;
3600       break;
3601
3602     case 'c':
3603       emitSKPNC;
3604       break;
3605
3606     case 'd':
3607       emitSKPDC;
3608       break;
3609
3610     }
3611
3612     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3613     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3614
3615   } else {
3616
3617     switch(status_bit) {
3618
3619     case 'z':
3620       emitSKPZ;
3621       break;
3622
3623     case 'c':
3624       emitSKPC;
3625       break;
3626
3627     case 'd':
3628       emitSKPDC;
3629       break;
3630     }
3631     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3632     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3633
3634   }
3635
3636 }
3637
3638 /*-----------------------------------------------------------------*/
3639 /* genSkipc                                                        */
3640 /*-----------------------------------------------------------------*/
3641 static void genSkipc(resolvedIfx *rifx)
3642 {
3643   if(!rifx)
3644     return;
3645
3646   if(rifx->condition)
3647     emitSKPC;
3648   else
3649     emitSKPNC;
3650
3651   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3652   rifx->generated = 1;
3653 }
3654
3655 /*-----------------------------------------------------------------*/
3656 /* genSkipz2                                                       */
3657 /*-----------------------------------------------------------------*/
3658 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3659 {
3660   if(!rifx)
3661     return;
3662
3663   if( (rifx->condition ^ invert_condition) & 1)
3664     emitSKPZ;
3665   else
3666     emitSKPNZ;
3667
3668   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3669   rifx->generated = 1;
3670 }
3671
3672 /*-----------------------------------------------------------------*/
3673 /* genSkipz                                                        */
3674 /*-----------------------------------------------------------------*/
3675 static void genSkipz(iCode *ifx, int condition)
3676 {
3677   if(!ifx)
3678     return;
3679
3680   if(condition)
3681     emitSKPNZ;
3682   else
3683     emitSKPZ;
3684
3685   if ( IC_TRUE(ifx) )
3686     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3687   else
3688     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3689
3690   if ( IC_TRUE(ifx) )
3691     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3692   else
3693     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3694
3695 }
3696 /*-----------------------------------------------------------------*/
3697 /* genSkipCond                                                     */
3698 /*-----------------------------------------------------------------*/
3699 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3700 {
3701   if(!rifx)
3702     return;
3703
3704   if(rifx->condition)
3705     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3706   else
3707     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3708
3709
3710   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3711   rifx->generated = 1;
3712 }
3713
3714 #if 0
3715 /*-----------------------------------------------------------------*/
3716 /* genChkZeroes :- greater or less than comparison                 */
3717 /*     For each byte in a literal that is zero, inclusive or the   */
3718 /*     the corresponding byte in the operand with W                */
3719 /*     returns true if any of the bytes are zero                   */
3720 /*-----------------------------------------------------------------*/
3721 static int genChkZeroes(operand *op, int lit,  int size)
3722 {
3723
3724   int i;
3725   int flag =1;
3726
3727   while(size--) {
3728     i = (lit >> (size*8)) & 0xff;
3729
3730     if(i==0) {
3731       if(flag) 
3732         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3733       else
3734         emitpcode(POC_IORFW, popGet(AOP(op),size));
3735       flag = 0;
3736     }
3737   }
3738
3739   return (flag==0);
3740 }
3741 #endif
3742
3743 /*-----------------------------------------------------------------*/
3744 /* genCmp :- greater or less than comparison                       */
3745 /*-----------------------------------------------------------------*/
3746 static void genCmp (operand *left,operand *right,
3747                     operand *result, iCode *ifx, int sign)
3748 {
3749   int size; //, offset = 0 ;
3750   unsigned long lit = 0L,i = 0;
3751   resolvedIfx rFalseIfx;
3752   //  resolvedIfx rTrueIfx;
3753   symbol *truelbl;
3754   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3755 /*
3756   if(ifx) {
3757     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3758     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3759   }
3760 */
3761
3762   resolveIfx(&rFalseIfx,ifx);
3763   truelbl  = newiTempLabel(NULL);
3764   size = max(AOP_SIZE(left),AOP_SIZE(right));
3765
3766 #define _swapp
3767
3768   /* if literal is on the right then swap with left */
3769   if ((AOP_TYPE(right) == AOP_LIT)) {
3770     operand *tmp = right ;
3771     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3772     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3773 #ifdef _swapp
3774
3775     lit = (lit - 1) & mask;
3776     right = left;
3777     left = tmp;
3778     rFalseIfx.condition ^= 1;
3779 #endif
3780
3781   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3782     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3783   }
3784
3785
3786   //if(IC_TRUE(ifx) == NULL)
3787   /* if left & right are bit variables */
3788   if (AOP_TYPE(left) == AOP_CRY &&
3789       AOP_TYPE(right) == AOP_CRY ) {
3790     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3791     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3792   } else {
3793     /* subtract right from left if at the
3794        end the carry flag is set then we know that
3795        left is greater than right */
3796
3797     //    {
3798
3799     symbol *lbl  = newiTempLabel(NULL);
3800
3801 #ifndef _swapp
3802     if(AOP_TYPE(right) == AOP_LIT) {
3803
3804       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3805
3806       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3807
3808       /* special cases */
3809
3810       if(lit == 0) {
3811
3812         if(sign != 0) 
3813           genSkipCond(&rFalseIfx,left,size-1,7);
3814         else 
3815           /* no need to compare to 0...*/
3816           /* NOTE: this is a de-generate compare that most certainly 
3817            *       creates some dead code. */
3818           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3819
3820         if(ifx) ifx->generated = 1;
3821         return;
3822
3823       }
3824       size--;
3825
3826       if(size == 0) {
3827         //i = (lit >> (size*8)) & 0xff;
3828         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3829         
3830         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3831
3832         i = ((0-lit) & 0xff);
3833         if(sign) {
3834           if( i == 0x81) { 
3835             /* lit is 0x7f, all signed chars are less than
3836              * this except for 0x7f itself */
3837             emitpcode(POC_XORLW, popGetLit(0x7f));
3838             genSkipz2(&rFalseIfx,0);
3839           } else {
3840             emitpcode(POC_ADDLW, popGetLit(0x80));
3841             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3842             genSkipc(&rFalseIfx);
3843           }
3844
3845         } else {
3846           if(lit == 1) {
3847             genSkipz2(&rFalseIfx,1);
3848           } else {
3849             emitpcode(POC_ADDLW, popGetLit(i));
3850             genSkipc(&rFalseIfx);
3851           }
3852         }
3853
3854         if(ifx) ifx->generated = 1;
3855         return;
3856       }
3857
3858       /* chars are out of the way. now do ints and longs */
3859
3860
3861       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3862         
3863       /* special cases */
3864
3865       if(sign) {
3866
3867         if(lit == 0) {
3868           genSkipCond(&rFalseIfx,left,size,7);
3869           if(ifx) ifx->generated = 1;
3870           return;
3871         }
3872
3873         if(lit <0x100) {
3874           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3875
3876           //rFalseIfx.condition ^= 1;
3877           //genSkipCond(&rFalseIfx,left,size,7);
3878           //rFalseIfx.condition ^= 1;
3879
3880           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3881           if(rFalseIfx.condition)
3882             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3883           else
3884             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3885
3886           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3887           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3888           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3889
3890           while(size > 1)
3891             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3892
3893           if(rFalseIfx.condition) {
3894             emitSKPZ;
3895             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3896
3897           } else {
3898             emitSKPNZ;
3899           }
3900
3901           genSkipc(&rFalseIfx);
3902           emitpLabel(truelbl->key);
3903           if(ifx) ifx->generated = 1;
3904           return;
3905
3906         }
3907
3908         if(size == 1) {
3909
3910           if( (lit & 0xff) == 0) {
3911             /* lower byte is zero */
3912             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3913             i = ((lit >> 8) & 0xff) ^0x80;
3914             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3915             emitpcode(POC_ADDLW, popGetLit( 0x80));
3916             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3917             genSkipc(&rFalseIfx);
3918
3919
3920             if(ifx) ifx->generated = 1;
3921             return;
3922
3923           }
3924         } else {
3925           /* Special cases for signed longs */
3926           if( (lit & 0xffffff) == 0) {
3927             /* lower byte is zero */
3928             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3929             i = ((lit >> 8*3) & 0xff) ^0x80;
3930             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3931             emitpcode(POC_ADDLW, popGetLit( 0x80));
3932             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3933             genSkipc(&rFalseIfx);
3934
3935
3936             if(ifx) ifx->generated = 1;
3937             return;
3938
3939           }
3940
3941         }
3942
3943
3944         if(lit & (0x80 << (size*8))) {
3945           /* lit is negative */
3946           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3947
3948           //genSkipCond(&rFalseIfx,left,size,7);
3949
3950           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3951
3952           if(rFalseIfx.condition)
3953             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3954           else
3955             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3956
3957
3958         } else {
3959           /* lit is positive */
3960           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3961           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3962           if(rFalseIfx.condition)
3963             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3964           else
3965             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3966
3967         }
3968
3969         /*
3970           This works, but is only good for ints.
3971           It also requires a "known zero" register.
3972           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3973           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3974           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3975           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3976           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3977           genSkipc(&rFalseIfx);
3978
3979           emitpLabel(truelbl->key);
3980           if(ifx) ifx->generated = 1;
3981           return;
3982         **/
3983           
3984         /* There are no more special cases, so perform a general compare */
3985   
3986         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3987         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3988
3989         while(size--) {
3990
3991           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3992           emitSKPNZ;
3993           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3994         }
3995         //rFalseIfx.condition ^= 1;
3996         genSkipc(&rFalseIfx);
3997
3998         emitpLabel(truelbl->key);
3999
4000         if(ifx) ifx->generated = 1;
4001         return;
4002
4003
4004       }
4005
4006
4007       /* sign is out of the way. So now do an unsigned compare */
4008       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4009
4010
4011       /* General case - compare to an unsigned literal on the right.*/
4012
4013       i = (lit >> (size*8)) & 0xff;
4014       emitpcode(POC_MOVLW, popGetLit(i));
4015       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4016       while(size--) {
4017         i = (lit >> (size*8)) & 0xff;
4018
4019         if(i) {
4020           emitpcode(POC_MOVLW, popGetLit(i));
4021           emitSKPNZ;
4022           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4023         } else {
4024           /* this byte of the lit is zero, 
4025            *if it's not the last then OR in the variable */
4026           if(size)
4027             emitpcode(POC_IORFW, popGet(AOP(left),size));
4028         }
4029       }
4030
4031
4032       emitpLabel(lbl->key);
4033       //if(emitFinalCheck)
4034       genSkipc(&rFalseIfx);
4035       if(sign)
4036         emitpLabel(truelbl->key);
4037
4038       if(ifx) ifx->generated = 1;
4039       return;
4040
4041
4042     }
4043 #endif
4044     if(AOP_TYPE(left) == AOP_LIT) {
4045       //symbol *lbl = newiTempLabel(NULL);
4046
4047       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4048
4049
4050       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4051
4052       /* Special cases */
4053       if((lit == 0) && (sign == 0)){
4054
4055         size--;
4056         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4057         while(size) 
4058           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4059
4060         genSkipz2(&rFalseIfx,0);
4061         if(ifx) ifx->generated = 1;
4062         return;
4063       }
4064
4065       if(size==1) {
4066         /* Special cases */
4067         lit &= 0xff;
4068         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4069           /* degenerate compare can never be true */
4070           if(rFalseIfx.condition == 0)
4071             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4072
4073           if(ifx) ifx->generated = 1;
4074           return;
4075         }
4076
4077         if(sign) {
4078           /* signed comparisons to a literal byte */
4079
4080           int lp1 = (lit+1) & 0xff;
4081
4082           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4083           switch (lp1) {
4084           case 0:
4085             rFalseIfx.condition ^= 1;
4086             genSkipCond(&rFalseIfx,right,0,7);
4087             break;
4088           case 0x7f:
4089             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4090             emitpcode(POC_XORLW, popGetLit(0x7f));
4091             genSkipz2(&rFalseIfx,1);
4092             break;
4093           default:
4094             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4095             emitpcode(POC_ADDLW, popGetLit(0x80));
4096             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4097             rFalseIfx.condition ^= 1;
4098             genSkipc(&rFalseIfx);
4099             break;
4100           }
4101         } else {
4102           /* unsigned comparisons to a literal byte */
4103
4104           switch(lit & 0xff ) {
4105           case 0:
4106             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4107             genSkipz2(&rFalseIfx,0);
4108             break;
4109           case 0x7f:
4110             rFalseIfx.condition ^= 1;
4111             genSkipCond(&rFalseIfx,right,0,7);
4112             break;
4113
4114           default:
4115             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4116             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4117             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4118             rFalseIfx.condition ^= 1;
4119             genSkipc(&rFalseIfx);
4120             break;
4121           }
4122         }
4123
4124         if(ifx) ifx->generated = 1;
4125         return;
4126
4127       } else {
4128
4129         /* Size is greater than 1 */
4130
4131         if(sign) {
4132           int lp1 = lit+1;
4133
4134           size--;
4135
4136           if(lp1 == 0) {
4137             /* this means lit = 0xffffffff, or -1 */
4138
4139
4140             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4141             rFalseIfx.condition ^= 1;
4142             genSkipCond(&rFalseIfx,right,size,7);
4143             if(ifx) ifx->generated = 1;
4144             return;
4145           }
4146
4147           if(lit == 0) {
4148             int s = size;
4149
4150             if(rFalseIfx.condition) {
4151               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4153             }
4154
4155             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4156             while(size--)
4157               emitpcode(POC_IORFW, popGet(AOP(right),size));
4158
4159
4160             emitSKPZ;
4161             if(rFalseIfx.condition) {
4162               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4163               emitpLabel(truelbl->key);
4164             }else {
4165               rFalseIfx.condition ^= 1;
4166               genSkipCond(&rFalseIfx,right,s,7);
4167             }
4168
4169             if(ifx) ifx->generated = 1;
4170             return;
4171           }
4172
4173           if((size == 1) &&  (0 == (lp1&0xff))) {
4174             /* lower byte of signed word is zero */
4175             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4176             i = ((lp1 >> 8) & 0xff) ^0x80;
4177             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4178             emitpcode(POC_ADDLW, popGetLit( 0x80));
4179             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4180             rFalseIfx.condition ^= 1;
4181             genSkipc(&rFalseIfx);
4182
4183
4184             if(ifx) ifx->generated = 1;
4185             return;
4186           }
4187
4188           if(lit & (0x80 << (size*8))) {
4189             /* Lit is less than zero */
4190             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4191             //rFalseIfx.condition ^= 1;
4192             //genSkipCond(&rFalseIfx,left,size,7);
4193             //rFalseIfx.condition ^= 1;
4194             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4195             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4196
4197             if(rFalseIfx.condition)
4198               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4199             else
4200               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4201
4202
4203           } else {
4204             /* Lit is greater than or equal to zero */
4205             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4206             //rFalseIfx.condition ^= 1;
4207             //genSkipCond(&rFalseIfx,right,size,7);
4208             //rFalseIfx.condition ^= 1;
4209
4210             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4212
4213             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214             if(rFalseIfx.condition)
4215               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4216             else
4217               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4218
4219           }
4220
4221
4222           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4224
4225           while(size--) {
4226
4227             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4228             emitSKPNZ;
4229             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230           }
4231           rFalseIfx.condition ^= 1;
4232           //rFalseIfx.condition = 1;
4233           genSkipc(&rFalseIfx);
4234
4235           emitpLabel(truelbl->key);
4236
4237           if(ifx) ifx->generated = 1;
4238           return;
4239           // end of if (sign)
4240         } else {
4241
4242           /* compare word or long to an unsigned literal on the right.*/
4243
4244
4245           size--;
4246           if(lit < 0xff) {
4247             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4248             switch (lit) {
4249             case 0:
4250               break; /* handled above */
4251 /*
4252             case 0xff:
4253               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4254               while(size--)
4255                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256               genSkipz2(&rFalseIfx,0);
4257               break;
4258 */
4259             default:
4260               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4261               while(--size)
4262                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4263
4264               emitSKPZ;
4265               if(rFalseIfx.condition)
4266                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4267               else
4268                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4269
4270
4271               emitpcode(POC_MOVLW, popGetLit(lit+1));
4272               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4273
4274               rFalseIfx.condition ^= 1;
4275               genSkipc(&rFalseIfx);
4276             }
4277
4278             emitpLabel(truelbl->key);
4279
4280             if(ifx) ifx->generated = 1;
4281             return;
4282           }
4283
4284
4285           lit++;
4286           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4287           i = (lit >> (size*8)) & 0xff;
4288
4289           emitpcode(POC_MOVLW, popGetLit(i));
4290           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4291
4292           while(size--) {
4293             i = (lit >> (size*8)) & 0xff;
4294
4295             if(i) {
4296               emitpcode(POC_MOVLW, popGetLit(i));
4297               emitSKPNZ;
4298               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4299             } else {
4300               /* this byte of the lit is zero, 
4301                *if it's not the last then OR in the variable */
4302               if(size)
4303                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4304             }
4305           }
4306
4307
4308           emitpLabel(lbl->key);
4309
4310           rFalseIfx.condition ^= 1;
4311           genSkipc(&rFalseIfx);
4312         }
4313
4314         if(sign)
4315           emitpLabel(truelbl->key);
4316         if(ifx) ifx->generated = 1;
4317         return;
4318       }
4319     }
4320     /* Compare two variables */
4321
4322     DEBUGpic14_emitcode(";sign","%d",sign);
4323
4324     size--;
4325     if(sign) {
4326       /* Sigh. thus sucks... */
4327       if(size) {
4328         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4329         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4330         emitpcode(POC_MOVLW, popGetLit(0x80));
4331         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4332         emitpcode(POC_XORFW, popGet(AOP(right),size));
4333         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4334       } else {
4335         /* Signed char comparison */
4336         /* Special thanks to Nikolai Golovchenko for this snippet */
4337         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4338         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4339         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4340         emitpcode(POC_XORFW, popGet(AOP(left),0));
4341         emitpcode(POC_XORFW, popGet(AOP(right),0));
4342         emitpcode(POC_ADDLW, popGetLit(0x80));
4343
4344         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4345         genSkipc(&rFalseIfx);
4346           
4347         if(ifx) ifx->generated = 1;
4348         return;
4349       }
4350
4351     } else {
4352
4353       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4354       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4355     }
4356
4357
4358     /* The rest of the bytes of a multi-byte compare */
4359     while (size) {
4360
4361       emitSKPZ;
4362       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4363       size--;
4364
4365       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4366       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367
4368
4369     }
4370
4371     emitpLabel(lbl->key);
4372
4373     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4374     genSkipc(&rFalseIfx);
4375     if(ifx) ifx->generated = 1;
4376     return;
4377
4378   }
4379
4380   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4381     pic14_outBitC(result);
4382   } else {
4383     /* if the result is used in the next
4384        ifx conditional branch then generate
4385        code a little differently */
4386     if (ifx )
4387       genIfxJump (ifx,"c");
4388     else
4389       pic14_outBitC(result);
4390     /* leave the result in acc */
4391   }
4392
4393 }
4394
4395 /*-----------------------------------------------------------------*/
4396 /* genCmpGt :- greater than comparison                             */
4397 /*-----------------------------------------------------------------*/
4398 static void genCmpGt (iCode *ic, iCode *ifx)
4399 {
4400     operand *left, *right, *result;
4401     sym_link *letype , *retype;
4402     int sign ;
4403
4404     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4405     left = IC_LEFT(ic);
4406     right= IC_RIGHT(ic);
4407     result = IC_RESULT(ic);
4408
4409     letype = getSpec(operandType(left));
4410     retype =getSpec(operandType(right));
4411     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4412     /* assign the amsops */
4413     aopOp (left,ic,FALSE);
4414     aopOp (right,ic,FALSE);
4415     aopOp (result,ic,TRUE);
4416
4417     genCmp(right, left, result, ifx, sign);
4418
4419     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4420     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4421     freeAsmop(result,NULL,ic,TRUE); 
4422 }
4423
4424 /*-----------------------------------------------------------------*/
4425 /* genCmpLt - less than comparisons                                */
4426 /*-----------------------------------------------------------------*/
4427 static void genCmpLt (iCode *ic, iCode *ifx)
4428 {
4429     operand *left, *right, *result;
4430     sym_link *letype , *retype;
4431     int sign ;
4432
4433     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4434     left = IC_LEFT(ic);
4435     right= IC_RIGHT(ic);
4436     result = IC_RESULT(ic);
4437
4438     letype = getSpec(operandType(left));
4439     retype =getSpec(operandType(right));
4440     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4441
4442     /* assign the amsops */
4443     aopOp (left,ic,FALSE);
4444     aopOp (right,ic,FALSE);
4445     aopOp (result,ic,TRUE);
4446
4447     genCmp(left, right, result, ifx, sign);
4448
4449     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4450     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4451     freeAsmop(result,NULL,ic,TRUE); 
4452 }
4453
4454 /*-----------------------------------------------------------------*/
4455 /* genc16bit2lit - compare a 16 bit value to a literal             */
4456 /*-----------------------------------------------------------------*/
4457 static void genc16bit2lit(operand *op, int lit, int offset)
4458 {
4459   int i;
4460
4461   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4462   if( (lit&0xff) == 0) 
4463     i=1;
4464   else
4465     i=0;
4466
4467   switch( BYTEofLONG(lit,i)) { 
4468   case 0:
4469     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4470     break;
4471   case 1:
4472     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4473     break;
4474   case 0xff:
4475     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4476     break;
4477   default:
4478     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4479     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4480   }
4481
4482   i ^= 1;
4483
4484   switch( BYTEofLONG(lit,i)) { 
4485   case 0:
4486     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4487     break;
4488   case 1:
4489     emitSKPNZ;
4490     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4491     break;
4492   case 0xff:
4493     emitSKPNZ;
4494     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4495     break;
4496   default:
4497     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4498     emitSKPNZ;
4499     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4500
4501   }
4502
4503 }
4504
4505 /*-----------------------------------------------------------------*/
4506 /* gencjneshort - compare and jump if not equal                    */
4507 /*-----------------------------------------------------------------*/
4508 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4509 {
4510   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4511   int offset = 0;
4512   resolvedIfx rIfx;
4513   symbol *lbl;
4514
4515   unsigned long lit = 0L;
4516   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4517   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4518
4519   resolveIfx(&rIfx,ifx);
4520   lbl =  newiTempLabel(NULL);
4521
4522
4523   /* if the left side is a literal or 
4524      if the right is in a pointer register and left 
4525      is not */
4526   if ((AOP_TYPE(left) == AOP_LIT) || 
4527       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4528     operand *t = right;
4529     right = left;
4530     left = t;
4531   }
4532   if(AOP_TYPE(right) == AOP_LIT)
4533     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4534
4535   /* if the right side is a literal then anything goes */
4536   if (AOP_TYPE(right) == AOP_LIT &&
4537       AOP_TYPE(left) != AOP_DIR ) {
4538     switch(size) {
4539     case 2:
4540       genc16bit2lit(left, lit, 0);
4541       emitSKPNZ;
4542       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4543       break;
4544     default:
4545       while (size--) {
4546         if(lit & 0xff) {
4547           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4548           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4549         } else {
4550           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4551         }
4552
4553         emitSKPNZ;
4554         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4555         offset++;
4556         lit >>= 8;
4557       }
4558       break;
4559     }
4560   }
4561
4562   /* if the right side is in a register or in direct space or
4563      if the left is a pointer register & right is not */    
4564   else if (AOP_TYPE(right) == AOP_REG ||
4565            AOP_TYPE(right) == AOP_DIR || 
4566            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4567            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4568     switch(size) {
4569     case 2:
4570       genc16bit2lit(left, lit, 0);
4571       emitSKPNZ;
4572       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4573       break;
4574     default:
4575       while (size--) {
4576         int emit_skip=1;
4577         if((AOP_TYPE(left) == AOP_DIR) && 
4578            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4579
4580           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4581           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4582
4583         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4584             
4585           switch (lit & 0xff) {
4586           case 0:
4587             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4588             break;
4589           case 1:
4590             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4591             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4592             emit_skip=0;
4593             break;
4594           case 0xff:
4595             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4596             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4597             emit_skip=0;
4598             break;
4599           default:
4600             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4601             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4602           }
4603           lit >>= 8;
4604
4605         } else {
4606           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4607         }
4608         if(emit_skip) {
4609           if(AOP_TYPE(result) == AOP_CRY) {
4610             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4611             if(rIfx.condition)
4612               emitSKPNZ;
4613             else
4614               emitSKPZ;
4615             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4616           } else {
4617             /* fix me. probably need to check result size too */
4618             emitpcode(POC_CLRF,popGet(AOP(result),0));
4619             if(rIfx.condition)
4620               emitSKPNZ;
4621             else
4622               emitSKPZ;
4623             emitpcode(POC_INCF,popGet(AOP(result),0));
4624           }
4625           if(ifx)
4626             ifx->generated=1;
4627         }
4628         emit_skip++;
4629         offset++;
4630       }
4631       break;
4632     }
4633   } else if(AOP_TYPE(right) == AOP_REG &&
4634             AOP_TYPE(left) != AOP_DIR){
4635
4636     while(size--) {
4637       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4638       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4639       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4640       if(rIfx.condition)
4641         emitSKPNZ;
4642       else
4643         emitSKPZ;
4644       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4645       offset++;
4646     }
4647       
4648   }else{
4649     /* right is a pointer reg need both a & b */
4650     while(size--) {
4651       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4652       if(strcmp(l,"b"))
4653         pic14_emitcode("mov","b,%s",l);
4654       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4655       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4656       offset++;
4657     }
4658   }
4659   emitpLabel(lbl->key);
4660
4661   if(ifx)
4662     ifx->generated = 1;
4663 }
4664
4665 #if 0
4666 /*-----------------------------------------------------------------*/
4667 /* gencjne - compare and jump if not equal                         */
4668 /*-----------------------------------------------------------------*/
4669 static void gencjne(operand *left, operand *right, iCode *ifx)
4670 {
4671     symbol *tlbl  = newiTempLabel(NULL);
4672
4673     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4674     gencjneshort(left, right, lbl);
4675
4676     pic14_emitcode("mov","a,%s",one);
4677     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4678     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4679     pic14_emitcode("clr","a");
4680     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4681
4682     emitpLabel(lbl->key);
4683     emitpLabel(tlbl->key);
4684
4685 }
4686 #endif
4687
4688 /*-----------------------------------------------------------------*/
4689 /* genCmpEq - generates code for equal to                          */
4690 /*-----------------------------------------------------------------*/
4691 static void genCmpEq (iCode *ic, iCode *ifx)
4692 {
4693     operand *left, *right, *result;
4694     unsigned long lit = 0L;
4695     int size,offset=0;
4696
4697     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4698
4699     if(ifx)
4700       DEBUGpic14_emitcode ("; ifx is non-null","");
4701     else
4702       DEBUGpic14_emitcode ("; ifx is null","");
4703
4704     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4705     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4706     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4707
4708     size = max(AOP_SIZE(left),AOP_SIZE(right));
4709
4710     DEBUGpic14_AopType(__LINE__,left,right,result);
4711
4712     /* if literal, literal on the right or 
4713     if the right is in a pointer register and left 
4714     is not */
4715     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4716         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4717       operand *tmp = right ;
4718       right = left;
4719       left = tmp;
4720     }
4721
4722
4723     if(ifx && !AOP_SIZE(result)){
4724         symbol *tlbl;
4725         /* if they are both bit variables */
4726         if (AOP_TYPE(left) == AOP_CRY &&
4727             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4728             if(AOP_TYPE(right) == AOP_LIT){
4729                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4730                 if(lit == 0L){
4731                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4732                     pic14_emitcode("cpl","c");
4733                 } else if(lit == 1L) {
4734                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4735                 } else {
4736                     pic14_emitcode("clr","c");
4737                 }
4738                 /* AOP_TYPE(right) == AOP_CRY */
4739             } else {
4740                 symbol *lbl = newiTempLabel(NULL);
4741                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4742                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4743                 pic14_emitcode("cpl","c");
4744                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4745             }
4746             /* if true label then we jump if condition
4747             supplied is true */
4748             tlbl = newiTempLabel(NULL);
4749             if ( IC_TRUE(ifx) ) {
4750                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4751                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4752             } else {
4753                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4754                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4755             }
4756             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4757
4758             {
4759               /* left and right are both bit variables, result is carry */
4760               resolvedIfx rIfx;
4761               
4762               resolveIfx(&rIfx,ifx);
4763
4764               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4765               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4766               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4767               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4768               genSkipz2(&rIfx,0);
4769             }
4770         } else {
4771
4772           /* They're not both bit variables. Is the right a literal? */
4773           if(AOP_TYPE(right) == AOP_LIT) {
4774             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4775             
4776             switch(size) {
4777
4778             case 1:
4779               switch(lit & 0xff) {
4780               case 1:
4781                 if ( IC_TRUE(ifx) ) {
4782                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4783                   emitSKPNZ;
4784                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4785                 } else {
4786                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4787                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4788                 }
4789                 break;
4790               case 0xff:
4791                 if ( IC_TRUE(ifx) ) {
4792                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4793                   emitSKPNZ;
4794                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4795                 } else {
4796                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4797                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4798                 }
4799                 break;
4800               default:
4801                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4802                 if(lit)
4803                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4804                 genSkip(ifx,'z');
4805               }
4806
4807
4808               /* end of size == 1 */
4809               break;
4810               
4811             case 2:
4812               genc16bit2lit(left,lit,offset);
4813               genSkip(ifx,'z');
4814               break;
4815               /* end of size == 2 */
4816
4817             default:
4818               /* size is 4 */
4819               if(lit==0) {
4820                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4821                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4822                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4823                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4824
4825               } else {
4826
4827                 /* search for patterns that can be optimized */
4828
4829                 genc16bit2lit(left,lit,0);
4830                 lit >>= 16;
4831                 if(lit) {
4832                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4833                   //genSkip(ifx,'z');
4834                   genc16bit2lit(left,lit,2);
4835                 } else {
4836                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4837                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4838
4839                 }
4840                 
4841               }
4842
4843               genSkip(ifx,'z');
4844             }
4845           
4846             ifx->generated = 1;
4847             goto release ;
4848             
4849
4850           } else if(AOP_TYPE(right) == AOP_CRY ) {
4851             /* we know the left is not a bit, but that the right is */
4852             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4853             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4854                       popGet(AOP(right),offset));
4855             emitpcode(POC_XORLW,popGetLit(1));
4856
4857             /* if the two are equal, then W will be 0 and the Z bit is set
4858              * we could test Z now, or go ahead and check the high order bytes if
4859              * the variable we're comparing is larger than a byte. */
4860
4861             while(--size)
4862               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4863
4864             if ( IC_TRUE(ifx) ) {
4865               emitSKPNZ;
4866               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4867               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4868             } else {
4869               emitSKPZ;
4870               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4871               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4872             }
4873
4874           } else {
4875             /* They're both variables that are larger than bits */
4876             int s = size;
4877
4878             tlbl = newiTempLabel(NULL);
4879
4880             while(size--) {
4881               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4882               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4883
4884               if ( IC_TRUE(ifx) ) {
4885                 if(size) {
4886                   emitSKPZ;
4887                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4888                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4889                 } else {
4890                   emitSKPNZ;
4891                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4892                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4893                 }
4894               } else {
4895                 emitSKPZ;
4896                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4897                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4898               }
4899               offset++;
4900             }
4901             if(s>1 && IC_TRUE(ifx)) {
4902               emitpLabel(tlbl->key);
4903               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4904             }
4905           }
4906         }
4907         /* mark the icode as generated */
4908         ifx->generated = 1;
4909         goto release ;
4910     }
4911
4912     /* if they are both bit variables */
4913     if (AOP_TYPE(left) == AOP_CRY &&
4914         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4915         if(AOP_TYPE(right) == AOP_LIT){
4916             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4917             if(lit == 0L){
4918                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4919                 pic14_emitcode("cpl","c");
4920             } else if(lit == 1L) {
4921                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4922             } else {
4923                 pic14_emitcode("clr","c");
4924             }
4925             /* AOP_TYPE(right) == AOP_CRY */
4926         } else {
4927             symbol *lbl = newiTempLabel(NULL);
4928             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4929             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4930             pic14_emitcode("cpl","c");
4931             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4932         }
4933         /* c = 1 if egal */
4934         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4935             pic14_outBitC(result);
4936             goto release ;
4937         }
4938         if (ifx) {
4939             genIfxJump (ifx,"c");
4940             goto release ;
4941         }
4942         /* if the result is used in an arithmetic operation
4943         then put the result in place */
4944         pic14_outBitC(result);
4945     } else {
4946       
4947       gencjne(left,right,result,ifx);
4948 /*
4949       if(ifx) 
4950         gencjne(left,right,newiTempLabel(NULL));
4951       else {
4952         if(IC_TRUE(ifx)->key)
4953           gencjne(left,right,IC_TRUE(ifx)->key);
4954         else
4955           gencjne(left,right,IC_FALSE(ifx)->key);
4956         ifx->generated = 1;
4957         goto release ;
4958       }
4959       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4960         aopPut(AOP(result),"a",0);
4961         goto release ;
4962       }
4963
4964       if (ifx) {
4965         genIfxJump (ifx,"a");
4966         goto release ;
4967       }
4968 */
4969       /* if the result is used in an arithmetic operation
4970          then put the result in place */
4971 /*
4972       if (AOP_TYPE(result) != AOP_CRY) 
4973         pic14_outAcc(result);
4974 */
4975       /* leave the result in acc */
4976     }
4977
4978 release:
4979     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4980     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4981     freeAsmop(result,NULL,ic,TRUE);
4982 }
4983
4984 /*-----------------------------------------------------------------*/
4985 /* ifxForOp - returns the icode containing the ifx for operand     */
4986 /*-----------------------------------------------------------------*/
4987 static iCode *ifxForOp ( operand *op, iCode *ic )
4988 {
4989     /* if true symbol then needs to be assigned */
4990     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4991     if (IS_TRUE_SYMOP(op))
4992         return NULL ;
4993
4994     /* if this has register type condition and
4995     the next instruction is ifx with the same operand
4996     and live to of the operand is upto the ifx only then */
4997     if (ic->next &&
4998         ic->next->op == IFX &&
4999         IC_COND(ic->next)->key == op->key &&
5000         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5001         return ic->next;
5002
5003     if (ic->next &&
5004         ic->next->op == IFX &&
5005         IC_COND(ic->next)->key == op->key) {
5006       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5007       return ic->next;
5008     }
5009
5010     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5011     if (ic->next &&
5012         ic->next->op == IFX)
5013       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5014
5015     if (ic->next &&
5016         ic->next->op == IFX &&
5017         IC_COND(ic->next)->key == op->key) {
5018       DEBUGpic14_emitcode ("; "," key is okay");
5019       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5020                            OP_SYMBOL(op)->liveTo,
5021                            ic->next->seq);
5022     }
5023
5024
5025     return NULL;
5026 }
5027 /*-----------------------------------------------------------------*/
5028 /* genAndOp - for && operation                                     */
5029 /*-----------------------------------------------------------------*/
5030 static void genAndOp (iCode *ic)
5031 {
5032     operand *left,*right, *result;
5033     symbol *tlbl;
5034
5035     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5036     /* note here that && operations that are in an
5037     if statement are taken away by backPatchLabels
5038     only those used in arthmetic operations remain */
5039     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5040     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5041     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5042
5043     /* if both are bit variables */
5044     if (AOP_TYPE(left) == AOP_CRY &&
5045         AOP_TYPE(right) == AOP_CRY ) {
5046         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5047         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5048         pic14_outBitC(result);
5049     } else {
5050         tlbl = newiTempLabel(NULL);
5051         pic14_toBoolean(left);    
5052         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5053         pic14_toBoolean(right);
5054         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5055         pic14_outBitAcc(result);
5056     }
5057
5058     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5059     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5060     freeAsmop(result,NULL,ic,TRUE);
5061 }
5062
5063
5064 /*-----------------------------------------------------------------*/
5065 /* genOrOp - for || operation                                      */
5066 /*-----------------------------------------------------------------*/
5067 /*
5068   tsd pic port -
5069   modified this code, but it doesn't appear to ever get called
5070 */
5071
5072 static void genOrOp (iCode *ic)
5073 {
5074     operand *left,*right, *result;
5075     symbol *tlbl;
5076
5077     /* note here that || operations that are in an
5078     if statement are taken away by backPatchLabels
5079     only those used in arthmetic operations remain */
5080     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5081     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5082     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5083     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5084
5085     DEBUGpic14_AopType(__LINE__,left,right,result);
5086
5087     /* if both are bit variables */
5088     if (AOP_TYPE(left) == AOP_CRY &&
5089         AOP_TYPE(right) == AOP_CRY ) {
5090       pic14_emitcode("clrc","");
5091       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5092                AOP(left)->aopu.aop_dir,
5093                AOP(left)->aopu.aop_dir);
5094       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5095                AOP(right)->aopu.aop_dir,
5096                AOP(right)->aopu.aop_dir);
5097       pic14_emitcode("setc","");
5098
5099     } else {
5100         tlbl = newiTempLabel(NULL);
5101         pic14_toBoolean(left);
5102         emitSKPZ;
5103         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5104         pic14_toBoolean(right);
5105         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5106
5107         pic14_outBitAcc(result);
5108     }
5109
5110     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5112     freeAsmop(result,NULL,ic,TRUE);            
5113 }
5114
5115 /*-----------------------------------------------------------------*/
5116 /* isLiteralBit - test if lit == 2^n                               */
5117 /*-----------------------------------------------------------------*/
5118 static int isLiteralBit(unsigned long lit)
5119 {
5120     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5121     0x100L,0x200L,0x400L,0x800L,
5122     0x1000L,0x2000L,0x4000L,0x8000L,
5123     0x10000L,0x20000L,0x40000L,0x80000L,
5124     0x100000L,0x200000L,0x400000L,0x800000L,
5125     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5126     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5127     int idx;
5128     
5129     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5130     for(idx = 0; idx < 32; idx++)
5131         if(lit == pw[idx])
5132             return idx+1;
5133     return 0;
5134 }
5135
5136 /*-----------------------------------------------------------------*/
5137 /* continueIfTrue -                                                */
5138 /*-----------------------------------------------------------------*/
5139 static void continueIfTrue (iCode *ic)
5140 {
5141     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5142     if(IC_TRUE(ic))
5143         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5144     ic->generated = 1;
5145 }
5146
5147 /*-----------------------------------------------------------------*/
5148 /* jmpIfTrue -                                                     */
5149 /*-----------------------------------------------------------------*/
5150 static void jumpIfTrue (iCode *ic)
5151 {
5152     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5153     if(!IC_TRUE(ic))
5154         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5155     ic->generated = 1;
5156 }
5157
5158 /*-----------------------------------------------------------------*/
5159 /* jmpTrueOrFalse -                                                */
5160 /*-----------------------------------------------------------------*/
5161 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5162 {
5163     // ugly but optimized by peephole
5164     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5165     if(IC_TRUE(ic)){
5166         symbol *nlbl = newiTempLabel(NULL);
5167         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5168         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5169         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5170         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5171     }
5172     else{
5173         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5174         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5175     }
5176     ic->generated = 1;
5177 }
5178
5179 /*-----------------------------------------------------------------*/
5180 /* genAnd  - code for and                                          */
5181 /*-----------------------------------------------------------------*/
5182 static void genAnd (iCode *ic, iCode *ifx)
5183 {
5184   operand *left, *right, *result;
5185   int size, offset=0;  
5186   unsigned long lit = 0L;
5187   int bytelit = 0;
5188   resolvedIfx rIfx;
5189
5190
5191   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5192   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5193   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5194   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5195
5196   resolveIfx(&rIfx,ifx);
5197
5198   /* if left is a literal & right is not then exchange them */
5199   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5200       AOP_NEEDSACC(left)) {
5201     operand *tmp = right ;
5202     right = left;
5203     left = tmp;
5204   }
5205
5206   /* if result = right then exchange them */
5207   if(pic14_sameRegs(AOP(result),AOP(right))){
5208     operand *tmp = right ;
5209     right = left;
5210     left = tmp;
5211   }
5212
5213   /* if right is bit then exchange them */
5214   if (AOP_TYPE(right) == AOP_CRY &&
5215       AOP_TYPE(left) != AOP_CRY){
5216     operand *tmp = right ;
5217     right = left;
5218     left = tmp;
5219   }
5220   if(AOP_TYPE(right) == AOP_LIT)
5221     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5222
5223   size = AOP_SIZE(result);
5224
5225   DEBUGpic14_AopType(__LINE__,left,right,result);
5226
5227   // if(bit & yy)
5228   // result = bit & yy;
5229   if (AOP_TYPE(left) == AOP_CRY){
5230     // c = bit & literal;
5231     if(AOP_TYPE(right) == AOP_LIT){
5232       if(lit & 1) {
5233         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5234           // no change
5235           goto release;
5236         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5237       } else {
5238         // bit(result) = 0;
5239         if(size && (AOP_TYPE(result) == AOP_CRY)){
5240           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5241           goto release;
5242         }
5243         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5244           jumpIfTrue(ifx);
5245           goto release;
5246         }
5247         pic14_emitcode("clr","c");
5248       }
5249     } else {
5250       if (AOP_TYPE(right) == AOP_CRY){
5251         // c = bit & bit;
5252         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5253         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5254       } else {
5255         // c = bit & val;
5256         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5257         // c = lsb
5258         pic14_emitcode("rrc","a");
5259         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5260       }
5261     }
5262     // bit = c
5263     // val = c
5264     if(size)
5265       pic14_outBitC(result);
5266     // if(bit & ...)
5267     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5268       genIfxJump(ifx, "c");           
5269     goto release ;
5270   }
5271
5272   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5273   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5274   if((AOP_TYPE(right) == AOP_LIT) &&
5275      (AOP_TYPE(result) == AOP_CRY) &&
5276      (AOP_TYPE(left) != AOP_CRY)){
5277     int posbit = isLiteralBit(lit);
5278     /* left &  2^n */
5279     if(posbit){
5280       posbit--;
5281       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5282       // bit = left & 2^n
5283       if(size)
5284         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5285       // if(left &  2^n)
5286       else{
5287         if(ifx){
5288 /*
5289           if(IC_TRUE(ifx)) {
5290             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5291             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5292           } else {
5293             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5294             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5295           }
5296 */
5297           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5298                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5299           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5300           
5301           ifx->generated = 1;
5302         }
5303         goto release;
5304       }
5305     } else {
5306       symbol *tlbl = newiTempLabel(NULL);
5307       int sizel = AOP_SIZE(left);
5308       if(size)
5309         pic14_emitcode("setb","c");
5310       while(sizel--){
5311         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5312           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5313           // byte ==  2^n ?
5314           if((posbit = isLiteralBit(bytelit)) != 0)
5315             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5316           else{
5317             if(bytelit != 0x0FFL)
5318               pic14_emitcode("anl","a,%s",
5319                              aopGet(AOP(right),offset,FALSE,TRUE));
5320             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5321           }
5322         }
5323         offset++;
5324       }
5325       // bit = left & literal
5326       if(size){
5327         pic14_emitcode("clr","c");
5328         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5329       }
5330       // if(left & literal)
5331       else{
5332         if(ifx)
5333           jmpTrueOrFalse(ifx, tlbl);
5334         goto release ;
5335       }
5336     }
5337     pic14_outBitC(result);
5338     goto release ;
5339   }
5340
5341   /* if left is same as result */
5342   if(pic14_sameRegs(AOP(result),AOP(left))){
5343     int know_W = -1;
5344     for(;size--; offset++,lit>>=8) {
5345       if(AOP_TYPE(right) == AOP_LIT){
5346         switch(lit & 0xff) {
5347         case 0x00:
5348           /*  and'ing with 0 has clears the result */
5349           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5350           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5351           break;
5352         case 0xff:
5353           /* and'ing with 0xff is a nop when the result and left are the same */
5354           break;
5355
5356         default:
5357           {
5358             int p = my_powof2( (~lit) & 0xff );
5359             if(p>=0) {
5360               /* only one bit is set in the literal, so use a bcf instruction */
5361               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5362               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5363
5364             } else {
5365               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5366               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5367               if(know_W != (lit&0xff))
5368                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5369               know_W = lit &0xff;
5370               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5371             }
5372           }    
5373         }
5374       } else {
5375         if (AOP_TYPE(left) == AOP_ACC) {
5376           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5377         } else {                    
5378           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5379           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5380
5381         }
5382       }
5383     }
5384
5385   } else {
5386     // left & result in different registers
5387     if(AOP_TYPE(result) == AOP_CRY){
5388       // result = bit
5389       // if(size), result in bit
5390       // if(!size && ifx), conditional oper: if(left & right)
5391       symbol *tlbl = newiTempLabel(NULL);
5392       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5393       if(size)
5394         pic14_emitcode("setb","c");
5395       while(sizer--){
5396         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5397         pic14_emitcode("anl","a,%s",
5398                        aopGet(AOP(left),offset,FALSE,FALSE));
5399         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5400         offset++;
5401       }
5402       if(size){
5403         CLRC;
5404         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5405         pic14_outBitC(result);
5406       } else if(ifx)
5407         jmpTrueOrFalse(ifx, tlbl);
5408     } else {
5409       for(;(size--);offset++) {
5410         // normal case
5411         // result = left & right
5412         if(AOP_TYPE(right) == AOP_LIT){
5413           int t = (lit >> (offset*8)) & 0x0FFL;
5414           switch(t) { 
5415           case 0x00:
5416             pic14_emitcode("clrf","%s",
5417                            aopGet(AOP(result),offset,FALSE,FALSE));
5418             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5419             break;
5420           case 0xff:
5421             pic14_emitcode("movf","%s,w",
5422                            aopGet(AOP(left),offset,FALSE,FALSE));
5423             pic14_emitcode("movwf","%s",
5424                            aopGet(AOP(result),offset,FALSE,FALSE));
5425             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5426             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5427             break;
5428           default:
5429             pic14_emitcode("movlw","0x%x",t);
5430             pic14_emitcode("andwf","%s,w",
5431                            aopGet(AOP(left),offset,FALSE,FALSE));
5432             pic14_emitcode("movwf","%s",
5433                            aopGet(AOP(result),offset,FALSE,FALSE));
5434               
5435             emitpcode(POC_MOVLW, popGetLit(t));
5436             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5437             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5438           }
5439           continue;
5440         }
5441
5442         if (AOP_TYPE(left) == AOP_ACC) {
5443           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5444           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5445         } else {
5446           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5447           pic14_emitcode("andwf","%s,w",
5448                          aopGet(AOP(left),offset,FALSE,FALSE));
5449           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5450           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5451         }
5452         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5453         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5454       }
5455     }
5456   }
5457
5458   release :
5459     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5460   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5461   freeAsmop(result,NULL,ic,TRUE);     
5462 }
5463
5464 /*-----------------------------------------------------------------*/
5465 /* genOr  - code for or                                            */
5466 /*-----------------------------------------------------------------*/
5467 static void genOr (iCode *ic, iCode *ifx)
5468 {
5469     operand *left, *right, *result;
5470     int size, offset=0;
5471     unsigned long lit = 0L;
5472
5473     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5474
5475     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5476     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5477     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5478
5479     DEBUGpic14_AopType(__LINE__,left,right,result);
5480
5481     /* if left is a literal & right is not then exchange them */
5482     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5483         AOP_NEEDSACC(left)) {
5484         operand *tmp = right ;
5485         right = left;
5486         left = tmp;
5487     }
5488
5489     /* if result = right then exchange them */
5490     if(pic14_sameRegs(AOP(result),AOP(right))){
5491         operand *tmp = right ;
5492         right = left;
5493         left = tmp;
5494     }
5495
5496     /* if right is bit then exchange them */
5497     if (AOP_TYPE(right) == AOP_CRY &&
5498         AOP_TYPE(left) != AOP_CRY){
5499         operand *tmp = right ;
5500         right = left;
5501         left = tmp;
5502     }
5503
5504     DEBUGpic14_AopType(__LINE__,left,right,result);
5505
5506     if(AOP_TYPE(right) == AOP_LIT)
5507         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5508
5509     size = AOP_SIZE(result);
5510
5511     // if(bit | yy)
5512     // xx = bit | yy;
5513     if (AOP_TYPE(left) == AOP_CRY){
5514         if(AOP_TYPE(right) == AOP_LIT){
5515             // c = bit & literal;
5516             if(lit){
5517                 // lit != 0 => result = 1
5518                 if(AOP_TYPE(result) == AOP_CRY){
5519                   if(size)
5520                     emitpcode(POC_BSF, popGet(AOP(result),0));
5521                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5522                   //     AOP(result)->aopu.aop_dir,
5523                   //     AOP(result)->aopu.aop_dir);
5524                     else if(ifx)
5525                         continueIfTrue(ifx);
5526                     goto release;
5527                 }
5528             } else {
5529                 // lit == 0 => result = left
5530                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5531                     goto release;
5532                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5533             }
5534         } else {
5535             if (AOP_TYPE(right) == AOP_CRY){
5536               if(pic14_sameRegs(AOP(result),AOP(left))){
5537                 // c = bit | bit;
5538                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5539                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5540                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5541
5542                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5543                          AOP(result)->aopu.aop_dir,
5544                          AOP(result)->aopu.aop_dir);
5545                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5546                          AOP(right)->aopu.aop_dir,
5547                          AOP(right)->aopu.aop_dir);
5548                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5549                          AOP(result)->aopu.aop_dir,
5550                          AOP(result)->aopu.aop_dir);
5551               } else {
5552                 if( AOP_TYPE(result) == AOP_ACC) {
5553                   emitpcode(POC_MOVLW, popGetLit(0));
5554                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5555                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5556                   emitpcode(POC_MOVLW, popGetLit(1));
5557
5558                 } else {
5559
5560                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5561                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5562                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5563                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5564
5565                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5566                                  AOP(result)->aopu.aop_dir,
5567                                  AOP(result)->aopu.aop_dir);
5568                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5569                                  AOP(right)->aopu.aop_dir,
5570                                  AOP(right)->aopu.aop_dir);
5571                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5572                                  AOP(left)->aopu.aop_dir,
5573                                  AOP(left)->aopu.aop_dir);
5574                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5575                                  AOP(result)->aopu.aop_dir,
5576                                  AOP(result)->aopu.aop_dir);
5577                 }
5578               }
5579             } else {
5580                 // c = bit | val;
5581                 symbol *tlbl = newiTempLabel(NULL);
5582                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5583
5584
5585                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5586                 if( AOP_TYPE(right) == AOP_ACC) {
5587                   emitpcode(POC_IORLW, popGetLit(0));
5588                   emitSKPNZ;
5589                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5590                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5591                 }
5592
5593
5594
5595                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5596                     pic14_emitcode(";XXX setb","c");
5597                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5598                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5599                 pic14_toBoolean(right);
5600                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5601                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5602                     jmpTrueOrFalse(ifx, tlbl);
5603                     goto release;
5604                 } else {
5605                     CLRC;
5606                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5607                 }
5608             }
5609         }
5610         // bit = c
5611         // val = c
5612         if(size)
5613             pic14_outBitC(result);
5614         // if(bit | ...)
5615         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5616             genIfxJump(ifx, "c");           
5617         goto release ;
5618     }
5619
5620     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5621     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5622     if((AOP_TYPE(right) == AOP_LIT) &&
5623        (AOP_TYPE(result) == AOP_CRY) &&
5624        (AOP_TYPE(left) != AOP_CRY)){
5625         if(lit){
5626           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5627             // result = 1
5628             if(size)
5629                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5630             else 
5631                 continueIfTrue(ifx);
5632             goto release;
5633         } else {
5634           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5635             // lit = 0, result = boolean(left)
5636             if(size)
5637                 pic14_emitcode(";XXX setb","c");
5638             pic14_toBoolean(right);
5639             if(size){
5640                 symbol *tlbl = newiTempLabel(NULL);
5641                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5642                 CLRC;
5643                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5644             } else {
5645                 genIfxJump (ifx,"a");
5646                 goto release;
5647             }
5648         }
5649         pic14_outBitC(result);
5650         goto release ;
5651     }
5652
5653     /* if left is same as result */
5654     if(pic14_sameRegs(AOP(result),AOP(left))){
5655       int know_W = -1;
5656       for(;size--; offset++,lit>>=8) {
5657         if(AOP_TYPE(right) == AOP_LIT){
5658           if((lit & 0xff) == 0)
5659             /*  or'ing with 0 has no effect */
5660             continue;
5661           else {
5662             int p = my_powof2(lit & 0xff);
5663             if(p>=0) {
5664               /* only one bit is set in the literal, so use a bsf instruction */
5665               emitpcode(POC_BSF,
5666                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5667             } else {
5668               if(know_W != (lit & 0xff))
5669                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5670               know_W = lit & 0xff;
5671               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5672             }
5673                     
5674           }
5675         } else {
5676           if (AOP_TYPE(left) == AOP_ACC) {
5677             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5678             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5679           } else {                  
5680             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5681             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5682
5683             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5684             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5685
5686           }
5687         }
5688       }
5689     } else {
5690         // left & result in different registers
5691         if(AOP_TYPE(result) == AOP_CRY){
5692             // result = bit
5693             // if(size), result in bit
5694             // if(!size && ifx), conditional oper: if(left | right)
5695             symbol *tlbl = newiTempLabel(NULL);
5696             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5697             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5698
5699
5700             if(size)
5701                 pic14_emitcode(";XXX setb","c");
5702             while(sizer--){
5703                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5704                 pic14_emitcode(";XXX orl","a,%s",
5705                          aopGet(AOP(left),offset,FALSE,FALSE));
5706                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5707                 offset++;
5708             }
5709             if(size){
5710                 CLRC;
5711                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5712                 pic14_outBitC(result);
5713             } else if(ifx)
5714                 jmpTrueOrFalse(ifx, tlbl);
5715         } else for(;(size--);offset++){
5716           // normal case
5717           // result = left & right
5718           if(AOP_TYPE(right) == AOP_LIT){
5719             int t = (lit >> (offset*8)) & 0x0FFL;
5720             switch(t) { 
5721             case 0x00:
5722               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5723               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5724
5725               pic14_emitcode("movf","%s,w",
5726                        aopGet(AOP(left),offset,FALSE,FALSE));
5727               pic14_emitcode("movwf","%s",
5728                        aopGet(AOP(result),offset,FALSE,FALSE));
5729               break;
5730             default:
5731               emitpcode(POC_MOVLW,  popGetLit(t));
5732               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5733               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5734
5735               pic14_emitcode("movlw","0x%x",t);
5736               pic14_emitcode("iorwf","%s,w",
5737                        aopGet(AOP(left),offset,FALSE,FALSE));
5738               pic14_emitcode("movwf","%s",
5739                        aopGet(AOP(result),offset,FALSE,FALSE));
5740               
5741             }
5742             continue;
5743           }
5744
5745           // faster than result <- left, anl result,right
5746           // and better if result is SFR
5747           if (AOP_TYPE(left) == AOP_ACC) {
5748             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5749             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5750           } else {
5751             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5752             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5753
5754             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5755             pic14_emitcode("iorwf","%s,w",
5756                      aopGet(AOP(left),offset,FALSE,FALSE));
5757           }
5758           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5759           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5760         }
5761     }
5762
5763 release :
5764     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5765     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5766     freeAsmop(result,NULL,ic,TRUE);     
5767 }
5768
5769 /*-----------------------------------------------------------------*/
5770 /* genXor - code for xclusive or                                   */
5771 /*-----------------------------------------------------------------*/
5772 static void genXor (iCode *ic, iCode *ifx)
5773 {
5774   operand *left, *right, *result;
5775   int size, offset=0;
5776   unsigned long lit = 0L;
5777
5778   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5779
5780   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5781   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5782   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5783
5784   /* if left is a literal & right is not ||
5785      if left needs acc & right does not */
5786   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5787       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5788     operand *tmp = right ;
5789     right = left;
5790     left = tmp;
5791   }
5792
5793   /* if result = right then exchange them */
5794   if(pic14_sameRegs(AOP(result),AOP(right))){
5795     operand *tmp = right ;
5796     right = left;
5797     left = tmp;
5798   }
5799
5800   /* if right is bit then exchange them */
5801   if (AOP_TYPE(right) == AOP_CRY &&
5802       AOP_TYPE(left) != AOP_CRY){
5803     operand *tmp = right ;
5804     right = left;
5805     left = tmp;
5806   }
5807   if(AOP_TYPE(right) == AOP_LIT)
5808     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5809
5810   size = AOP_SIZE(result);
5811
5812   // if(bit ^ yy)
5813   // xx = bit ^ yy;
5814   if (AOP_TYPE(left) == AOP_CRY){
5815     if(AOP_TYPE(right) == AOP_LIT){
5816       // c = bit & literal;
5817       if(lit>>1){
5818         // lit>>1  != 0 => result = 1
5819         if(AOP_TYPE(result) == AOP_CRY){
5820           if(size)
5821             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5822             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5823           else if(ifx)
5824             continueIfTrue(ifx);
5825           goto release;
5826         }
5827         pic14_emitcode("setb","c");
5828       } else{
5829         // lit == (0 or 1)
5830         if(lit == 0){
5831           // lit == 0, result = left
5832           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5833             goto release;
5834           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5835         } else{
5836           // lit == 1, result = not(left)
5837           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5838             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5839             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5840             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5841             goto release;
5842           } else {
5843             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5844             pic14_emitcode("cpl","c");
5845           }
5846         }
5847       }
5848
5849     } else {
5850       // right != literal
5851       symbol *tlbl = newiTempLabel(NULL);
5852       if (AOP_TYPE(right) == AOP_CRY){
5853         // c = bit ^ bit;
5854         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5855       }
5856       else{
5857         int sizer = AOP_SIZE(right);
5858         // c = bit ^ val
5859         // if val>>1 != 0, result = 1
5860         pic14_emitcode("setb","c");
5861         while(sizer){
5862           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5863           if(sizer == 1)
5864             // test the msb of the lsb
5865             pic14_emitcode("anl","a,#0xfe");
5866           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5867           sizer--;
5868         }
5869         // val = (0,1)
5870         pic14_emitcode("rrc","a");
5871       }
5872       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5873       pic14_emitcode("cpl","c");
5874       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5875     }
5876     // bit = c
5877     // val = c
5878     if(size)
5879       pic14_outBitC(result);
5880     // if(bit | ...)
5881     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5882       genIfxJump(ifx, "c");           
5883     goto release ;
5884   }
5885
5886   if(pic14_sameRegs(AOP(result),AOP(left))){
5887     /* if left is same as result */
5888     for(;size--; offset++) {
5889       if(AOP_TYPE(right) == AOP_LIT){
5890         int t  = (lit >> (offset*8)) & 0x0FFL;
5891         if(t == 0x00L)
5892           continue;
5893         else
5894           if (IS_AOP_PREG(left)) {
5895             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5896             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5897             aopPut(AOP(result),"a",offset);
5898           } else {
5899             emitpcode(POC_MOVLW, popGetLit(t));
5900             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5901             pic14_emitcode("xrl","%s,%s",
5902                            aopGet(AOP(left),offset,FALSE,TRUE),
5903                            aopGet(AOP(right),offset,FALSE,FALSE));
5904           }
5905       } else {
5906         if (AOP_TYPE(left) == AOP_ACC)
5907           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5908         else {
5909           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5910           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5911 /*
5912           if (IS_AOP_PREG(left)) {
5913             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5914             aopPut(AOP(result),"a",offset);
5915           } else
5916             pic14_emitcode("xrl","%s,a",
5917                            aopGet(AOP(left),offset,FALSE,TRUE));
5918 */
5919         }
5920       }
5921     }
5922   } else {
5923     // left & result in different registers
5924     if(AOP_TYPE(result) == AOP_CRY){
5925       // result = bit
5926       // if(size), result in bit
5927       // if(!size && ifx), conditional oper: if(left ^ right)
5928       symbol *tlbl = newiTempLabel(NULL);
5929       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5930       if(size)
5931         pic14_emitcode("setb","c");
5932       while(sizer--){
5933         if((AOP_TYPE(right) == AOP_LIT) &&
5934            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5935           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5936         } else {
5937           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5938           pic14_emitcode("xrl","a,%s",
5939                          aopGet(AOP(left),offset,FALSE,FALSE));
5940         }
5941         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5942         offset++;
5943       }
5944       if(size){
5945         CLRC;
5946         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5947         pic14_outBitC(result);
5948       } else if(ifx)
5949         jmpTrueOrFalse(ifx, tlbl);
5950     } else for(;(size--);offset++){
5951       // normal case
5952       // result = left & right
5953       if(AOP_TYPE(right) == AOP_LIT){
5954         int t = (lit >> (offset*8)) & 0x0FFL;
5955         switch(t) { 
5956         case 0x00:
5957           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5958           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5959           pic14_emitcode("movf","%s,w",
5960                          aopGet(AOP(left),offset,FALSE,FALSE));
5961           pic14_emitcode("movwf","%s",
5962                          aopGet(AOP(result),offset,FALSE,FALSE));
5963           break;
5964         case 0xff:
5965           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5966           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5967           pic14_emitcode("comf","%s,w",
5968                          aopGet(AOP(left),offset,FALSE,FALSE));
5969           pic14_emitcode("movwf","%s",
5970                          aopGet(AOP(result),offset,FALSE,FALSE));
5971           break;
5972         default:
5973           emitpcode(POC_MOVLW, popGetLit(t));
5974           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5975           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5976           pic14_emitcode("movlw","0x%x",t);
5977           pic14_emitcode("xorwf","%s,w",
5978                          aopGet(AOP(left),offset,FALSE,FALSE));
5979           pic14_emitcode("movwf","%s",
5980                          aopGet(AOP(result),offset,FALSE,FALSE));
5981
5982         }
5983         continue;
5984       }
5985
5986       // faster than result <- left, anl result,right
5987       // and better if result is SFR
5988       if (AOP_TYPE(left) == AOP_ACC) {
5989         emitpcode(POC_XORFW,popGet(AOP(right),offset));
5990         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5991       } else {
5992         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5993         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5994         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5995         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5996       }
5997       if ( AOP_TYPE(result) != AOP_ACC){
5998         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5999         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6000       }
6001     }
6002   }
6003
6004   release :
6005     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6006   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6007   freeAsmop(result,NULL,ic,TRUE);     
6008 }
6009
6010 /*-----------------------------------------------------------------*/
6011 /* genInline - write the inline code out                           */
6012 /*-----------------------------------------------------------------*/
6013 static void genInline (iCode *ic)
6014 {
6015     char *buffer, *bp, *bp1;
6016     
6017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6018
6019     _G.inLine += (!options.asmpeep);
6020
6021     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6022     strcpy(buffer,IC_INLINE(ic));
6023
6024     /* emit each line as a code */
6025     while (*bp) {
6026         if (*bp == '\n') {
6027             *bp++ = '\0';
6028
6029             if(*bp1)
6030               addpCode2pBlock(pb,AssembleLine(bp1));
6031             bp1 = bp;
6032         } else {
6033             if (*bp == ':') {
6034                 bp++;
6035                 *bp = '\0';
6036                 bp++;
6037                 pic14_emitcode(bp1,"");
6038                 bp1 = bp;
6039             } else
6040                 bp++;
6041         }
6042     }
6043     if ((bp1 != bp) && *bp1)
6044       addpCode2pBlock(pb,AssembleLine(bp1));
6045
6046     Safe_free(buffer);
6047
6048     _G.inLine -= (!options.asmpeep);
6049 }
6050
6051 /*-----------------------------------------------------------------*/
6052 /* genRRC - rotate right with carry                                */
6053 /*-----------------------------------------------------------------*/
6054 static void genRRC (iCode *ic)
6055 {
6056   operand *left , *result ;
6057   int size, offset = 0, same;
6058
6059   /* rotate right with carry */
6060   left = IC_LEFT(ic);
6061   result=IC_RESULT(ic);
6062   aopOp (left,ic,FALSE);
6063   aopOp (result,ic,FALSE);
6064
6065   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6066
6067   same = pic14_sameRegs(AOP(result),AOP(left));
6068
6069   size = AOP_SIZE(result);    
6070
6071   /* get the lsb and put it into the carry */
6072   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6073
6074   offset = 0 ;
6075
6076   while(size--) {
6077
6078     if(same) {
6079       emitpcode(POC_RRF, popGet(AOP(left),offset));
6080     } else {
6081       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6082       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6083     }
6084
6085     offset++;
6086   }
6087
6088   freeAsmop(left,NULL,ic,TRUE);
6089   freeAsmop(result,NULL,ic,TRUE);
6090 }
6091
6092 /*-----------------------------------------------------------------*/
6093 /* genRLC - generate code for rotate left with carry               */
6094 /*-----------------------------------------------------------------*/
6095 static void genRLC (iCode *ic)
6096 {    
6097   operand *left , *result ;
6098   int size, offset = 0;
6099   int same;
6100
6101   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6102   /* rotate right with carry */
6103   left = IC_LEFT(ic);
6104   result=IC_RESULT(ic);
6105   aopOp (left,ic,FALSE);
6106   aopOp (result,ic,FALSE);
6107
6108   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6109
6110   same = pic14_sameRegs(AOP(result),AOP(left));
6111
6112   /* move it to the result */
6113   size = AOP_SIZE(result);    
6114
6115   /* get the msb and put it into the carry */
6116   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6117
6118   offset = 0 ;
6119
6120   while(size--) {
6121
6122     if(same) {
6123       emitpcode(POC_RLF, popGet(AOP(left),offset));
6124     } else {
6125       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6126       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6127     }
6128
6129     offset++;
6130   }
6131
6132
6133   freeAsmop(left,NULL,ic,TRUE);
6134   freeAsmop(result,NULL,ic,TRUE);
6135 }
6136
6137 /*-----------------------------------------------------------------*/
6138 /* genGetHbit - generates code get highest order bit               */
6139 /*-----------------------------------------------------------------*/
6140 static void genGetHbit (iCode *ic)
6141 {
6142     operand *left, *result;
6143     left = IC_LEFT(ic);
6144     result=IC_RESULT(ic);
6145     aopOp (left,ic,FALSE);
6146     aopOp (result,ic,FALSE);
6147
6148     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6149     /* get the highest order byte into a */
6150     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6151     if(AOP_TYPE(result) == AOP_CRY){
6152         pic14_emitcode("rlc","a");
6153         pic14_outBitC(result);
6154     }
6155     else{
6156         pic14_emitcode("rl","a");
6157         pic14_emitcode("anl","a,#0x01");
6158         pic14_outAcc(result);
6159     }
6160
6161
6162     freeAsmop(left,NULL,ic,TRUE);
6163     freeAsmop(result,NULL,ic,TRUE);
6164 }
6165
6166 /*-----------------------------------------------------------------*/
6167 /* AccRol - rotate left accumulator by known count                 */
6168 /*-----------------------------------------------------------------*/
6169 static void AccRol (int shCount)
6170 {
6171     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6172     shCount &= 0x0007;              // shCount : 0..7
6173     switch(shCount){
6174         case 0 :
6175             break;
6176         case 1 :
6177             pic14_emitcode("rl","a");
6178             break;
6179         case 2 :
6180             pic14_emitcode("rl","a");
6181             pic14_emitcode("rl","a");
6182             break;
6183         case 3 :
6184             pic14_emitcode("swap","a");
6185             pic14_emitcode("rr","a");
6186             break;
6187         case 4 :
6188             pic14_emitcode("swap","a");
6189             break;
6190         case 5 :
6191             pic14_emitcode("swap","a");
6192             pic14_emitcode("rl","a");
6193             break;
6194         case 6 :
6195             pic14_emitcode("rr","a");
6196             pic14_emitcode("rr","a");
6197             break;
6198         case 7 :
6199             pic14_emitcode("rr","a");
6200             break;
6201     }
6202 }
6203
6204 /*-----------------------------------------------------------------*/
6205 /* AccLsh - left shift accumulator by known count                  */
6206 /*-----------------------------------------------------------------*/
6207 static void AccLsh (int shCount)
6208 {
6209     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6210     if(shCount != 0){
6211         if(shCount == 1)
6212             pic14_emitcode("add","a,acc");
6213         else 
6214             if(shCount == 2) {
6215             pic14_emitcode("add","a,acc");
6216             pic14_emitcode("add","a,acc");
6217         } else {
6218             /* rotate left accumulator */
6219             AccRol(shCount);
6220             /* and kill the lower order bits */
6221             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6222         }
6223     }
6224 }
6225
6226 /*-----------------------------------------------------------------*/
6227 /* AccRsh - right shift accumulator by known count                 */
6228 /*-----------------------------------------------------------------*/
6229 static void AccRsh (int shCount)
6230 {
6231     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6232     if(shCount != 0){
6233         if(shCount == 1){
6234             CLRC;
6235             pic14_emitcode("rrc","a");
6236         } else {
6237             /* rotate right accumulator */
6238             AccRol(8 - shCount);
6239             /* and kill the higher order bits */
6240             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6241         }
6242     }
6243 }
6244
6245 #if 0
6246 /*-----------------------------------------------------------------*/
6247 /* AccSRsh - signed right shift accumulator by known count                 */
6248 /*-----------------------------------------------------------------*/
6249 static void AccSRsh (int shCount)
6250 {
6251     symbol *tlbl ;
6252     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6253     if(shCount != 0){
6254         if(shCount == 1){
6255             pic14_emitcode("mov","c,acc.7");
6256             pic14_emitcode("rrc","a");
6257         } else if(shCount == 2){
6258             pic14_emitcode("mov","c,acc.7");
6259             pic14_emitcode("rrc","a");
6260             pic14_emitcode("mov","c,acc.7");
6261             pic14_emitcode("rrc","a");
6262         } else {
6263             tlbl = newiTempLabel(NULL);
6264             /* rotate right accumulator */
6265             AccRol(8 - shCount);
6266             /* and kill the higher order bits */
6267             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6268             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6269             pic14_emitcode("orl","a,#0x%02x",
6270                      (unsigned char)~SRMask[shCount]);
6271             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6272         }
6273     }
6274 }
6275 #endif
6276 /*-----------------------------------------------------------------*/
6277 /* shiftR1Left2Result - shift right one byte from left to result   */
6278 /*-----------------------------------------------------------------*/
6279 static void shiftR1Left2ResultSigned (operand *left, int offl,
6280                                 operand *result, int offr,
6281                                 int shCount)
6282 {
6283   int same;
6284
6285   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6286
6287   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6288
6289   switch(shCount) {
6290   case 1:
6291     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6292     if(same) 
6293       emitpcode(POC_RRF, popGet(AOP(result),offr));
6294     else {
6295       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6296       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6297     }
6298
6299     break;
6300   case 2:
6301
6302     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6303     if(same) 
6304       emitpcode(POC_RRF, popGet(AOP(result),offr));
6305     else {
6306       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6307       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6308     }
6309     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6310     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6311
6312     break;
6313
6314   case 3:
6315     if(same)
6316       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6317     else {
6318       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6319       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6320     }
6321
6322     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6323     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6324     emitpcode(POC_ANDLW, popGetLit(0x1f));
6325
6326     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6327     emitpcode(POC_IORLW, popGetLit(0xe0));
6328
6329     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6330     break;
6331
6332   case 4:
6333     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6334     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6335     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6336     emitpcode(POC_IORLW,  popGetLit(0xf0));
6337     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6338     break;
6339   case 5:
6340     if(same) {
6341       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6342     } else {
6343       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6344       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6345     }
6346     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6347     emitpcode(POC_ANDLW,  popGetLit(0x07));
6348     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6349     emitpcode(POC_IORLW,  popGetLit(0xf8));
6350     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6351     break;
6352
6353   case 6:
6354     if(same) {
6355       emitpcode(POC_MOVLW, popGetLit(0x00));
6356       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6357       emitpcode(POC_MOVLW, popGetLit(0xfe));
6358       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6359       emitpcode(POC_IORLW, popGetLit(0x01));
6360       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6361     } else {
6362       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6363       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6364       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6365       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6366       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6367     }
6368     break;
6369
6370   case 7:
6371     if(same) {
6372       emitpcode(POC_MOVLW, popGetLit(0x00));
6373       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6374       emitpcode(POC_MOVLW, popGetLit(0xff));
6375       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6376     } else {
6377       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6378       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6379       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6380     }
6381
6382   default:
6383     break;
6384   }
6385 }
6386
6387 /*-----------------------------------------------------------------*/
6388 /* shiftR1Left2Result - shift right one byte from left to result   */
6389 /*-----------------------------------------------------------------*/
6390 static void shiftR1Left2Result (operand *left, int offl,
6391                                 operand *result, int offr,
6392                                 int shCount, int sign)
6393 {
6394   int same;
6395
6396   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6397
6398   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6399
6400   /* Copy the msb into the carry if signed. */
6401   if(sign) {
6402     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6403     return;
6404   }
6405
6406
6407
6408   switch(shCount) {
6409   case 1:
6410     emitCLRC;
6411     if(same) 
6412       emitpcode(POC_RRF, popGet(AOP(result),offr));
6413     else {
6414       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6415       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416     }
6417     break;
6418   case 2:
6419     emitCLRC;
6420     if(same) {
6421       emitpcode(POC_RRF, popGet(AOP(result),offr));
6422     } else {
6423       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6424       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6425     }
6426     emitCLRC;
6427     emitpcode(POC_RRF, popGet(AOP(result),offr));
6428
6429     break;
6430   case 3:
6431     if(same)
6432       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6433     else {
6434       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6435       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436     }
6437
6438     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6439     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6440     emitpcode(POC_ANDLW, popGetLit(0x1f));
6441     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6442     break;
6443       
6444   case 4:
6445     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6446     emitpcode(POC_ANDLW, popGetLit(0x0f));
6447     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6448     break;
6449
6450   case 5:
6451     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6452     emitpcode(POC_ANDLW, popGetLit(0x0f));
6453     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6454     emitCLRC;
6455     emitpcode(POC_RRF, popGet(AOP(result),offr));
6456
6457     break;
6458   case 6:
6459
6460     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6461     emitpcode(POC_ANDLW, popGetLit(0x80));
6462     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6463     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6464     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6465     break;
6466
6467   case 7:
6468
6469     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6470     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6471     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6472
6473     break;
6474
6475   default:
6476     break;
6477   }
6478 }
6479
6480 /*-----------------------------------------------------------------*/
6481 /* shiftL1Left2Result - shift left one byte from left to result    */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftL1Left2Result (operand *left, int offl,
6484                                 operand *result, int offr, int shCount)
6485 {
6486   int same;
6487
6488   //    char *l;
6489   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6490
6491   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6492   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6493     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6494     //    MOVA(l);
6495     /* shift left accumulator */
6496     //AccLsh(shCount); // don't comment out just yet...
6497   //    aopPut(AOP(result),"a",offr);
6498
6499   switch(shCount) {
6500   case 1:
6501     /* Shift left 1 bit position */
6502     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6503     if(same) {
6504       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6505     } else {
6506       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6507       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6508     }
6509     break;
6510   case 2:
6511     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6512     emitpcode(POC_ANDLW,popGetLit(0x7e));
6513     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6514     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6515     break;
6516   case 3:
6517     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6518     emitpcode(POC_ANDLW,popGetLit(0x3e));
6519     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6520     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6521     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6522     break;
6523   case 4:
6524     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6525     emitpcode(POC_ANDLW, popGetLit(0xf0));
6526     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6527     break;
6528   case 5:
6529     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6530     emitpcode(POC_ANDLW, popGetLit(0xf0));
6531     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6532     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6533     break;
6534   case 6:
6535     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6536     emitpcode(POC_ANDLW, popGetLit(0x30));
6537     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6538     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6539     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6540     break;
6541   case 7:
6542     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6543     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6544     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6545     break;
6546
6547   default:
6548     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6549   }
6550
6551 }
6552
6553 /*-----------------------------------------------------------------*/
6554 /* movLeft2Result - move byte from left to result                  */
6555 /*-----------------------------------------------------------------*/
6556 static void movLeft2Result (operand *left, int offl,
6557                             operand *result, int offr)
6558 {
6559   char *l;
6560   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6561   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6562     l = aopGet(AOP(left),offl,FALSE,FALSE);
6563
6564     if (*l == '@' && (IS_AOP_PREG(result))) {
6565       pic14_emitcode("mov","a,%s",l);
6566       aopPut(AOP(result),"a",offr);
6567     } else {
6568       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6569       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6570     }
6571   }
6572 }
6573
6574 /*-----------------------------------------------------------------*/
6575 /* shiftL2Left2Result - shift left two bytes from left to result   */
6576 /*-----------------------------------------------------------------*/
6577 static void shiftL2Left2Result (operand *left, int offl,
6578                                 operand *result, int offr, int shCount)
6579 {
6580
6581
6582   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6583
6584   if(pic14_sameRegs(AOP(result), AOP(left))) {
6585     switch(shCount) {
6586     case 0:
6587       break;
6588     case 1:
6589     case 2:
6590     case 3:
6591
6592       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6593       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6594       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6595
6596       while(--shCount) {
6597         emitCLRC;
6598         emitpcode(POC_RLF, popGet(AOP(result),offr));
6599         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6600       }
6601
6602       break;
6603     case 4:
6604     case 5:
6605       emitpcode(POC_MOVLW, popGetLit(0x0f));
6606       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6607       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6608       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6609       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6610       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6611       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6612       if(shCount >=5) {
6613         emitpcode(POC_RLF, popGet(AOP(result),offr));
6614         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6615       }
6616       break;
6617     case 6:
6618       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6619       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6620       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6621       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6622       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6623       emitpcode(POC_ANDLW,popGetLit(0xc0));
6624       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6625       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6626       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6627       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6628       break;
6629     case 7:
6630       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6631       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6632       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6633       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6634       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6635     }
6636
6637   } else {
6638     switch(shCount) {
6639     case 0:
6640       break;
6641     case 1:
6642     case 2:
6643     case 3:
6644       /* note, use a mov/add for the shift since the mov has a
6645          chance of getting optimized out */
6646       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6647       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6648       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6649       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6650       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6651
6652       while(--shCount) {
6653         emitCLRC;
6654         emitpcode(POC_RLF, popGet(AOP(result),offr));
6655         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6656       }
6657       break;
6658
6659     case 4:
6660     case 5:
6661       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6662       emitpcode(POC_ANDLW, popGetLit(0xF0));
6663       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6664       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6665       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6666       emitpcode(POC_ANDLW, popGetLit(0xF0));
6667       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6668       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6669
6670
6671       if(shCount == 5) {
6672         emitpcode(POC_RLF, popGet(AOP(result),offr));
6673         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6674       }
6675       break;
6676     case 6:
6677       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6678       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6679       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6680       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6681
6682       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6683       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6684       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6685       emitpcode(POC_ANDLW,popGetLit(0xc0));
6686       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6687       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6688       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6689       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6690       break;
6691     case 7:
6692       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6693       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6694       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6695       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6696       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6697     }
6698   }
6699
6700 }
6701 /*-----------------------------------------------------------------*/
6702 /* shiftR2Left2Result - shift right two bytes from left to result  */
6703 /*-----------------------------------------------------------------*/
6704 static void shiftR2Left2Result (operand *left, int offl,
6705                                 operand *result, int offr,
6706                                 int shCount, int sign)
6707 {
6708   int same=0;
6709
6710   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6711   same = pic14_sameRegs(AOP(result), AOP(left));
6712
6713   if(same && ((offl + MSB16) == offr)){
6714     same=1;
6715     /* don't crash result[offr] */
6716     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6717     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6718   } else {
6719     movLeft2Result(left,offl, result, offr);
6720     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6721   }
6722   /* a:x >> shCount (x = lsb(result))*/
6723 /*
6724   if(sign)
6725     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6726   else {
6727     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6728 */
6729   switch(shCount) {
6730   case 0:
6731     break;
6732   case 1:
6733   case 2:
6734   case 3:
6735     if(sign)
6736       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6737     else
6738       emitCLRC;
6739
6740     if(same) {
6741       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6742       emitpcode(POC_RRF,popGet(AOP(result),offr));
6743     } else {
6744       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6745       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6747       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6748     }
6749
6750     while(--shCount) {
6751       if(sign)
6752         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6753       else
6754         emitCLRC;
6755       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6756       emitpcode(POC_RRF,popGet(AOP(result),offr));
6757     }
6758     break;
6759   case 4:
6760   case 5:
6761     if(same) {
6762
6763       emitpcode(POC_MOVLW, popGetLit(0xf0));
6764       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6765       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6766
6767       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6768       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6769       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6770       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6771     } else {
6772       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6773       emitpcode(POC_ANDLW, popGetLit(0x0f));
6774       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6775
6776       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6777       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6778       emitpcode(POC_ANDLW, popGetLit(0xf0));
6779       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6780       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6781     }
6782
6783     if(shCount >=5) {
6784       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6785       emitpcode(POC_RRF, popGet(AOP(result),offr));
6786     }
6787
6788     if(sign) {
6789       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6790       emitpcode(POC_BTFSC, 
6791                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6792       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6793     }
6794
6795     break;
6796
6797   case 6:
6798     if(same) {
6799
6800       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6801       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6802
6803       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6804       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6805       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6806       emitpcode(POC_ANDLW,popGetLit(0x03));
6807       if(sign) {
6808         emitpcode(POC_BTFSC, 
6809                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6810         emitpcode(POC_IORLW,popGetLit(0xfc));
6811       }
6812       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6813       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6814       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6815       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6816     } else {
6817       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6818       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6819       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6820       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6821       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6822       emitpcode(POC_ANDLW,popGetLit(0x03));
6823       if(sign) {
6824         emitpcode(POC_BTFSC, 
6825                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6826         emitpcode(POC_IORLW,popGetLit(0xfc));
6827       }
6828       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6829       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6830
6831         
6832     }
6833
6834     break;
6835   case 7:
6836     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6837     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6838     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6839     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6840     if(sign) {
6841       emitSKPNC;
6842       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6843     } else 
6844       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6845   }
6846 }
6847
6848
6849 /*-----------------------------------------------------------------*/
6850 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6851 /*-----------------------------------------------------------------*/
6852 static void shiftLLeftOrResult (operand *left, int offl,
6853                                 operand *result, int offr, int shCount)
6854 {
6855     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6856     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6857     /* shift left accumulator */
6858     AccLsh(shCount);
6859     /* or with result */
6860     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6861     /* back to result */
6862     aopPut(AOP(result),"a",offr);
6863 }
6864
6865 /*-----------------------------------------------------------------*/
6866 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6867 /*-----------------------------------------------------------------*/
6868 static void shiftRLeftOrResult (operand *left, int offl,
6869                                 operand *result, int offr, int shCount)
6870 {
6871     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6872     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6873     /* shift right accumulator */
6874     AccRsh(shCount);
6875     /* or with result */
6876     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6877     /* back to result */
6878     aopPut(AOP(result),"a",offr);
6879 }
6880
6881 /*-----------------------------------------------------------------*/
6882 /* genlshOne - left shift a one byte quantity by known count       */
6883 /*-----------------------------------------------------------------*/
6884 static void genlshOne (operand *result, operand *left, int shCount)
6885 {       
6886     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6887     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6888 }
6889
6890 /*-----------------------------------------------------------------*/
6891 /* genlshTwo - left shift two bytes by known amount != 0           */
6892 /*-----------------------------------------------------------------*/
6893 static void genlshTwo (operand *result,operand *left, int shCount)
6894 {
6895     int size;
6896     
6897     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6898     size = pic14_getDataSize(result);
6899
6900     /* if shCount >= 8 */
6901     if (shCount >= 8) {
6902         shCount -= 8 ;
6903
6904         if (size > 1){
6905             if (shCount)
6906                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6907             else 
6908                 movLeft2Result(left, LSB, result, MSB16);
6909         }
6910         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6911     }
6912
6913     /*  1 <= shCount <= 7 */
6914     else {  
6915         if(size == 1)
6916             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6917         else 
6918             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6919     }
6920 }
6921
6922 /*-----------------------------------------------------------------*/
6923 /* shiftLLong - shift left one long from left to result            */
6924 /* offl = LSB or MSB16                                             */
6925 /*-----------------------------------------------------------------*/
6926 static void shiftLLong (operand *left, operand *result, int offr )
6927 {
6928     char *l;
6929     int size = AOP_SIZE(result);
6930
6931     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6932     if(size >= LSB+offr){
6933         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6934         MOVA(l);
6935         pic14_emitcode("add","a,acc");
6936         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6937             size >= MSB16+offr && offr != LSB )
6938             pic14_emitcode("xch","a,%s",
6939                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6940         else        
6941             aopPut(AOP(result),"a",LSB+offr);
6942     }
6943
6944     if(size >= MSB16+offr){
6945         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6946             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6947             MOVA(l);
6948         }
6949         pic14_emitcode("rlc","a");
6950         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6951             size >= MSB24+offr && offr != LSB)
6952             pic14_emitcode("xch","a,%s",
6953                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6954         else        
6955             aopPut(AOP(result),"a",MSB16+offr);
6956     }
6957
6958     if(size >= MSB24+offr){
6959         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6960             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6961             MOVA(l);
6962         }
6963         pic14_emitcode("rlc","a");
6964         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6965             size >= MSB32+offr && offr != LSB )
6966             pic14_emitcode("xch","a,%s",
6967                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6968         else        
6969             aopPut(AOP(result),"a",MSB24+offr);
6970     }
6971
6972     if(size > MSB32+offr){
6973         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6974             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6975             MOVA(l);    
6976         }
6977         pic14_emitcode("rlc","a");
6978         aopPut(AOP(result),"a",MSB32+offr);
6979     }
6980     if(offr != LSB)
6981         aopPut(AOP(result),zero,LSB);       
6982 }
6983
6984 /*-----------------------------------------------------------------*/
6985 /* genlshFour - shift four byte by a known amount != 0             */
6986 /*-----------------------------------------------------------------*/
6987 static void genlshFour (operand *result, operand *left, int shCount)
6988 {
6989     int size;
6990
6991     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6992     size = AOP_SIZE(result);
6993
6994     /* if shifting more that 3 bytes */
6995     if (shCount >= 24 ) {
6996         shCount -= 24;
6997         if (shCount)
6998             /* lowest order of left goes to the highest
6999             order of the destination */
7000             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7001         else
7002             movLeft2Result(left, LSB, result, MSB32);
7003         aopPut(AOP(result),zero,LSB);
7004         aopPut(AOP(result),zero,MSB16);
7005         aopPut(AOP(result),zero,MSB32);
7006         return;
7007     }
7008
7009     /* more than two bytes */
7010     else if ( shCount >= 16 ) {
7011         /* lower order two bytes goes to higher order two bytes */
7012         shCount -= 16;
7013         /* if some more remaining */
7014         if (shCount)
7015             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7016         else {
7017             movLeft2Result(left, MSB16, result, MSB32);
7018             movLeft2Result(left, LSB, result, MSB24);
7019         }
7020         aopPut(AOP(result),zero,MSB16);
7021         aopPut(AOP(result),zero,LSB);
7022         return;
7023     }    
7024
7025     /* if more than 1 byte */
7026     else if ( shCount >= 8 ) {
7027         /* lower order three bytes goes to higher order  three bytes */
7028         shCount -= 8;
7029         if(size == 2){
7030             if(shCount)
7031                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7032             else
7033                 movLeft2Result(left, LSB, result, MSB16);
7034         }
7035         else{   /* size = 4 */
7036             if(shCount == 0){
7037                 movLeft2Result(left, MSB24, result, MSB32);
7038                 movLeft2Result(left, MSB16, result, MSB24);
7039                 movLeft2Result(left, LSB, result, MSB16);
7040                 aopPut(AOP(result),zero,LSB);
7041             }
7042             else if(shCount == 1)
7043                 shiftLLong(left, result, MSB16);
7044             else{
7045                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7046                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7047                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7048                 aopPut(AOP(result),zero,LSB);
7049             }
7050         }
7051     }
7052
7053     /* 1 <= shCount <= 7 */
7054     else if(shCount <= 2){
7055         shiftLLong(left, result, LSB);
7056         if(shCount == 2)
7057             shiftLLong(result, result, LSB);
7058     }
7059     /* 3 <= shCount <= 7, optimize */
7060     else{
7061         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7062         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7063         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7064     }
7065 }
7066
7067 /*-----------------------------------------------------------------*/
7068 /* genLeftShiftLiteral - left shifting by known count              */
7069 /*-----------------------------------------------------------------*/
7070 static void genLeftShiftLiteral (operand *left,
7071                                  operand *right,
7072                                  operand *result,
7073                                  iCode *ic)
7074 {    
7075     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7076     int size;
7077
7078     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7079     freeAsmop(right,NULL,ic,TRUE);
7080
7081     aopOp(left,ic,FALSE);
7082     aopOp(result,ic,FALSE);
7083
7084     size = getSize(operandType(result));
7085
7086 #if VIEW_SIZE
7087     pic14_emitcode("; shift left ","result %d, left %d",size,
7088              AOP_SIZE(left));
7089 #endif
7090
7091     /* I suppose that the left size >= result size */
7092     if(shCount == 0){
7093         while(size--){
7094             movLeft2Result(left, size, result, size);
7095         }
7096     }
7097
7098     else if(shCount >= (size * 8))
7099         while(size--)
7100             aopPut(AOP(result),zero,size);
7101     else{
7102         switch (size) {
7103             case 1:
7104                 genlshOne (result,left,shCount);
7105                 break;
7106
7107             case 2:
7108             case 3:
7109                 genlshTwo (result,left,shCount);
7110                 break;
7111
7112             case 4:
7113                 genlshFour (result,left,shCount);
7114                 break;
7115         }
7116     }
7117     freeAsmop(left,NULL,ic,TRUE);
7118     freeAsmop(result,NULL,ic,TRUE);
7119 }
7120
7121 /*-----------------------------------------------------------------*
7122  * genMultiAsm - repeat assembly instruction for size of register.
7123  * if endian == 1, then the high byte (i.e base address + size of 
7124  * register) is used first else the low byte is used first;
7125  *-----------------------------------------------------------------*/
7126 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7127 {
7128
7129   int offset = 0;
7130
7131   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7132
7133   if(!reg)
7134     return;
7135
7136   if(!endian) {
7137     endian = 1;
7138   } else {
7139     endian = -1;
7140     offset = size-1;
7141   }
7142
7143   while(size--) {
7144     emitpcode(poc,    popGet(AOP(reg),offset));
7145     offset += endian;
7146   }
7147
7148 }
7149 /*-----------------------------------------------------------------*/
7150 /* genLeftShift - generates code for left shifting                 */
7151 /*-----------------------------------------------------------------*/
7152 static void genLeftShift (iCode *ic)
7153 {
7154   operand *left,*right, *result;
7155   int size, offset;
7156   char *l;
7157   symbol *tlbl , *tlbl1;
7158   pCodeOp *pctemp;
7159
7160   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7161
7162   right = IC_RIGHT(ic);
7163   left  = IC_LEFT(ic);
7164   result = IC_RESULT(ic);
7165
7166   aopOp(right,ic,FALSE);
7167
7168   /* if the shift count is known then do it 
7169      as efficiently as possible */
7170   if (AOP_TYPE(right) == AOP_LIT) {
7171     genLeftShiftLiteral (left,right,result,ic);
7172     return ;
7173   }
7174
7175   /* shift count is unknown then we have to form 
7176      a loop get the loop count in B : Note: we take
7177      only the lower order byte since shifting
7178      more that 32 bits make no sense anyway, ( the
7179      largest size of an object can be only 32 bits ) */  
7180
7181     
7182   aopOp(left,ic,FALSE);
7183   aopOp(result,ic,FALSE);
7184
7185   /* now move the left to the result if they are not the
7186      same */
7187   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7188       AOP_SIZE(result) > 1) {
7189
7190     size = AOP_SIZE(result);
7191     offset=0;
7192     while (size--) {
7193       l = aopGet(AOP(left),offset,FALSE,TRUE);
7194       if (*l == '@' && (IS_AOP_PREG(result))) {
7195
7196         pic14_emitcode("mov","a,%s",l);
7197         aopPut(AOP(result),"a",offset);
7198       } else {
7199         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7200         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7201         //aopPut(AOP(result),l,offset);
7202       }
7203       offset++;
7204     }
7205   }
7206
7207   size = AOP_SIZE(result);
7208
7209   /* if it is only one byte then */
7210   if (size == 1) {
7211     if(optimized_for_speed) {
7212       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7213       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7214       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7215       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7216       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7217       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7218       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7219       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7220       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7221       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7222       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7223       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7224     } else {
7225
7226       tlbl = newiTempLabel(NULL);
7227       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7228         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7229         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7230       }
7231
7232       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7233       emitpcode(POC_RRF,    popGet(AOP(result),0));
7234       emitpLabel(tlbl->key);
7235       emitpcode(POC_RLF,    popGet(AOP(result),0));
7236       emitpcode(POC_ADDLW,  popGetLit(1));
7237       emitSKPC;
7238       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7239     }
7240     goto release ;
7241   }
7242     
7243   if (pic14_sameRegs(AOP(left),AOP(result))) {
7244
7245     tlbl = newiTempLabel(NULL);
7246     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7247     genMultiAsm(POC_RRF, result, size,1);
7248     emitpLabel(tlbl->key);
7249     genMultiAsm(POC_RLF, result, size,0);
7250     emitpcode(POC_ADDLW,  popGetLit(1));
7251     emitSKPC;
7252     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7253     goto release;
7254   }
7255
7256   //tlbl = newiTempLabel(NULL);
7257   //offset = 0 ;   
7258   //tlbl1 = newiTempLabel(NULL);
7259
7260   //reAdjustPreg(AOP(result));    
7261     
7262   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7263   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7264   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7265   //MOVA(l);
7266   //pic14_emitcode("add","a,acc");         
7267   //aopPut(AOP(result),"a",offset++);
7268   //while (--size) {
7269   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7270   //  MOVA(l);
7271   //  pic14_emitcode("rlc","a");         
7272   //  aopPut(AOP(result),"a",offset++);
7273   //}
7274   //reAdjustPreg(AOP(result));
7275
7276   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7277   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7278
7279
7280   tlbl = newiTempLabel(NULL);
7281   tlbl1= newiTempLabel(NULL);
7282
7283   size = AOP_SIZE(result);
7284   offset = 1;
7285
7286   pctemp = popGetTempReg();  /* grab a temporary working register. */
7287
7288   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7289
7290   /* offset should be 0, 1 or 3 */
7291   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7292   emitSKPNZ;
7293   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7294
7295   emitpcode(POC_MOVWF, pctemp);
7296
7297
7298   emitpLabel(tlbl->key);
7299
7300   emitCLRC;
7301   emitpcode(POC_RLF,  popGet(AOP(result),0));
7302   while(--size)
7303     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7304
7305   emitpcode(POC_DECFSZ,  pctemp);
7306   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7307   emitpLabel(tlbl1->key);
7308
7309   popReleaseTempReg(pctemp);
7310
7311
7312  release:
7313   freeAsmop (right,NULL,ic,TRUE);
7314   freeAsmop(left,NULL,ic,TRUE);
7315   freeAsmop(result,NULL,ic,TRUE);
7316 }
7317
7318 /*-----------------------------------------------------------------*/
7319 /* genrshOne - right shift a one byte quantity by known count      */
7320 /*-----------------------------------------------------------------*/
7321 static void genrshOne (operand *result, operand *left,
7322                        int shCount, int sign)
7323 {
7324     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7325     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7326 }
7327
7328 /*-----------------------------------------------------------------*/
7329 /* genrshTwo - right shift two bytes by known amount != 0          */
7330 /*-----------------------------------------------------------------*/
7331 static void genrshTwo (operand *result,operand *left,
7332                        int shCount, int sign)
7333 {
7334   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7335   /* if shCount >= 8 */
7336   if (shCount >= 8) {
7337     shCount -= 8 ;
7338     if (shCount)
7339       shiftR1Left2Result(left, MSB16, result, LSB,
7340                          shCount, sign);
7341     else
7342       movLeft2Result(left, MSB16, result, LSB);
7343
7344     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7345
7346     if(sign) {
7347       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7348       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7349     }
7350   }
7351
7352   /*  1 <= shCount <= 7 */
7353   else
7354     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7355 }
7356
7357 /*-----------------------------------------------------------------*/
7358 /* shiftRLong - shift right one long from left to result           */
7359 /* offl = LSB or MSB16                                             */
7360 /*-----------------------------------------------------------------*/
7361 static void shiftRLong (operand *left, int offl,
7362                         operand *result, int sign)
7363 {
7364     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7365     if(!sign)
7366         pic14_emitcode("clr","c");
7367     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7368     if(sign)
7369         pic14_emitcode("mov","c,acc.7");
7370     pic14_emitcode("rrc","a");
7371     aopPut(AOP(result),"a",MSB32-offl);
7372     if(offl == MSB16)
7373         /* add sign of "a" */
7374         addSign(result, MSB32, sign);
7375
7376     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7377     pic14_emitcode("rrc","a");
7378     aopPut(AOP(result),"a",MSB24-offl);
7379
7380     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7381     pic14_emitcode("rrc","a");
7382     aopPut(AOP(result),"a",MSB16-offl);
7383
7384     if(offl == LSB){
7385         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7386         pic14_emitcode("rrc","a");
7387         aopPut(AOP(result),"a",LSB);
7388     }
7389 }
7390
7391 /*-----------------------------------------------------------------*/
7392 /* genrshFour - shift four byte by a known amount != 0             */
7393 /*-----------------------------------------------------------------*/
7394 static void genrshFour (operand *result, operand *left,
7395                         int shCount, int sign)
7396 {
7397   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7398   /* if shifting more that 3 bytes */
7399   if(shCount >= 24 ) {
7400     shCount -= 24;
7401     if(shCount)
7402       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7403     else
7404       movLeft2Result(left, MSB32, result, LSB);
7405
7406     addSign(result, MSB16, sign);
7407   }
7408   else if(shCount >= 16){
7409     shCount -= 16;
7410     if(shCount)
7411       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7412     else{
7413       movLeft2Result(left, MSB24, result, LSB);
7414       movLeft2Result(left, MSB32, result, MSB16);
7415     }
7416     addSign(result, MSB24, sign);
7417   }
7418   else if(shCount >= 8){
7419     shCount -= 8;
7420     if(shCount == 1)
7421       shiftRLong(left, MSB16, result, sign);
7422     else if(shCount == 0){
7423       movLeft2Result(left, MSB16, result, LSB);
7424       movLeft2Result(left, MSB24, result, MSB16);
7425       movLeft2Result(left, MSB32, result, MSB24);
7426       addSign(result, MSB32, sign);
7427     }
7428     else{
7429       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7430       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7431       /* the last shift is signed */
7432       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7433       addSign(result, MSB32, sign);
7434     }
7435   }
7436   else{   /* 1 <= shCount <= 7 */
7437     if(shCount <= 2){
7438       shiftRLong(left, LSB, result, sign);
7439       if(shCount == 2)
7440         shiftRLong(result, LSB, result, sign);
7441     }
7442     else{
7443       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7444       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7445       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7446     }
7447   }
7448 }
7449
7450 /*-----------------------------------------------------------------*/
7451 /* genRightShiftLiteral - right shifting by known count            */
7452 /*-----------------------------------------------------------------*/
7453 static void genRightShiftLiteral (operand *left,
7454                                   operand *right,
7455                                   operand *result,
7456                                   iCode *ic,
7457                                   int sign)
7458 {    
7459   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7460   int lsize,res_size;
7461
7462   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7463   freeAsmop(right,NULL,ic,TRUE);
7464
7465   aopOp(left,ic,FALSE);
7466   aopOp(result,ic,FALSE);
7467
7468 #if VIEW_SIZE
7469   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7470                  AOP_SIZE(left));
7471 #endif
7472
7473   lsize = pic14_getDataSize(left);
7474   res_size = pic14_getDataSize(result);
7475   /* test the LEFT size !!! */
7476
7477   /* I suppose that the left size >= result size */
7478   if(shCount == 0){
7479     while(res_size--)
7480       movLeft2Result(left, lsize, result, res_size);
7481   }
7482
7483   else if(shCount >= (lsize * 8)){
7484
7485     if(res_size == 1) {
7486       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7487       if(sign) {
7488         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7489         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7490       }
7491     } else {
7492
7493       if(sign) {
7494         emitpcode(POC_MOVLW, popGetLit(0));
7495         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7496         emitpcode(POC_MOVLW, popGetLit(0xff));
7497         while(res_size--)
7498           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7499
7500       } else {
7501
7502         while(res_size--)
7503           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7504       }
7505     }
7506   } else {
7507
7508     switch (res_size) {
7509     case 1:
7510       genrshOne (result,left,shCount,sign);
7511       break;
7512
7513     case 2:
7514       genrshTwo (result,left,shCount,sign);
7515       break;
7516
7517     case 4:
7518       genrshFour (result,left,shCount,sign);
7519       break;
7520     default :
7521       break;
7522     }
7523
7524   }
7525
7526   freeAsmop(left,NULL,ic,TRUE);
7527   freeAsmop(result,NULL,ic,TRUE);
7528 }
7529
7530 /*-----------------------------------------------------------------*/
7531 /* genSignedRightShift - right shift of signed number              */
7532 /*-----------------------------------------------------------------*/
7533 static void genSignedRightShift (iCode *ic)
7534 {
7535   operand *right, *left, *result;
7536   int size, offset;
7537   //  char *l;
7538   symbol *tlbl, *tlbl1 ;
7539   pCodeOp *pctemp;
7540
7541   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7542
7543   /* we do it the hard way put the shift count in b
7544      and loop thru preserving the sign */
7545   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7546
7547   right = IC_RIGHT(ic);
7548   left  = IC_LEFT(ic);
7549   result = IC_RESULT(ic);
7550
7551   aopOp(right,ic,FALSE);  
7552   aopOp(left,ic,FALSE);
7553   aopOp(result,ic,FALSE);
7554
7555
7556   if ( AOP_TYPE(right) == AOP_LIT) {
7557     genRightShiftLiteral (left,right,result,ic,1);
7558     return ;
7559   }
7560   /* shift count is unknown then we have to form 
7561      a loop get the loop count in B : Note: we take
7562      only the lower order byte since shifting
7563      more that 32 bits make no sense anyway, ( the
7564      largest size of an object can be only 32 bits ) */  
7565
7566   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7567   //pic14_emitcode("inc","b");
7568   //freeAsmop (right,NULL,ic,TRUE);
7569   //aopOp(left,ic,FALSE);
7570   //aopOp(result,ic,FALSE);
7571
7572   /* now move the left to the result if they are not the
7573      same */
7574   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7575       AOP_SIZE(result) > 1) {
7576
7577     size = AOP_SIZE(result);
7578     offset=0;
7579     while (size--) { 
7580       /*
7581         l = aopGet(AOP(left),offset,FALSE,TRUE);
7582         if (*l == '@' && IS_AOP_PREG(result)) {
7583
7584         pic14_emitcode("mov","a,%s",l);
7585         aopPut(AOP(result),"a",offset);
7586         } else
7587         aopPut(AOP(result),l,offset);
7588       */
7589       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7590       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7591
7592       offset++;
7593     }
7594   }
7595
7596   /* mov the highest order bit to OVR */    
7597   tlbl = newiTempLabel(NULL);
7598   tlbl1= newiTempLabel(NULL);
7599
7600   size = AOP_SIZE(result);
7601   offset = size - 1;
7602
7603   pctemp = popGetTempReg();  /* grab a temporary working register. */
7604
7605   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7606
7607   /* offset should be 0, 1 or 3 */
7608   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7609   emitSKPNZ;
7610   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7611
7612   emitpcode(POC_MOVWF, pctemp);
7613
7614
7615   emitpLabel(tlbl->key);
7616
7617   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7618   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7619
7620   while(--size) {
7621     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7622   }
7623
7624   emitpcode(POC_DECFSZ,  pctemp);
7625   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7626   emitpLabel(tlbl1->key);
7627
7628   popReleaseTempReg(pctemp);
7629 #if 0
7630   size = AOP_SIZE(result);
7631   offset = size - 1;
7632   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7633   pic14_emitcode("rlc","a");
7634   pic14_emitcode("mov","ov,c");
7635   /* if it is only one byte then */
7636   if (size == 1) {
7637     l = aopGet(AOP(left),0,FALSE,FALSE);
7638     MOVA(l);
7639     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7640     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7641     pic14_emitcode("mov","c,ov");
7642     pic14_emitcode("rrc","a");
7643     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7644     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7645     aopPut(AOP(result),"a",0);
7646     goto release ;
7647   }
7648
7649   reAdjustPreg(AOP(result));
7650   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7651   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7652   pic14_emitcode("mov","c,ov");
7653   while (size--) {
7654     l = aopGet(AOP(result),offset,FALSE,FALSE);
7655     MOVA(l);
7656     pic14_emitcode("rrc","a");         
7657     aopPut(AOP(result),"a",offset--);
7658   }
7659   reAdjustPreg(AOP(result));
7660   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7661   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7662
7663  release:
7664 #endif
7665
7666   freeAsmop(left,NULL,ic,TRUE);
7667   freeAsmop(result,NULL,ic,TRUE);
7668   freeAsmop(right,NULL,ic,TRUE);
7669 }
7670
7671 /*-----------------------------------------------------------------*/
7672 /* genRightShift - generate code for right shifting                */
7673 /*-----------------------------------------------------------------*/
7674 static void genRightShift (iCode *ic)
7675 {
7676     operand *right, *left, *result;
7677     sym_link *retype ;
7678     int size, offset;
7679     char *l;
7680     symbol *tlbl, *tlbl1 ;
7681
7682     /* if signed then we do it the hard way preserve the
7683     sign bit moving it inwards */
7684     retype = getSpec(operandType(IC_RESULT(ic)));
7685     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7686
7687     if (!SPEC_USIGN(retype)) {
7688         genSignedRightShift (ic);
7689         return ;
7690     }
7691
7692     /* signed & unsigned types are treated the same : i.e. the
7693     signed is NOT propagated inwards : quoting from the
7694     ANSI - standard : "for E1 >> E2, is equivalent to division
7695     by 2**E2 if unsigned or if it has a non-negative value,
7696     otherwise the result is implementation defined ", MY definition
7697     is that the sign does not get propagated */
7698
7699     right = IC_RIGHT(ic);
7700     left  = IC_LEFT(ic);
7701     result = IC_RESULT(ic);
7702
7703     aopOp(right,ic,FALSE);
7704
7705     /* if the shift count is known then do it 
7706     as efficiently as possible */
7707     if (AOP_TYPE(right) == AOP_LIT) {
7708         genRightShiftLiteral (left,right,result,ic, 0);
7709         return ;
7710     }
7711
7712     /* shift count is unknown then we have to form 
7713     a loop get the loop count in B : Note: we take
7714     only the lower order byte since shifting
7715     more that 32 bits make no sense anyway, ( the
7716     largest size of an object can be only 32 bits ) */  
7717
7718     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7719     pic14_emitcode("inc","b");
7720     aopOp(left,ic,FALSE);
7721     aopOp(result,ic,FALSE);
7722
7723     /* now move the left to the result if they are not the
7724     same */
7725     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7726         AOP_SIZE(result) > 1) {
7727
7728         size = AOP_SIZE(result);
7729         offset=0;
7730         while (size--) {
7731             l = aopGet(AOP(left),offset,FALSE,TRUE);
7732             if (*l == '@' && IS_AOP_PREG(result)) {
7733
7734                 pic14_emitcode("mov","a,%s",l);
7735                 aopPut(AOP(result),"a",offset);
7736             } else
7737                 aopPut(AOP(result),l,offset);
7738             offset++;
7739         }
7740     }
7741
7742     tlbl = newiTempLabel(NULL);
7743     tlbl1= newiTempLabel(NULL);
7744     size = AOP_SIZE(result);
7745     offset = size - 1;
7746
7747     /* if it is only one byte then */
7748     if (size == 1) {
7749
7750       tlbl = newiTempLabel(NULL);
7751       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7752         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7753         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7754       }
7755
7756       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7757       emitpcode(POC_RLF,    popGet(AOP(result),0));
7758       emitpLabel(tlbl->key);
7759       emitpcode(POC_RRF,    popGet(AOP(result),0));
7760       emitpcode(POC_ADDLW,  popGetLit(1));
7761       emitSKPC;
7762       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7763
7764       goto release ;
7765     }
7766
7767     reAdjustPreg(AOP(result));
7768     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7769     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7770     CLRC;
7771     while (size--) {
7772         l = aopGet(AOP(result),offset,FALSE,FALSE);
7773         MOVA(l);
7774         pic14_emitcode("rrc","a");         
7775         aopPut(AOP(result),"a",offset--);
7776     }
7777     reAdjustPreg(AOP(result));
7778
7779     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7780     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7781
7782 release:
7783     freeAsmop(left,NULL,ic,TRUE);
7784     freeAsmop (right,NULL,ic,TRUE);
7785     freeAsmop(result,NULL,ic,TRUE);
7786 }
7787
7788 /*-----------------------------------------------------------------*/
7789 /* genUnpackBits - generates code for unpacking bits               */
7790 /*-----------------------------------------------------------------*/
7791 static void genUnpackBits (operand *result, char *rname, int ptype)
7792 {    
7793     int shCnt ;
7794     int rlen = 0 ;
7795     sym_link *etype;
7796     int offset = 0 ;
7797
7798     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7799     etype = getSpec(operandType(result));
7800
7801     /* read the first byte  */
7802     switch (ptype) {
7803
7804     case POINTER:
7805     case IPOINTER:
7806         pic14_emitcode("mov","a,@%s",rname);
7807         break;
7808         
7809     case PPOINTER:
7810         pic14_emitcode("movx","a,@%s",rname);
7811         break;
7812         
7813     case FPOINTER:
7814         pic14_emitcode("movx","a,@dptr");
7815         break;
7816
7817     case CPOINTER:
7818         pic14_emitcode("clr","a");
7819         pic14_emitcode("movc","a","@a+dptr");
7820         break;
7821
7822     case GPOINTER:
7823         pic14_emitcode("lcall","__gptrget");
7824         break;
7825     }
7826
7827     /* if we have bitdisplacement then it fits   */
7828     /* into this byte completely or if length is */
7829     /* less than a byte                          */
7830     if ((shCnt = SPEC_BSTR(etype)) || 
7831         (SPEC_BLEN(etype) <= 8))  {
7832
7833         /* shift right acc */
7834         AccRsh(shCnt);
7835
7836         pic14_emitcode("anl","a,#0x%02x",
7837                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7838         aopPut(AOP(result),"a",offset);
7839         return ;
7840     }
7841
7842     /* bit field did not fit in a byte  */
7843     rlen = SPEC_BLEN(etype) - 8;
7844     aopPut(AOP(result),"a",offset++);
7845
7846     while (1)  {
7847
7848         switch (ptype) {
7849         case POINTER:
7850         case IPOINTER:
7851             pic14_emitcode("inc","%s",rname);
7852             pic14_emitcode("mov","a,@%s",rname);
7853             break;
7854             
7855         case PPOINTER:
7856             pic14_emitcode("inc","%s",rname);
7857             pic14_emitcode("movx","a,@%s",rname);
7858             break;
7859
7860         case FPOINTER:
7861             pic14_emitcode("inc","dptr");
7862             pic14_emitcode("movx","a,@dptr");
7863             break;
7864             
7865         case CPOINTER:
7866             pic14_emitcode("clr","a");
7867             pic14_emitcode("inc","dptr");
7868             pic14_emitcode("movc","a","@a+dptr");
7869             break;
7870             
7871         case GPOINTER:
7872             pic14_emitcode("inc","dptr");
7873             pic14_emitcode("lcall","__gptrget");
7874             break;
7875         }
7876
7877         rlen -= 8;            
7878         /* if we are done */
7879         if ( rlen <= 0 )
7880             break ;
7881         
7882         aopPut(AOP(result),"a",offset++);
7883                               
7884     }
7885     
7886     if (rlen) {
7887         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7888         aopPut(AOP(result),"a",offset);        
7889     }
7890     
7891     return ;
7892 }
7893
7894 #if 0
7895 /*-----------------------------------------------------------------*/
7896 /* genDataPointerGet - generates code when ptr offset is known     */
7897 /*-----------------------------------------------------------------*/
7898 static void genDataPointerGet (operand *left, 
7899                                operand *result, 
7900                                iCode *ic)
7901 {
7902   int size , offset = 0;
7903
7904
7905   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7906
7907
7908   /* optimization - most of the time, left and result are the same
7909    * address, but different types. for the pic code, we could omit
7910    * the following
7911    */
7912
7913   aopOp(result,ic,TRUE);
7914
7915   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7916
7917   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7918
7919   size = AOP_SIZE(result);
7920
7921   while (size--) {
7922     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7923     offset++;
7924   }
7925
7926   freeAsmop(left,NULL,ic,TRUE);
7927   freeAsmop(result,NULL,ic,TRUE);
7928 }
7929 #endif
7930 /*-----------------------------------------------------------------*/
7931 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7932 /*-----------------------------------------------------------------*/
7933 static void genNearPointerGet (operand *left, 
7934                                operand *result, 
7935                                iCode *ic)
7936 {
7937     asmop *aop = NULL;
7938     //regs *preg = NULL ;
7939     char *rname ;
7940     sym_link *rtype, *retype;
7941     sym_link *ltype = operandType(left);    
7942     //char buffer[80];
7943
7944     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7945
7946     rtype = operandType(result);
7947     retype= getSpec(rtype);
7948     
7949     aopOp(left,ic,FALSE);
7950     
7951     /* if left is rematerialisable and
7952        result is not bit variable type and
7953        the left is pointer to data space i.e
7954        lower 128 bytes of space */
7955     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7956         !IS_BITVAR(retype)         &&
7957         DCL_TYPE(ltype) == POINTER) {
7958       //genDataPointerGet (left,result,ic);
7959         return ;
7960     }
7961     
7962     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7963
7964         /* if the value is already in a pointer register
7965        then don't need anything more */
7966     if (!AOP_INPREG(AOP(left))) {
7967         /* otherwise get a free pointer register */
7968     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7969 /*
7970         aop = newAsmop(0);
7971         preg = getFreePtr(ic,&aop,FALSE);
7972         pic14_emitcode("mov","%s,%s",
7973                 preg->name,
7974                 aopGet(AOP(left),0,FALSE,TRUE));
7975         rname = preg->name ;
7976 */
7977     rname ="BAD";
7978     } else
7979         rname = aopGet(AOP(left),0,FALSE,FALSE);
7980     
7981     aopOp (result,ic,FALSE);
7982     
7983       /* if bitfield then unpack the bits */
7984     if (IS_BITVAR(retype)) 
7985         genUnpackBits (result,rname,POINTER);
7986     else {
7987         /* we have can just get the values */
7988       int size = AOP_SIZE(result);
7989       int offset = 0 ;  
7990         
7991       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7992
7993       emitpcode(POC_MOVFW,popGet(AOP(left),0));
7994       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7995       while(size--) {
7996         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7997         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7998         if(size)
7999           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8000       }
8001 /*
8002         while (size--) {
8003             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8004
8005                 pic14_emitcode("mov","a,@%s",rname);
8006                 aopPut(AOP(result),"a",offset);
8007             } else {
8008                 sprintf(buffer,"@%s",rname);
8009                 aopPut(AOP(result),buffer,offset);
8010             }
8011             offset++ ;
8012             if (size)
8013                 pic14_emitcode("inc","%s",rname);
8014         }
8015 */
8016     }
8017
8018     /* now some housekeeping stuff */
8019     if (aop) {
8020         /* we had to allocate for this iCode */
8021     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8022         freeAsmop(NULL,aop,ic,TRUE);
8023     } else { 
8024         /* we did not allocate which means left
8025            already in a pointer register, then
8026            if size > 0 && this could be used again
8027            we have to point it back to where it 
8028            belongs */
8029     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8030         if (AOP_SIZE(result) > 1 &&
8031             !OP_SYMBOL(left)->remat &&
8032             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8033               ic->depth )) {
8034             int size = AOP_SIZE(result) - 1;
8035             while (size--)
8036                 pic14_emitcode("dec","%s",rname);
8037         }
8038     }
8039
8040     /* done */
8041     freeAsmop(left,NULL,ic,TRUE);
8042     freeAsmop(result,NULL,ic,TRUE);
8043      
8044 }
8045
8046 /*-----------------------------------------------------------------*/
8047 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8048 /*-----------------------------------------------------------------*/
8049 static void genPagedPointerGet (operand *left, 
8050                                operand *result, 
8051                                iCode *ic)
8052 {
8053     asmop *aop = NULL;
8054     regs *preg = NULL ;
8055     char *rname ;
8056     sym_link *rtype, *retype;    
8057
8058     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8059
8060     rtype = operandType(result);
8061     retype= getSpec(rtype);
8062     
8063     aopOp(left,ic,FALSE);
8064
8065   /* if the value is already in a pointer register
8066        then don't need anything more */
8067     if (!AOP_INPREG(AOP(left))) {
8068         /* otherwise get a free pointer register */
8069         aop = newAsmop(0);
8070         preg = getFreePtr(ic,&aop,FALSE);
8071         pic14_emitcode("mov","%s,%s",
8072                 preg->name,
8073                 aopGet(AOP(left),0,FALSE,TRUE));
8074         rname = preg->name ;
8075     } else
8076         rname = aopGet(AOP(left),0,FALSE,FALSE);
8077     
8078     freeAsmop(left,NULL,ic,TRUE);
8079     aopOp (result,ic,FALSE);
8080
8081     /* if bitfield then unpack the bits */
8082     if (IS_BITVAR(retype)) 
8083         genUnpackBits (result,rname,PPOINTER);
8084     else {
8085         /* we have can just get the values */
8086         int size = AOP_SIZE(result);
8087         int offset = 0 ;        
8088         
8089         while (size--) {
8090             
8091             pic14_emitcode("movx","a,@%s",rname);
8092             aopPut(AOP(result),"a",offset);
8093             
8094             offset++ ;
8095             
8096             if (size)
8097                 pic14_emitcode("inc","%s",rname);
8098         }
8099     }
8100
8101     /* now some housekeeping stuff */
8102     if (aop) {
8103         /* we had to allocate for this iCode */
8104         freeAsmop(NULL,aop,ic,TRUE);
8105     } else { 
8106         /* we did not allocate which means left
8107            already in a pointer register, then
8108            if size > 0 && this could be used again
8109            we have to point it back to where it 
8110            belongs */
8111         if (AOP_SIZE(result) > 1 &&
8112             !OP_SYMBOL(left)->remat &&
8113             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8114               ic->depth )) {
8115             int size = AOP_SIZE(result) - 1;
8116             while (size--)
8117                 pic14_emitcode("dec","%s",rname);
8118         }
8119     }
8120
8121     /* done */
8122     freeAsmop(result,NULL,ic,TRUE);
8123     
8124         
8125 }
8126
8127 /*-----------------------------------------------------------------*/
8128 /* genFarPointerGet - gget value from far space                    */
8129 /*-----------------------------------------------------------------*/
8130 static void genFarPointerGet (operand *left,
8131                               operand *result, iCode *ic)
8132 {
8133     int size, offset ;
8134     sym_link *retype = getSpec(operandType(result));
8135
8136     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8137
8138     aopOp(left,ic,FALSE);
8139
8140     /* if the operand is already in dptr 
8141     then we do nothing else we move the value to dptr */
8142     if (AOP_TYPE(left) != AOP_STR) {
8143         /* if this is remateriazable */
8144         if (AOP_TYPE(left) == AOP_IMMD)
8145             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8146         else { /* we need to get it byte by byte */
8147             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8148             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8149             if (options.model == MODEL_FLAT24)
8150             {
8151                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8152             }
8153         }
8154     }
8155     /* so dptr know contains the address */
8156     freeAsmop(left,NULL,ic,TRUE);
8157     aopOp(result,ic,FALSE);
8158
8159     /* if bit then unpack */
8160     if (IS_BITVAR(retype)) 
8161         genUnpackBits(result,"dptr",FPOINTER);
8162     else {
8163         size = AOP_SIZE(result);
8164         offset = 0 ;
8165
8166         while (size--) {
8167             pic14_emitcode("movx","a,@dptr");
8168             aopPut(AOP(result),"a",offset++);
8169             if (size)
8170                 pic14_emitcode("inc","dptr");
8171         }
8172     }
8173
8174     freeAsmop(result,NULL,ic,TRUE);
8175 }
8176 #if 0
8177 /*-----------------------------------------------------------------*/
8178 /* genCodePointerGet - get value from code space                  */
8179 /*-----------------------------------------------------------------*/
8180 static void genCodePointerGet (operand *left,
8181                                 operand *result, iCode *ic)
8182 {
8183     int size, offset ;
8184     sym_link *retype = getSpec(operandType(result));
8185
8186     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8187
8188     aopOp(left,ic,FALSE);
8189
8190     /* if the operand is already in dptr 
8191     then we do nothing else we move the value to dptr */
8192     if (AOP_TYPE(left) != AOP_STR) {
8193         /* if this is remateriazable */
8194         if (AOP_TYPE(left) == AOP_IMMD)
8195             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8196         else { /* we need to get it byte by byte */
8197             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8198             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8199             if (options.model == MODEL_FLAT24)
8200             {
8201                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8202             }
8203         }
8204     }
8205     /* so dptr know contains the address */
8206     freeAsmop(left,NULL,ic,TRUE);
8207     aopOp(result,ic,FALSE);
8208
8209     /* if bit then unpack */
8210     if (IS_BITVAR(retype)) 
8211         genUnpackBits(result,"dptr",CPOINTER);
8212     else {
8213         size = AOP_SIZE(result);
8214         offset = 0 ;
8215
8216         while (size--) {
8217             pic14_emitcode("clr","a");
8218             pic14_emitcode("movc","a,@a+dptr");
8219             aopPut(AOP(result),"a",offset++);
8220             if (size)
8221                 pic14_emitcode("inc","dptr");
8222         }
8223     }
8224
8225     freeAsmop(result,NULL,ic,TRUE);
8226 }
8227 #endif
8228 /*-----------------------------------------------------------------*/
8229 /* genGenPointerGet - gget value from generic pointer space        */
8230 /*-----------------------------------------------------------------*/
8231 static void genGenPointerGet (operand *left,
8232                               operand *result, iCode *ic)
8233 {
8234   int size, offset ;
8235   sym_link *retype = getSpec(operandType(result));
8236
8237   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8238   aopOp(left,ic,FALSE);
8239   aopOp(result,ic,FALSE);
8240
8241
8242   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8243
8244   /* if the operand is already in dptr 
8245      then we do nothing else we move the value to dptr */
8246   //  if (AOP_TYPE(left) != AOP_STR) {
8247     /* if this is remateriazable */
8248     if (AOP_TYPE(left) == AOP_IMMD) {
8249       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8250       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8251     }
8252     else { /* we need to get it byte by byte */
8253
8254       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8255       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8256
8257       size = AOP_SIZE(result);
8258       offset = 0 ;
8259
8260       while(size--) {
8261         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8262         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8263         if(size)
8264           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8265       }
8266       goto release;
8267     }
8268     //}
8269   /* so dptr know contains the address */
8270
8271   /* if bit then unpack */
8272   //if (IS_BITVAR(retype)) 
8273   //  genUnpackBits(result,"dptr",GPOINTER);
8274
8275  release:
8276   freeAsmop(left,NULL,ic,TRUE);
8277   freeAsmop(result,NULL,ic,TRUE);
8278
8279 }
8280
8281 /*-----------------------------------------------------------------*/
8282 /* genConstPointerGet - get value from const generic pointer space */
8283 /*-----------------------------------------------------------------*/
8284 static void genConstPointerGet (operand *left,
8285                                 operand *result, iCode *ic)
8286 {
8287   //sym_link *retype = getSpec(operandType(result));
8288   symbol *albl = newiTempLabel(NULL);
8289   symbol *blbl = newiTempLabel(NULL);
8290   PIC_OPCODE poc;
8291
8292   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8293   aopOp(left,ic,FALSE);
8294   aopOp(result,ic,FALSE);
8295
8296
8297   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8298
8299   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8300
8301   emitpcode(POC_CALL,popGetLabel(albl->key));
8302   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8303   emitpLabel(albl->key);
8304
8305   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8306     
8307   emitpcode(poc,popGet(AOP(left),1));
8308   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8309   emitpcode(poc,popGet(AOP(left),0));
8310   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8311
8312   emitpLabel(blbl->key);
8313
8314   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8315
8316
8317   freeAsmop(left,NULL,ic,TRUE);
8318   freeAsmop(result,NULL,ic,TRUE);
8319
8320 }
8321 /*-----------------------------------------------------------------*/
8322 /* genPointerGet - generate code for pointer get                   */
8323 /*-----------------------------------------------------------------*/
8324 static void genPointerGet (iCode *ic)
8325 {
8326     operand *left, *result ;
8327     sym_link *type, *etype;
8328     int p_type;
8329
8330     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8331
8332     left = IC_LEFT(ic);
8333     result = IC_RESULT(ic) ;
8334
8335     /* depending on the type of pointer we need to
8336     move it to the correct pointer register */
8337     type = operandType(left);
8338     etype = getSpec(type);
8339
8340     if (IS_PTR_CONST(type))
8341       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8342
8343     /* if left is of type of pointer then it is simple */
8344     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8345         p_type = DCL_TYPE(type);
8346     else {
8347         /* we have to go by the storage class */
8348         p_type = PTR_TYPE(SPEC_OCLS(etype));
8349
8350         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8351
8352         if (SPEC_OCLS(etype)->codesp ) {
8353           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8354           //p_type = CPOINTER ; 
8355         }
8356         else
8357             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8358               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8359                /*p_type = FPOINTER ;*/ 
8360             else
8361                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8362                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8363 /*                  p_type = PPOINTER; */
8364                 else
8365                     if (SPEC_OCLS(etype) == idata )
8366                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8367 /*                      p_type = IPOINTER; */
8368                     else
8369                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8370 /*                      p_type = POINTER ; */
8371     }
8372
8373     /* now that we have the pointer type we assign
8374     the pointer values */
8375     switch (p_type) {
8376
8377     case POINTER:       
8378     case IPOINTER:
8379         genNearPointerGet (left,result,ic);
8380         break;
8381
8382     case PPOINTER:
8383         genPagedPointerGet(left,result,ic);
8384         break;
8385
8386     case FPOINTER:
8387         genFarPointerGet (left,result,ic);
8388         break;
8389
8390     case CPOINTER:
8391         genConstPointerGet (left,result,ic);
8392         //pic14_emitcodePointerGet (left,result,ic);
8393         break;
8394
8395     case GPOINTER:
8396       if (IS_PTR_CONST(type))
8397         genConstPointerGet (left,result,ic);
8398       else
8399         genGenPointerGet (left,result,ic);
8400       break;
8401     }
8402
8403 }
8404
8405 /*-----------------------------------------------------------------*/
8406 /* genPackBits - generates code for packed bit storage             */
8407 /*-----------------------------------------------------------------*/
8408 static void genPackBits (sym_link    *etype ,
8409                          operand *right ,
8410                          char *rname, int p_type)
8411 {
8412     int shCount = 0 ;
8413     int offset = 0  ;
8414     int rLen = 0 ;
8415     int blen, bstr ;   
8416     char *l ;
8417
8418     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8419     blen = SPEC_BLEN(etype);
8420     bstr = SPEC_BSTR(etype);
8421
8422     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8423     MOVA(l);   
8424
8425     /* if the bit lenth is less than or    */
8426     /* it exactly fits a byte then         */
8427     if (SPEC_BLEN(etype) <= 8 )  {
8428         shCount = SPEC_BSTR(etype) ;
8429
8430         /* shift left acc */
8431         AccLsh(shCount);
8432
8433         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8434
8435
8436             switch (p_type) {
8437                 case POINTER:
8438                     pic14_emitcode ("mov","b,a");
8439                     pic14_emitcode("mov","a,@%s",rname);
8440                     break;
8441
8442                 case FPOINTER:
8443                     pic14_emitcode ("mov","b,a");
8444                     pic14_emitcode("movx","a,@dptr");
8445                     break;
8446
8447                 case GPOINTER:
8448                     pic14_emitcode ("push","b");
8449                     pic14_emitcode ("push","acc");
8450                     pic14_emitcode ("lcall","__gptrget");
8451                     pic14_emitcode ("pop","b");
8452                     break;
8453             }
8454
8455             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8456                       ((unsigned char)(0xFF << (blen+bstr)) | 
8457                        (unsigned char)(0xFF >> (8-bstr)) ) );
8458             pic14_emitcode ("orl","a,b");
8459             if (p_type == GPOINTER)
8460                 pic14_emitcode("pop","b");
8461         }
8462     }
8463
8464     switch (p_type) {
8465         case POINTER:
8466             pic14_emitcode("mov","@%s,a",rname);
8467             break;
8468
8469         case FPOINTER:
8470             pic14_emitcode("movx","@dptr,a");
8471             break;
8472
8473         case GPOINTER:
8474             DEBUGpic14_emitcode(";lcall","__gptrput");
8475             break;
8476     }
8477
8478     /* if we r done */
8479     if ( SPEC_BLEN(etype) <= 8 )
8480         return ;
8481
8482     pic14_emitcode("inc","%s",rname);
8483     rLen = SPEC_BLEN(etype) ;     
8484
8485     /* now generate for lengths greater than one byte */
8486     while (1) {
8487
8488         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8489
8490         rLen -= 8 ;
8491         if (rLen <= 0 )
8492             break ;
8493
8494         switch (p_type) {
8495             case POINTER:
8496                 if (*l == '@') {
8497                     MOVA(l);
8498                     pic14_emitcode("mov","@%s,a",rname);
8499                 } else
8500                     pic14_emitcode("mov","@%s,%s",rname,l);
8501                 break;
8502
8503             case FPOINTER:
8504                 MOVA(l);
8505                 pic14_emitcode("movx","@dptr,a");
8506                 break;
8507
8508             case GPOINTER:
8509                 MOVA(l);
8510                 DEBUGpic14_emitcode(";lcall","__gptrput");
8511                 break;  
8512         }   
8513         pic14_emitcode ("inc","%s",rname);
8514     }
8515
8516     MOVA(l);
8517
8518     /* last last was not complete */
8519     if (rLen)   {
8520         /* save the byte & read byte */
8521         switch (p_type) {
8522             case POINTER:
8523                 pic14_emitcode ("mov","b,a");
8524                 pic14_emitcode("mov","a,@%s",rname);
8525                 break;
8526
8527             case FPOINTER:
8528                 pic14_emitcode ("mov","b,a");
8529                 pic14_emitcode("movx","a,@dptr");
8530                 break;
8531
8532             case GPOINTER:
8533                 pic14_emitcode ("push","b");
8534                 pic14_emitcode ("push","acc");
8535                 pic14_emitcode ("lcall","__gptrget");
8536                 pic14_emitcode ("pop","b");
8537                 break;
8538         }
8539
8540         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8541         pic14_emitcode ("orl","a,b");
8542     }
8543
8544     if (p_type == GPOINTER)
8545         pic14_emitcode("pop","b");
8546
8547     switch (p_type) {
8548
8549     case POINTER:
8550         pic14_emitcode("mov","@%s,a",rname);
8551         break;
8552         
8553     case FPOINTER:
8554         pic14_emitcode("movx","@dptr,a");
8555         break;
8556         
8557     case GPOINTER:
8558         DEBUGpic14_emitcode(";lcall","__gptrput");
8559         break;                  
8560     }
8561 }
8562 /*-----------------------------------------------------------------*/
8563 /* genDataPointerSet - remat pointer to data space                 */
8564 /*-----------------------------------------------------------------*/
8565 static void genDataPointerSet(operand *right,
8566                               operand *result,
8567                               iCode *ic)
8568 {
8569     int size, offset = 0 ;
8570     char *l, buffer[256];
8571
8572     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8573     aopOp(right,ic,FALSE);
8574     
8575     l = aopGet(AOP(result),0,FALSE,TRUE);
8576     size = AOP_SIZE(right);
8577 /*
8578     if ( AOP_TYPE(result) == AOP_PCODE) {
8579       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8580               AOP(result)->aopu.pcop->name,
8581               PCOI(AOP(result)->aopu.pcop)->offset);
8582     }
8583 */
8584
8585     // tsd, was l+1 - the underline `_' prefix was being stripped
8586     while (size--) {
8587       if (offset) {
8588         sprintf(buffer,"(%s + %d)",l,offset);
8589         fprintf(stderr,"oops  %s\n",buffer);
8590       } else
8591         sprintf(buffer,"%s",l);
8592
8593         if (AOP_TYPE(right) == AOP_LIT) {
8594           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8595           lit = lit >> (8*offset);
8596           if(lit&0xff) {
8597             pic14_emitcode("movlw","%d",lit);
8598             pic14_emitcode("movwf","%s",buffer);
8599
8600             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8601             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8602             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8603
8604           } else {
8605             pic14_emitcode("clrf","%s",buffer);
8606             //emitpcode(POC_CLRF, popRegFromString(buffer));
8607             emitpcode(POC_CLRF, popGet(AOP(result),0));
8608           }
8609         }else {
8610           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8611           pic14_emitcode("movwf","%s",buffer);
8612
8613           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8614           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8615           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8616
8617         }
8618
8619         offset++;
8620     }
8621
8622     freeAsmop(right,NULL,ic,TRUE);
8623     freeAsmop(result,NULL,ic,TRUE);
8624 }
8625
8626 /*-----------------------------------------------------------------*/
8627 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8628 /*-----------------------------------------------------------------*/
8629 static void genNearPointerSet (operand *right,
8630                                operand *result, 
8631                                iCode *ic)
8632 {
8633   asmop *aop = NULL;
8634   char *l;
8635   sym_link *retype;
8636   sym_link *ptype = operandType(result);
8637
8638     
8639   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8640   retype= getSpec(operandType(right));
8641
8642   aopOp(result,ic,FALSE);
8643
8644     
8645   /* if the result is rematerializable &
8646      in data space & not a bit variable */
8647   //if (AOP_TYPE(result) == AOP_IMMD &&
8648   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8649       DCL_TYPE(ptype) == POINTER   &&
8650       !IS_BITVAR(retype)) {
8651     genDataPointerSet (right,result,ic);
8652     freeAsmop(result,NULL,ic,TRUE);
8653     return;
8654   }
8655
8656   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8657   aopOp(right,ic,FALSE);
8658   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8659
8660   /* if the value is already in a pointer register
8661      then don't need anything more */
8662   if (!AOP_INPREG(AOP(result))) {
8663     /* otherwise get a free pointer register */
8664     //aop = newAsmop(0);
8665     //preg = getFreePtr(ic,&aop,FALSE);
8666     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8667     //pic14_emitcode("mov","%s,%s",
8668     //         preg->name,
8669     //         aopGet(AOP(result),0,FALSE,TRUE));
8670     //rname = preg->name ;
8671     //pic14_emitcode("movwf","fsr");
8672     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8673     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8674     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8675     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8676     goto release;
8677
8678   }// else
8679   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8680
8681
8682   /* if bitfield then unpack the bits */
8683   if (IS_BITVAR(retype)) {
8684     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8685            "The programmer is obviously confused");
8686     //genPackBits (retype,right,rname,POINTER);
8687     exit(1);
8688   }
8689   else {
8690     /* we have can just get the values */
8691     int size = AOP_SIZE(right);
8692     int offset = 0 ;    
8693
8694     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8695     while (size--) {
8696       l = aopGet(AOP(right),offset,FALSE,TRUE);
8697       if (*l == '@' ) {
8698         //MOVA(l);
8699         //pic14_emitcode("mov","@%s,a",rname);
8700         pic14_emitcode("movf","indf,w ;1");
8701       } else {
8702
8703         if (AOP_TYPE(right) == AOP_LIT) {
8704           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8705           if(lit) {
8706             pic14_emitcode("movlw","%s",l);
8707             pic14_emitcode("movwf","indf ;2");
8708           } else 
8709             pic14_emitcode("clrf","indf");
8710         }else {
8711           pic14_emitcode("movf","%s,w",l);
8712           pic14_emitcode("movwf","indf ;2");
8713         }
8714         //pic14_emitcode("mov","@%s,%s",rname,l);
8715       }
8716       if (size)
8717         pic14_emitcode("incf","fsr,f ;3");
8718       //pic14_emitcode("inc","%s",rname);
8719       offset++;
8720     }
8721   }
8722
8723   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8724   /* now some housekeeping stuff */
8725   if (aop) {
8726     /* we had to allocate for this iCode */
8727     freeAsmop(NULL,aop,ic,TRUE);
8728   } else { 
8729     /* we did not allocate which means left
8730        already in a pointer register, then
8731        if size > 0 && this could be used again
8732        we have to point it back to where it 
8733        belongs */
8734     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8735     if (AOP_SIZE(right) > 1 &&
8736         !OP_SYMBOL(result)->remat &&
8737         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8738           ic->depth )) {
8739       int size = AOP_SIZE(right) - 1;
8740       while (size--)
8741         pic14_emitcode("decf","fsr,f");
8742       //pic14_emitcode("dec","%s",rname);
8743     }
8744   }
8745
8746   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8747   /* done */
8748  release:
8749   freeAsmop(right,NULL,ic,TRUE);
8750   freeAsmop(result,NULL,ic,TRUE);
8751 }
8752
8753 /*-----------------------------------------------------------------*/
8754 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8755 /*-----------------------------------------------------------------*/
8756 static void genPagedPointerSet (operand *right,
8757                                operand *result, 
8758                                iCode *ic)
8759 {
8760     asmop *aop = NULL;
8761     regs *preg = NULL ;
8762     char *rname , *l;
8763     sym_link *retype;
8764        
8765     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8766
8767     retype= getSpec(operandType(right));
8768     
8769     aopOp(result,ic,FALSE);
8770     
8771     /* if the value is already in a pointer register
8772        then don't need anything more */
8773     if (!AOP_INPREG(AOP(result))) {
8774         /* otherwise get a free pointer register */
8775         aop = newAsmop(0);
8776         preg = getFreePtr(ic,&aop,FALSE);
8777         pic14_emitcode("mov","%s,%s",
8778                 preg->name,
8779                 aopGet(AOP(result),0,FALSE,TRUE));
8780         rname = preg->name ;
8781     } else
8782         rname = aopGet(AOP(result),0,FALSE,FALSE);
8783     
8784     freeAsmop(result,NULL,ic,TRUE);
8785     aopOp (right,ic,FALSE);
8786
8787     /* if bitfield then unpack the bits */
8788     if (IS_BITVAR(retype)) 
8789         genPackBits (retype,right,rname,PPOINTER);
8790     else {
8791         /* we have can just get the values */
8792         int size = AOP_SIZE(right);
8793         int offset = 0 ;        
8794         
8795         while (size--) {
8796             l = aopGet(AOP(right),offset,FALSE,TRUE);
8797             
8798             MOVA(l);
8799             pic14_emitcode("movx","@%s,a",rname);
8800
8801             if (size)
8802                 pic14_emitcode("inc","%s",rname);
8803
8804             offset++;
8805         }
8806     }
8807     
8808     /* now some housekeeping stuff */
8809     if (aop) {
8810         /* we had to allocate for this iCode */
8811         freeAsmop(NULL,aop,ic,TRUE);
8812     } else { 
8813         /* we did not allocate which means left
8814            already in a pointer register, then
8815            if size > 0 && this could be used again
8816            we have to point it back to where it 
8817            belongs */
8818         if (AOP_SIZE(right) > 1 &&
8819             !OP_SYMBOL(result)->remat &&
8820             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8821               ic->depth )) {
8822             int size = AOP_SIZE(right) - 1;
8823             while (size--)
8824                 pic14_emitcode("dec","%s",rname);
8825         }
8826     }
8827
8828     /* done */
8829     freeAsmop(right,NULL,ic,TRUE);
8830     
8831         
8832 }
8833
8834 /*-----------------------------------------------------------------*/
8835 /* genFarPointerSet - set value from far space                     */
8836 /*-----------------------------------------------------------------*/
8837 static void genFarPointerSet (operand *right,
8838                               operand *result, iCode *ic)
8839 {
8840     int size, offset ;
8841     sym_link *retype = getSpec(operandType(right));
8842
8843     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8844     aopOp(result,ic,FALSE);
8845
8846     /* if the operand is already in dptr 
8847     then we do nothing else we move the value to dptr */
8848     if (AOP_TYPE(result) != AOP_STR) {
8849         /* if this is remateriazable */
8850         if (AOP_TYPE(result) == AOP_IMMD)
8851             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8852         else { /* we need to get it byte by byte */
8853             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8854             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8855             if (options.model == MODEL_FLAT24)
8856             {
8857                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8858             }
8859         }
8860     }
8861     /* so dptr know contains the address */
8862     freeAsmop(result,NULL,ic,TRUE);
8863     aopOp(right,ic,FALSE);
8864
8865     /* if bit then unpack */
8866     if (IS_BITVAR(retype)) 
8867         genPackBits(retype,right,"dptr",FPOINTER);
8868     else {
8869         size = AOP_SIZE(right);
8870         offset = 0 ;
8871
8872         while (size--) {
8873             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8874             MOVA(l);
8875             pic14_emitcode("movx","@dptr,a");
8876             if (size)
8877                 pic14_emitcode("inc","dptr");
8878         }
8879     }
8880
8881     freeAsmop(right,NULL,ic,TRUE);
8882 }
8883
8884 /*-----------------------------------------------------------------*/
8885 /* genGenPointerSet - set value from generic pointer space         */
8886 /*-----------------------------------------------------------------*/
8887 static void genGenPointerSet (operand *right,
8888                               operand *result, iCode *ic)
8889 {
8890   int size, offset ;
8891   sym_link *retype = getSpec(operandType(right));
8892
8893   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8894
8895   aopOp(result,ic,FALSE);
8896   aopOp(right,ic,FALSE);
8897   size = AOP_SIZE(right);
8898
8899   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8900
8901   /* if the operand is already in dptr 
8902      then we do nothing else we move the value to dptr */
8903   if (AOP_TYPE(result) != AOP_STR) {
8904     /* if this is remateriazable */
8905     if (AOP_TYPE(result) == AOP_IMMD) {
8906       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8907       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8908     }
8909     else { /* we need to get it byte by byte */
8910       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8911       size = AOP_SIZE(right);
8912       offset = 0 ;
8913
8914       /* hack hack! see if this the FSR. If so don't load W */
8915       if(AOP_TYPE(right) != AOP_ACC) {
8916
8917         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8918         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8919
8920         //if(size==2)
8921         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8922         //if(size==4) {
8923         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8924         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8925         //}
8926
8927         while(size--) {
8928           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8929           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8930           
8931           if(size)
8932             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8933         }
8934
8935
8936         goto release;
8937       } 
8938
8939       if(aopIdx(AOP(result),0) != 4) {
8940
8941         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8942         goto release;
8943       }
8944
8945       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8946       goto release;
8947
8948     }
8949   }
8950   /* so dptr know contains the address */
8951
8952
8953   /* if bit then unpack */
8954   if (IS_BITVAR(retype)) 
8955     genPackBits(retype,right,"dptr",GPOINTER);
8956   else {
8957     size = AOP_SIZE(right);
8958     offset = 0 ;
8959
8960   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8961
8962     while (size--) {
8963
8964       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8965       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8966
8967       if (AOP_TYPE(right) == AOP_LIT) 
8968         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8969       else
8970         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8971
8972       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8973
8974       offset++;
8975     }
8976   }
8977
8978  release:
8979   freeAsmop(right,NULL,ic,TRUE);
8980   freeAsmop(result,NULL,ic,TRUE);
8981 }
8982
8983 /*-----------------------------------------------------------------*/
8984 /* genPointerSet - stores the value into a pointer location        */
8985 /*-----------------------------------------------------------------*/
8986 static void genPointerSet (iCode *ic)
8987 {    
8988     operand *right, *result ;
8989     sym_link *type, *etype;
8990     int p_type;
8991
8992     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8993
8994     right = IC_RIGHT(ic);
8995     result = IC_RESULT(ic) ;
8996
8997     /* depending on the type of pointer we need to
8998     move it to the correct pointer register */
8999     type = operandType(result);
9000     etype = getSpec(type);
9001     /* if left is of type of pointer then it is simple */
9002     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9003         p_type = DCL_TYPE(type);
9004     }
9005     else {
9006         /* we have to go by the storage class */
9007         p_type = PTR_TYPE(SPEC_OCLS(etype));
9008
9009 /*      if (SPEC_OCLS(etype)->codesp ) { */
9010 /*          p_type = CPOINTER ;  */
9011 /*      } */
9012 /*      else */
9013 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9014 /*              p_type = FPOINTER ; */
9015 /*          else */
9016 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9017 /*                  p_type = PPOINTER ; */
9018 /*              else */
9019 /*                  if (SPEC_OCLS(etype) == idata ) */
9020 /*                      p_type = IPOINTER ; */
9021 /*                  else */
9022 /*                      p_type = POINTER ; */
9023     }
9024
9025     /* now that we have the pointer type we assign
9026     the pointer values */
9027     switch (p_type) {
9028
9029     case POINTER:
9030     case IPOINTER:
9031         genNearPointerSet (right,result,ic);
9032         break;
9033
9034     case PPOINTER:
9035         genPagedPointerSet (right,result,ic);
9036         break;
9037
9038     case FPOINTER:
9039         genFarPointerSet (right,result,ic);
9040         break;
9041
9042     case GPOINTER:
9043         genGenPointerSet (right,result,ic);
9044         break;
9045
9046     default:
9047       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9048               "genPointerSet: illegal pointer type");
9049     }
9050 }
9051
9052 /*-----------------------------------------------------------------*/
9053 /* genIfx - generate code for Ifx statement                        */
9054 /*-----------------------------------------------------------------*/
9055 static void genIfx (iCode *ic, iCode *popIc)
9056 {
9057   operand *cond = IC_COND(ic);
9058   int isbit =0;
9059
9060   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9061
9062   aopOp(cond,ic,FALSE);
9063
9064   /* get the value into acc */
9065   if (AOP_TYPE(cond) != AOP_CRY)
9066     pic14_toBoolean(cond);
9067   else
9068     isbit = 1;
9069   /* the result is now in the accumulator */
9070   freeAsmop(cond,NULL,ic,TRUE);
9071
9072   /* if there was something to be popped then do it */
9073   if (popIc)
9074     genIpop(popIc);
9075
9076   /* if the condition is  a bit variable */
9077   if (isbit && IS_ITEMP(cond) && 
9078       SPIL_LOC(cond)) {
9079     genIfxJump(ic,SPIL_LOC(cond)->rname);
9080     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9081   }
9082   else {
9083     if (isbit && !IS_ITEMP(cond))
9084       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9085     else
9086       genIfxJump(ic,"a");
9087   }
9088   ic->generated = 1;
9089
9090 }
9091
9092 /*-----------------------------------------------------------------*/
9093 /* genAddrOf - generates code for address of                       */
9094 /*-----------------------------------------------------------------*/
9095 static void genAddrOf (iCode *ic)
9096 {
9097   operand *right, *result, *left;
9098   int size, offset ;
9099
9100   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9101
9102
9103   //aopOp(IC_RESULT(ic),ic,FALSE);
9104
9105   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9106   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9107   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9108
9109   DEBUGpic14_AopType(__LINE__,left,right,result);
9110
9111   size = AOP_SIZE(IC_RESULT(ic));
9112   offset = 0;
9113
9114   while (size--) {
9115     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9116     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9117     offset++;
9118   }
9119
9120   freeAsmop(left,NULL,ic,FALSE);
9121   freeAsmop(result,NULL,ic,TRUE);
9122
9123 }
9124
9125 #if 0
9126 /*-----------------------------------------------------------------*/
9127 /* genFarFarAssign - assignment when both are in far space         */
9128 /*-----------------------------------------------------------------*/
9129 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9130 {
9131     int size = AOP_SIZE(right);
9132     int offset = 0;
9133     char *l ;
9134     /* first push the right side on to the stack */
9135     while (size--) {
9136         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9137         MOVA(l);
9138         pic14_emitcode ("push","acc");
9139     }
9140     
9141     freeAsmop(right,NULL,ic,FALSE);
9142     /* now assign DPTR to result */
9143     aopOp(result,ic,FALSE);
9144     size = AOP_SIZE(result);
9145     while (size--) {
9146         pic14_emitcode ("pop","acc");
9147         aopPut(AOP(result),"a",--offset);
9148     }
9149     freeAsmop(result,NULL,ic,FALSE);
9150         
9151 }
9152 #endif
9153
9154 /*-----------------------------------------------------------------*/
9155 /* genAssign - generate code for assignment                        */
9156 /*-----------------------------------------------------------------*/
9157 static void genAssign (iCode *ic)
9158 {
9159   operand *result, *right;
9160   int size, offset,know_W;
9161   unsigned long lit = 0L;
9162
9163   result = IC_RESULT(ic);
9164   right  = IC_RIGHT(ic) ;
9165
9166   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9167
9168   /* if they are the same */
9169   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9170     return ;
9171
9172   aopOp(right,ic,FALSE);
9173   aopOp(result,ic,TRUE);
9174
9175   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9176
9177   /* if they are the same registers */
9178   if (pic14_sameRegs(AOP(right),AOP(result)))
9179     goto release;
9180
9181   /* if the result is a bit */
9182   if (AOP_TYPE(result) == AOP_CRY) {
9183
9184     /* if the right size is a literal then
9185        we know what the value is */
9186     if (AOP_TYPE(right) == AOP_LIT) {
9187           
9188       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9189                   popGet(AOP(result),0));
9190
9191       if (((int) operandLitValue(right))) 
9192         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9193                        AOP(result)->aopu.aop_dir,
9194                        AOP(result)->aopu.aop_dir);
9195       else
9196         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9197                        AOP(result)->aopu.aop_dir,
9198                        AOP(result)->aopu.aop_dir);
9199       goto release;
9200     }
9201
9202     /* the right is also a bit variable */
9203     if (AOP_TYPE(right) == AOP_CRY) {
9204       emitpcode(POC_BCF,    popGet(AOP(result),0));
9205       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9206       emitpcode(POC_BSF,    popGet(AOP(result),0));
9207
9208       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9209                      AOP(result)->aopu.aop_dir,
9210                      AOP(result)->aopu.aop_dir);
9211       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9212                      AOP(right)->aopu.aop_dir,
9213                      AOP(right)->aopu.aop_dir);
9214       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9215                      AOP(result)->aopu.aop_dir,
9216                      AOP(result)->aopu.aop_dir);
9217       goto release ;
9218     }
9219
9220     /* we need to or */
9221     emitpcode(POC_BCF,    popGet(AOP(result),0));
9222     pic14_toBoolean(right);
9223     emitSKPZ;
9224     emitpcode(POC_BSF,    popGet(AOP(result),0));
9225     //aopPut(AOP(result),"a",0);
9226     goto release ;
9227   }
9228
9229   /* bit variables done */
9230   /* general case */
9231   size = AOP_SIZE(result);
9232   offset = 0 ;
9233   if(AOP_TYPE(right) == AOP_LIT)
9234     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9235
9236   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9237   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9238     if(aopIdx(AOP(result),0) == 4) {
9239   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9240       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9241       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9242       goto release;
9243     } else
9244       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9245   }
9246
9247   know_W=-1;
9248   while (size--) {
9249   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9250     if(AOP_TYPE(right) == AOP_LIT) {
9251       if(lit&0xff) {
9252         if(know_W != (lit&0xff))
9253           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9254         know_W = lit&0xff;
9255         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9256       } else
9257         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9258
9259       lit >>= 8;
9260
9261     } else if (AOP_TYPE(right) == AOP_CRY) {
9262       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9263       if(offset == 0) {
9264         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9265         emitpcode(POC_INCF, popGet(AOP(result),0));
9266       }
9267     } else {
9268   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9269       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9270       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9271     }
9272             
9273     offset++;
9274   }
9275
9276     
9277  release:
9278   freeAsmop (right,NULL,ic,FALSE);
9279   freeAsmop (result,NULL,ic,TRUE);
9280 }   
9281
9282 /*-----------------------------------------------------------------*/
9283 /* genJumpTab - genrates code for jump table                       */
9284 /*-----------------------------------------------------------------*/
9285 static void genJumpTab (iCode *ic)
9286 {
9287     symbol *jtab;
9288     char *l;
9289
9290     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9291
9292     aopOp(IC_JTCOND(ic),ic,FALSE);
9293     /* get the condition into accumulator */
9294     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9295     MOVA(l);
9296     /* multiply by three */
9297     pic14_emitcode("add","a,acc");
9298     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9299
9300     jtab = newiTempLabel(NULL);
9301     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9302     pic14_emitcode("jmp","@a+dptr");
9303     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9304
9305     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9306     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9307     emitSKPNC;
9308     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9309     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9310     emitpLabel(jtab->key);
9311
9312     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9313
9314     /* now generate the jump labels */
9315     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9316          jtab = setNextItem(IC_JTLABELS(ic))) {
9317         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9318         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9319         
9320     }
9321
9322 }
9323
9324 /*-----------------------------------------------------------------*/
9325 /* genMixedOperation - gen code for operators between mixed types  */
9326 /*-----------------------------------------------------------------*/
9327 /*
9328   TSD - Written for the PIC port - but this unfortunately is buggy.
9329   This routine is good in that it is able to efficiently promote 
9330   types to different (larger) sizes. Unfortunately, the temporary
9331   variables that are optimized out by this routine are sometimes
9332   used in other places. So until I know how to really parse the 
9333   iCode tree, I'm going to not be using this routine :(.
9334 */
9335 static int genMixedOperation (iCode *ic)
9336 {
9337 #if 0
9338   operand *result = IC_RESULT(ic);
9339   sym_link *ctype = operandType(IC_LEFT(ic));
9340   operand *right = IC_RIGHT(ic);
9341   int ret = 0;
9342   int big,small;
9343   int offset;
9344
9345   iCode *nextic;
9346   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9347
9348   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9349
9350   nextic = ic->next;
9351   if(!nextic)
9352     return 0;
9353
9354   nextright = IC_RIGHT(nextic);
9355   nextleft  = IC_LEFT(nextic);
9356   nextresult = IC_RESULT(nextic);
9357
9358   aopOp(right,ic,FALSE);
9359   aopOp(result,ic,FALSE);
9360   aopOp(nextright,  nextic, FALSE);
9361   aopOp(nextleft,   nextic, FALSE);
9362   aopOp(nextresult, nextic, FALSE);
9363
9364   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9365
9366     operand *t = right;
9367     right = nextright;
9368     nextright = t; 
9369
9370     pic14_emitcode(";remove right +","");
9371
9372   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9373 /*
9374     operand *t = right;
9375     right = nextleft;
9376     nextleft = t; 
9377 */
9378     pic14_emitcode(";remove left +","");
9379   } else
9380     return 0;
9381
9382   big = AOP_SIZE(nextleft);
9383   small = AOP_SIZE(nextright);
9384
9385   switch(nextic->op) {
9386
9387   case '+':
9388     pic14_emitcode(";optimize a +","");
9389     /* if unsigned or not an integral type */
9390     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9391       pic14_emitcode(";add a bit to something","");
9392     } else {
9393
9394       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9395
9396       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9397         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9398         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9399       } else
9400         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9401
9402       offset = 0;
9403       while(--big) {
9404
9405         offset++;
9406
9407         if(--small) {
9408           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9409             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9410             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9411           }
9412
9413           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9414           emitSKPNC;
9415           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9416                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9417                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9418           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9419           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9420
9421         } else {
9422           pic14_emitcode("rlf","known_zero,w");
9423
9424           /*
9425             if right is signed
9426               btfsc  right,7
9427                addlw ff
9428           */
9429           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9430             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9431             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9432           } else {
9433             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9434           }
9435         }
9436       }
9437       ret = 1;
9438     }
9439   }
9440   ret = 1;
9441
9442 release:
9443   freeAsmop(right,NULL,ic,TRUE);
9444   freeAsmop(result,NULL,ic,TRUE);
9445   freeAsmop(nextright,NULL,ic,TRUE);
9446   freeAsmop(nextleft,NULL,ic,TRUE);
9447   if(ret)
9448     nextic->generated = 1;
9449
9450   return ret;
9451 #else
9452   return 0;
9453 #endif
9454 }
9455 /*-----------------------------------------------------------------*/
9456 /* genCast - gen code for casting                                  */
9457 /*-----------------------------------------------------------------*/
9458 static void genCast (iCode *ic)
9459 {
9460     operand *result = IC_RESULT(ic);
9461     sym_link *ctype = operandType(IC_LEFT(ic));
9462     sym_link *rtype = operandType(IC_RIGHT(ic));
9463     operand *right = IC_RIGHT(ic);
9464     int size, offset ;
9465
9466     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9467     /* if they are equivalent then do nothing */
9468     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9469         return ;
9470
9471     aopOp(right,ic,FALSE) ;
9472     aopOp(result,ic,FALSE);
9473
9474     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9475
9476     /* if the result is a bit */
9477     if (AOP_TYPE(result) == AOP_CRY) {
9478         /* if the right size is a literal then
9479         we know what the value is */
9480       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9481         if (AOP_TYPE(right) == AOP_LIT) {
9482
9483           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9484                       popGet(AOP(result),0));
9485
9486             if (((int) operandLitValue(right))) 
9487               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9488                        AOP(result)->aopu.aop_dir,
9489                        AOP(result)->aopu.aop_dir);
9490             else
9491               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9492                        AOP(result)->aopu.aop_dir,
9493                        AOP(result)->aopu.aop_dir);
9494
9495             goto release;
9496         }
9497
9498         /* the right is also a bit variable */
9499         if (AOP_TYPE(right) == AOP_CRY) {
9500
9501           emitCLRC;
9502           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9503
9504           pic14_emitcode("clrc","");
9505           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9506                    AOP(right)->aopu.aop_dir,
9507                    AOP(right)->aopu.aop_dir);
9508             aopPut(AOP(result),"c",0);
9509             goto release ;
9510         }
9511
9512         /* we need to or */
9513         if (AOP_TYPE(right) == AOP_REG) {
9514           emitpcode(POC_BCF,    popGet(AOP(result),0));
9515           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9516           emitpcode(POC_BSF,    popGet(AOP(result),0));
9517         }
9518         pic14_toBoolean(right);
9519         aopPut(AOP(result),"a",0);
9520         goto release ;
9521     }
9522
9523     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9524       int offset = 1;
9525       size = AOP_SIZE(result);
9526
9527       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9528
9529       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9530       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9531       emitpcode(POC_INCF,   popGet(AOP(result),0));
9532
9533       while (size--)
9534         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9535
9536       goto release;
9537     }
9538
9539     /* if they are the same size : or less */
9540     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9541
9542         /* if they are in the same place */
9543       if (pic14_sameRegs(AOP(right),AOP(result)))
9544         goto release;
9545
9546       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9547       if (IS_PTR_CONST(rtype))
9548         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9549       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9550         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9551
9552       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9553         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9554         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9555         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9556         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9557         if(AOP_SIZE(result) <2)
9558           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9559
9560       } else {
9561
9562         /* if they in different places then copy */
9563         size = AOP_SIZE(result);
9564         offset = 0 ;
9565         while (size--) {
9566           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9567           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9568
9569           //aopPut(AOP(result),
9570           // aopGet(AOP(right),offset,FALSE,FALSE),
9571           // offset);
9572
9573           offset++;
9574         }
9575       }
9576       goto release;
9577     }
9578
9579
9580     /* if the result is of type pointer */
9581     if (IS_PTR(ctype)) {
9582
9583         int p_type;
9584         sym_link *type = operandType(right);
9585         sym_link *etype = getSpec(type);
9586       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9587
9588         /* pointer to generic pointer */
9589         if (IS_GENPTR(ctype)) {
9590             char *l = zero;
9591             
9592             if (IS_PTR(type)) 
9593                 p_type = DCL_TYPE(type);
9594             else {
9595                 /* we have to go by the storage class */
9596                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9597
9598 /*              if (SPEC_OCLS(etype)->codesp )  */
9599 /*                  p_type = CPOINTER ;  */
9600 /*              else */
9601 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9602 /*                      p_type = FPOINTER ; */
9603 /*                  else */
9604 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9605 /*                          p_type = PPOINTER; */
9606 /*                      else */
9607 /*                          if (SPEC_OCLS(etype) == idata ) */
9608 /*                              p_type = IPOINTER ; */
9609 /*                          else */
9610 /*                              p_type = POINTER ; */
9611             }
9612                 
9613             /* the first two bytes are known */
9614       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9615             size = GPTRSIZE - 1; 
9616             offset = 0 ;
9617             while (size--) {
9618               if(offset < AOP_SIZE(right)) {
9619       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9620                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9621                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9622                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9623                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9624                 } else { 
9625                   aopPut(AOP(result),
9626                          aopGet(AOP(right),offset,FALSE,FALSE),
9627                          offset);
9628                 }
9629               } else 
9630                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9631               offset++;
9632             }
9633             /* the last byte depending on type */
9634             switch (p_type) {
9635             case IPOINTER:
9636             case POINTER:
9637                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9638                 break;
9639             case FPOINTER:
9640               pic14_emitcode(";BUG!? ","%d",__LINE__);
9641                 l = one;
9642                 break;
9643             case CPOINTER:
9644               pic14_emitcode(";BUG!? ","%d",__LINE__);
9645                 l = "#0x02";
9646                 break;                          
9647             case PPOINTER:
9648               pic14_emitcode(";BUG!? ","%d",__LINE__);
9649                 l = "#0x03";
9650                 break;
9651                 
9652             default:
9653                 /* this should never happen */
9654                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9655                        "got unknown pointer type");
9656                 exit(1);
9657             }
9658             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9659             goto release ;
9660         }
9661         
9662         /* just copy the pointers */
9663         size = AOP_SIZE(result);
9664         offset = 0 ;
9665         while (size--) {
9666             aopPut(AOP(result),
9667                    aopGet(AOP(right),offset,FALSE,FALSE),
9668                    offset);
9669             offset++;
9670         }
9671         goto release ;
9672     }
9673     
9674
9675
9676     /* so we now know that the size of destination is greater
9677     than the size of the source.
9678     Now, if the next iCode is an operator then we might be
9679     able to optimize the operation without performing a cast.
9680     */
9681     if(genMixedOperation(ic))
9682       goto release;
9683
9684     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9685     
9686     /* we move to result for the size of source */
9687     size = AOP_SIZE(right);
9688     offset = 0 ;
9689     while (size--) {
9690       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9691       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9692       offset++;
9693     }
9694
9695     /* now depending on the sign of the destination */
9696     size = AOP_SIZE(result) - AOP_SIZE(right);
9697     /* if unsigned or not an integral type */
9698     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9699       while (size--)
9700         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9701     } else {
9702       /* we need to extend the sign :{ */
9703
9704       if(size == 1) {
9705         /* Save one instruction of casting char to int */
9706         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9707         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9708         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9709       } else {
9710         emitpcodeNULLop(POC_CLRW);
9711
9712         if(offset)
9713           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9714         else
9715           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9716         
9717         emitpcode(POC_MOVLW,   popGetLit(0xff));
9718
9719         while (size--)
9720           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9721       }
9722     }
9723
9724 release:
9725     freeAsmop(right,NULL,ic,TRUE);
9726     freeAsmop(result,NULL,ic,TRUE);
9727
9728 }
9729
9730 /*-----------------------------------------------------------------*/
9731 /* genDjnz - generate decrement & jump if not zero instrucion      */
9732 /*-----------------------------------------------------------------*/
9733 static int genDjnz (iCode *ic, iCode *ifx)
9734 {
9735     symbol *lbl, *lbl1;
9736     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9737
9738     if (!ifx)
9739         return 0;
9740     
9741     /* if the if condition has a false label
9742        then we cannot save */
9743     if (IC_FALSE(ifx))
9744         return 0;
9745
9746     /* if the minus is not of the form 
9747        a = a - 1 */
9748     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9749         !IS_OP_LITERAL(IC_RIGHT(ic)))
9750         return 0;
9751
9752     if (operandLitValue(IC_RIGHT(ic)) != 1)
9753         return 0;
9754
9755     /* if the size of this greater than one then no
9756        saving */
9757     if (getSize(operandType(IC_RESULT(ic))) > 1)
9758         return 0;
9759
9760     /* otherwise we can save BIG */
9761     lbl = newiTempLabel(NULL);
9762     lbl1= newiTempLabel(NULL);
9763
9764     aopOp(IC_RESULT(ic),ic,FALSE);
9765     
9766     if (IS_AOP_PREG(IC_RESULT(ic))) {
9767         pic14_emitcode("dec","%s",
9768                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9769         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9770         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9771     } else {    
9772
9773
9774       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9775       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9776
9777       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9778       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9779
9780     }
9781 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9782 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9783 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9784 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9785
9786     
9787     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9788     ifx->generated = 1;
9789     return 1;
9790 }
9791
9792 /*-----------------------------------------------------------------*/
9793 /* genReceive - generate code for a receive iCode                  */
9794 /*-----------------------------------------------------------------*/
9795 static void genReceive (iCode *ic)
9796 {    
9797   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9798
9799   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9800       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9801         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9802
9803     int size = getSize(operandType(IC_RESULT(ic)));
9804     int offset =  fReturnSizePic - size;
9805     while (size--) {
9806       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9807                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9808       offset++;
9809     }
9810     aopOp(IC_RESULT(ic),ic,FALSE);  
9811     size = AOP_SIZE(IC_RESULT(ic));
9812     offset = 0;
9813     while (size--) {
9814       pic14_emitcode ("pop","acc");
9815       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9816     }
9817         
9818   } else {
9819     _G.accInUse++;
9820     aopOp(IC_RESULT(ic),ic,FALSE);  
9821     _G.accInUse--;
9822     assignResultValue(IC_RESULT(ic));   
9823   }
9824
9825   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9826 }
9827
9828 /*-----------------------------------------------------------------*/
9829 /* genpic14Code - generate code for pic14 based controllers        */
9830 /*-----------------------------------------------------------------*/
9831 /*
9832  * At this point, ralloc.c has gone through the iCode and attempted
9833  * to optimize in a way suitable for a PIC. Now we've got to generate
9834  * PIC instructions that correspond to the iCode.
9835  *
9836  * Once the instructions are generated, we'll pass through both the
9837  * peep hole optimizer and the pCode optimizer.
9838  *-----------------------------------------------------------------*/
9839
9840 void genpic14Code (iCode *lic)
9841 {
9842     iCode *ic;
9843     int cln = 0;
9844
9845     lineHead = lineCurr = NULL;
9846
9847     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9848     addpBlock(pb);
9849
9850     /* if debug information required */
9851     if (options.debug && currFunc) { 
9852       if (currFunc) {
9853         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9854         _G.debugLine = 1;
9855         if (IS_STATIC(currFunc->etype)) {
9856           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9857           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9858         } else {
9859           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9860           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9861         }
9862         _G.debugLine = 0;
9863       }
9864     }
9865
9866
9867     for (ic = lic ; ic ; ic = ic->next ) {
9868
9869       DEBUGpic14_emitcode(";ic","");
9870         if ( cln != ic->lineno ) {
9871             if ( options.debug ) {
9872                 _G.debugLine = 1;
9873                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9874                          FileBaseName(ic->filename),ic->lineno,
9875                          ic->level,ic->block);
9876                 _G.debugLine = 0;
9877             }
9878             /*
9879               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9880               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9881               printCLine(ic->filename, ic->lineno));
9882             */
9883             addpCode2pBlock(pb,
9884                             newpCodeCSource(ic->lineno, 
9885                                             ic->filename, 
9886                                             printCLine(ic->filename, ic->lineno)));
9887
9888             cln = ic->lineno ;
9889         }
9890         /* if the result is marked as
9891            spilt and rematerializable or code for
9892            this has already been generated then
9893            do nothing */
9894         if (resultRemat(ic) || ic->generated ) 
9895             continue ;
9896         
9897         /* depending on the operation */
9898         switch (ic->op) {
9899         case '!' :
9900             genNot(ic);
9901             break;
9902             
9903         case '~' :
9904             genCpl(ic);
9905             break;
9906             
9907         case UNARYMINUS:
9908             genUminus (ic);
9909             break;
9910             
9911         case IPUSH:
9912             genIpush (ic);
9913             break;
9914             
9915         case IPOP:
9916             /* IPOP happens only when trying to restore a 
9917                spilt live range, if there is an ifx statement
9918                following this pop then the if statement might
9919                be using some of the registers being popped which
9920                would destory the contents of the register so
9921                we need to check for this condition and handle it */
9922             if (ic->next            && 
9923                 ic->next->op == IFX &&
9924                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9925                 genIfx (ic->next,ic);
9926             else
9927                 genIpop (ic);
9928             break; 
9929             
9930         case CALL:
9931             genCall (ic);
9932             break;
9933             
9934         case PCALL:
9935             genPcall (ic);
9936             break;
9937             
9938         case FUNCTION:
9939             genFunction (ic);
9940             break;
9941             
9942         case ENDFUNCTION:
9943             genEndFunction (ic);
9944             break;
9945             
9946         case RETURN:
9947             genRet (ic);
9948             break;
9949             
9950         case LABEL:
9951             genLabel (ic);
9952             break;
9953             
9954         case GOTO:
9955             genGoto (ic);
9956             break;
9957             
9958         case '+' :
9959             genPlus (ic) ;
9960             break;
9961             
9962         case '-' :
9963             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9964                 genMinus (ic);
9965             break;
9966             
9967         case '*' :
9968             genMult (ic);
9969             break;
9970             
9971         case '/' :
9972             genDiv (ic) ;
9973             break;
9974             
9975         case '%' :
9976             genMod (ic);
9977             break;
9978             
9979         case '>' :
9980             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9981             break;
9982             
9983         case '<' :
9984             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9985             break;
9986             
9987         case LE_OP:
9988         case GE_OP:
9989         case NE_OP:
9990             
9991             /* note these two are xlated by algebraic equivalence
9992                during parsing SDCC.y */
9993             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9994                    "got '>=' or '<=' shouldn't have come here");
9995             break;      
9996             
9997         case EQ_OP:
9998             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9999             break;          
10000             
10001         case AND_OP:
10002             genAndOp (ic);
10003             break;
10004             
10005         case OR_OP:
10006             genOrOp (ic);
10007             break;
10008             
10009         case '^' :
10010             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10011             break;
10012             
10013         case '|' :
10014                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10015             break;
10016             
10017         case BITWISEAND:
10018             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10019             break;
10020             
10021         case INLINEASM:
10022             genInline (ic);
10023             break;
10024             
10025         case RRC:
10026             genRRC (ic);
10027             break;
10028             
10029         case RLC:
10030             genRLC (ic);
10031             break;
10032             
10033         case GETHBIT:
10034             genGetHbit (ic);
10035             break;
10036             
10037         case LEFT_OP:
10038             genLeftShift (ic);
10039             break;
10040             
10041         case RIGHT_OP:
10042             genRightShift (ic);
10043             break;
10044             
10045         case GET_VALUE_AT_ADDRESS:
10046             genPointerGet(ic);
10047             break;
10048             
10049         case '=' :
10050             if (POINTER_SET(ic))
10051                 genPointerSet(ic);
10052             else
10053                 genAssign(ic);
10054             break;
10055             
10056         case IFX:
10057             genIfx (ic,NULL);
10058             break;
10059             
10060         case ADDRESS_OF:
10061             genAddrOf (ic);
10062             break;
10063             
10064         case JUMPTABLE:
10065             genJumpTab (ic);
10066             break;
10067             
10068         case CAST:
10069             genCast (ic);
10070             break;
10071             
10072         case RECEIVE:
10073             genReceive(ic);
10074             break;
10075             
10076         case SEND:
10077             addSet(&_G.sendSet,ic);
10078             break;
10079
10080         default :
10081             ic = ic;
10082         }
10083     }
10084     
10085
10086     /* now we are ready to call the 
10087        peep hole optimizer */
10088     if (!options.nopeep) {
10089       peepHole (&lineHead);
10090     }
10091     /* now do the actual printing */
10092     printLine (lineHead,codeOutFile);
10093
10094 #ifdef PCODE_DEBUG
10095     DFPRINTF((stderr,"printing pBlock\n\n"));
10096     printpBlock(stdout,pb);
10097 #endif
10098
10099     return;
10100 }