Changed the type of the result of the ! (NOT) operator to char;
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for pic
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 #include "common.h"
40 #include "SDCCpeeph.h"
41 #include "ralloc.h"
42 #include "pcode.h"
43 #include "gen.h"
44
45
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
51
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
55
56 /* max_key keeps track of the largest label number used in 
57    a function. This is then used to adjust the label offset
58    for the next function.
59 */
60 static int max_key=0;
61 static int GpsuedoStkPtr=0;
62
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
67
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69
70 /* this is the down and dirty file with all kinds of 
71    kludgy & hacky stuff. This is what it is all about
72    CODE GENERATION for a specific MCU . some of the
73    routines may be reusable, will have to see */
74
75 static char *zero = "#0x00";
76 static char *one  = "#0x01";
77 static char *spname = "sp";
78
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
83
84 static char *accUse[] = {"a","b"};
85
86 //static short rbank = -1;
87
88 static struct {
89     short r0Pushed;
90     short r1Pushed;
91     short accInUse;
92     short inLine;
93     short debugLine;
94     short nRegsSaved;
95     set *sendSet;
96 } _G;
97
98 /* Resolved ifx structure. This structure stores information
99    about an iCode ifx that makes it easier to generate code.
100 */
101 typedef struct resolvedIfx {
102   symbol *lbl;     /* pointer to a label */
103   int condition;   /* true or false ifx */
104   int generated;   /* set true when the code associated with the ifx
105                     * is generated */
106 } resolvedIfx;
107
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
112
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
115
116 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
120
121 static  pBlock *pb;
122
123 /*-----------------------------------------------------------------*/
124 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
125 /*                 exponent of 2 is returned, otherwise -1 is      */
126 /*                 returned.                                       */
127 /* note that this is similar to the function `powof2' in SDCCsymt  */
128 /* if(n == 2^y)                                                    */
129 /*   return y;                                                     */
130 /* return -1;                                                      */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
133 {
134   if(num) {
135     if( (num & (num-1)) == 0) {
136       int nshifts = -1;
137       while(num) {
138         num>>=1;
139         nshifts++;
140       }
141       return nshifts;
142     }
143   }
144
145   return -1;
146 }
147
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 {
150
151   DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152                        line_no,
153                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
154                        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
156                        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
158                        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159                        ((result) ? AOP_SIZE(result) : 0));
160
161 }
162
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 {
165
166   DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167                        line_no,
168                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
172                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
174
175 }
176
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 {
179     va_list ap;
180     char lb[INITIAL_INLINEASM];  
181     char *lbp = lb;
182
183     if(!debug_verbose)
184       return;
185
186     va_start(ap,fmt);   
187
188     if (inst && *inst) {
189         if (fmt && *fmt)
190             sprintf(lb,"%s\t",inst);
191         else
192             sprintf(lb,"%s",inst);
193         vsprintf(lb+(strlen(lb)),fmt,ap);
194     }  else
195         vsprintf(lb,fmt,ap);
196
197     while (isspace(*lbp)) lbp++;
198
199     if (lbp && *lbp) 
200         lineCurr = (lineCurr ?
201                     connectLine(lineCurr,newLineNode(lb)) :
202                     (lineHead = newLineNode(lb)));
203     lineCurr->isInline = _G.inLine;
204     lineCurr->isDebug  = _G.debugLine;
205
206     addpCode2pBlock(pb,newpCodeCharP(lb));
207
208     va_end(ap);
209 }
210
211
212 void emitpLabel(int key)
213 {
214   addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 }
216
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 {
219   if(pcop)
220     addpCode2pBlock(pb,newpCode(poc,pcop));
221   else
222     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
223 }
224
225 void emitpcodeNULLop(PIC_OPCODE poc)
226 {
227
228   addpCode2pBlock(pb,newpCode(poc,NULL));
229
230 }
231
232 void emitpcodePagesel(const char *label)
233 {
234
235   char code[81];
236   strcpy(code,"\tpagesel ");
237   strcat(code,label);
238   addpCode2pBlock(pb,newpCodeInlineP(code));
239
240 }
241
242 /*-----------------------------------------------------------------*/
243 /* pic14_emitcode - writes the code into a file : for now it is simple    */
244 /*-----------------------------------------------------------------*/
245 void pic14_emitcode (char *inst,char *fmt, ...)
246 {
247     va_list ap;
248     char lb[INITIAL_INLINEASM];  
249     char *lbp = lb;
250
251     va_start(ap,fmt);   
252
253     if (inst && *inst) {
254         if (fmt && *fmt)
255             sprintf(lb,"%s\t",inst);
256         else
257             sprintf(lb,"%s",inst);
258         vsprintf(lb+(strlen(lb)),fmt,ap);
259     }  else
260         vsprintf(lb,fmt,ap);
261
262     while (isspace(*lbp)) lbp++;
263
264     if (lbp && *lbp) 
265         lineCurr = (lineCurr ?
266                     connectLine(lineCurr,newLineNode(lb)) :
267                     (lineHead = newLineNode(lb)));
268     lineCurr->isInline = _G.inLine;
269     lineCurr->isDebug  = _G.debugLine;
270
271     if(debug_verbose)
272       addpCode2pBlock(pb,newpCodeCharP(lb));
273
274     va_end(ap);
275 }
276
277
278 /*-----------------------------------------------------------------*/
279 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
280 /*-----------------------------------------------------------------*/
281 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
282 {
283     bool r0iu = FALSE , r1iu = FALSE;
284     bool r0ou = FALSE , r1ou = FALSE;
285
286     /* the logic: if r0 & r1 used in the instruction
287     then we are in trouble otherwise */
288
289     /* first check if r0 & r1 are used by this
290     instruction, in which case we are in trouble */
291     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
292         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
293     {
294         goto endOfWorld;      
295     }
296
297     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
298     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
299
300     /* if no usage of r0 then return it */
301     if (!r0iu && !r0ou) {
302         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
303         (*aopp)->type = AOP_R0;
304         
305         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
306     }
307
308     /* if no usage of r1 then return it */
309     if (!r1iu && !r1ou) {
310         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
311         (*aopp)->type = AOP_R1;
312
313         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
314     }    
315
316     /* now we know they both have usage */
317     /* if r0 not used in this instruction */
318     if (!r0iu) {
319         /* push it if not already pushed */
320         if (!_G.r0Pushed) {
321           //pic14_emitcode ("push","%s",
322           //          pic14_regWithIdx(R0_IDX)->dname);
323             _G.r0Pushed++ ;
324         }
325         
326         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
327         (*aopp)->type = AOP_R0;
328
329         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
330     }
331
332     /* if r1 not used then */
333
334     if (!r1iu) {
335         /* push it if not already pushed */
336         if (!_G.r1Pushed) {
337           //pic14_emitcode ("push","%s",
338           //          pic14_regWithIdx(R1_IDX)->dname);
339             _G.r1Pushed++ ;
340         }
341         
342         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
343         (*aopp)->type = AOP_R1;
344         return pic14_regWithIdx(R1_IDX);
345     }
346
347 endOfWorld :
348     /* I said end of world but not quite end of world yet */
349     /* if this is a result then we can push it on the stack*/
350     if (result) {
351         (*aopp)->type = AOP_STK;    
352         return NULL;
353     }
354
355     /* other wise this is true end of the world */
356     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
357            "getFreePtr should never reach here");
358     exit(0);
359 }
360
361 /*-----------------------------------------------------------------*/
362 /* newAsmop - creates a new asmOp                                  */
363 /*-----------------------------------------------------------------*/
364 asmop *newAsmop (short type)
365 {
366     asmop *aop;
367
368     aop = Safe_calloc(1,sizeof(asmop));
369     aop->type = type;
370     return aop;
371 }
372
373 static void genSetDPTR(int n)
374 {
375     if (!n)
376     {
377         pic14_emitcode(";", "Select standard DPTR");
378         pic14_emitcode("mov", "dps, #0x00");
379     }
380     else
381     {
382         pic14_emitcode(";", "Select alternate DPTR");
383         pic14_emitcode("mov", "dps, #0x01");
384     }
385 }
386
387 /*-----------------------------------------------------------------*/
388 /* resolveIfx - converts an iCode ifx into a form more useful for  */
389 /*              generating code                                    */
390 /*-----------------------------------------------------------------*/
391 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
392 {
393   if(!resIfx) 
394     return;
395
396   //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
397
398   resIfx->condition = 1;    /* assume that the ifx is true */
399   resIfx->generated = 0;    /* indicate that the ifx has not been used */
400
401   if(!ifx) {
402     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
403 /*
404     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
405                         __FUNCTION__,__LINE__,resIfx->lbl->key);
406 */
407   } else {
408     if(IC_TRUE(ifx)) {
409       resIfx->lbl = IC_TRUE(ifx);
410     } else {
411       resIfx->lbl = IC_FALSE(ifx);
412       resIfx->condition = 0;
413     }
414 /*
415     if(IC_TRUE(ifx)) 
416       DEBUGpic14_emitcode("; ***","ifx true is non-null");
417     if(IC_FALSE(ifx)) 
418       DEBUGpic14_emitcode("; ***","ifx false is non-null");
419 */
420   }
421
422   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
423
424 }
425 /*-----------------------------------------------------------------*/
426 /* pointerCode - returns the code for a pointer type               */
427 /*-----------------------------------------------------------------*/
428 static int pointerCode (sym_link *etype)
429 {
430
431     return PTR_TYPE(SPEC_OCLS(etype));
432
433 }
434
435 /*-----------------------------------------------------------------*/
436 /* aopForSym - for a true symbol                                   */
437 /*-----------------------------------------------------------------*/
438 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
439 {
440     asmop *aop;
441     memmap *space= SPEC_OCLS(sym->etype);
442
443     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
444     /* if already has one */
445     if (sym->aop)
446         return sym->aop;
447
448     /* assign depending on the storage class */
449     /* if it is on the stack or indirectly addressable */
450     /* space we need to assign either r0 or r1 to it   */    
451     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
452         sym->aop = aop = newAsmop(0);
453         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
454         aop->size = getSize(sym->type);
455
456         /* now assign the address of the variable to 
457         the pointer register */
458         if (aop->type != AOP_STK) {
459
460             if (sym->onStack) {
461                     if ( _G.accInUse )
462                         pic14_emitcode("push","acc");
463
464                     pic14_emitcode("mov","a,_bp");
465                     pic14_emitcode("add","a,#0x%02x",
466                              ((sym->stack < 0) ?
467                               ((char)(sym->stack - _G.nRegsSaved )) :
468                               ((char)sym->stack)) & 0xff);
469                     pic14_emitcode("mov","%s,a",
470                              aop->aopu.aop_ptr->name);
471
472                     if ( _G.accInUse )
473                         pic14_emitcode("pop","acc");
474             } else
475                 pic14_emitcode("mov","%s,#%s",
476                          aop->aopu.aop_ptr->name,
477                          sym->rname);
478             aop->paged = space->paged;
479         } else
480             aop->aopu.aop_stk = sym->stack;
481         return aop;
482     }
483     
484     if (sym->onStack && options.stack10bit)
485     {
486         /* It's on the 10 bit stack, which is located in
487          * far data space.
488          */
489          
490       //DEBUGpic14_emitcode(";","%d",__LINE__);
491
492         if ( _G.accInUse )
493                 pic14_emitcode("push","acc");
494
495         pic14_emitcode("mov","a,_bp");
496         pic14_emitcode("add","a,#0x%02x",
497                  ((sym->stack < 0) ?
498                    ((char)(sym->stack - _G.nRegsSaved )) :
499                    ((char)sym->stack)) & 0xff);
500         
501         genSetDPTR(1);
502         pic14_emitcode ("mov","dpx1,#0x40");
503         pic14_emitcode ("mov","dph1,#0x00");
504         pic14_emitcode ("mov","dpl1, a");
505         genSetDPTR(0);
506         
507         if ( _G.accInUse )
508             pic14_emitcode("pop","acc");
509             
510         sym->aop = aop = newAsmop(AOP_DPTR2);
511         aop->size = getSize(sym->type); 
512         return aop;
513     }
514
515     //DEBUGpic14_emitcode(";","%d",__LINE__);
516     /* if in bit space */
517     if (IN_BITSPACE(space)) {
518         sym->aop = aop = newAsmop (AOP_CRY);
519         aop->aopu.aop_dir = sym->rname ;
520         aop->size = getSize(sym->type);
521         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
522         return aop;
523     }
524     /* if it is in direct space */
525     if (IN_DIRSPACE(space)) {
526         sym->aop = aop = newAsmop (AOP_DIR);
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
533     /* special case for a function */
534     if (IS_FUNC(sym->type)) {   
535
536       sym->aop = aop = newAsmop(AOP_PCODE);
537       aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
538       PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
539       PCOI(aop->aopu.pcop)->_function = 1;
540       PCOI(aop->aopu.pcop)->index = 0;
541       aop->size = FPTRSIZE; 
542       /*
543         sym->aop = aop = newAsmop(AOP_IMMD);    
544         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
545         strcpy(aop->aopu.aop_immd,sym->rname);
546         aop->size = FPTRSIZE; 
547       */
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,0);
558     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559     PCOI(aop->aopu.pcop)->index = 0;
560
561     DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
562                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
563
564     allocDirReg (IC_LEFT(ic));
565
566     aop->size = FPTRSIZE; 
567 /*
568     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569     sym->aop = aop = newAsmop(AOP_DPTR);
570     pic14_emitcode ("mov","dptr,#%s", sym->rname);
571     aop->size = getSize(sym->type);
572
573     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
574 */
575
576     /* if it is in code space */
577     if (IN_CODESPACE(space))
578         aop->code = 1;
579
580     return aop;     
581 }
582
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object                           */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
587 {
588   symbol *sym = OP_SYMBOL(op);
589   iCode *ic = NULL;
590   asmop *aop = newAsmop(AOP_PCODE);
591   int val = 0;
592   int offset = 0;
593
594   ic = sym->rematiCode;
595
596   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597   if(IS_OP_POINTER(op)) {
598     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
599   }
600   for (;;) {
601     if (ic->op == '+') {
602       val += (int) operandLitValue(IC_RIGHT(ic));
603     } else if (ic->op == '-') {
604       val -= (int) operandLitValue(IC_RIGHT(ic));
605     } else
606       break;
607         
608     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
609   }
610
611   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
613   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614   PCOI(aop->aopu.pcop)->index = val;
615
616   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
617                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
618                       val, IS_PTR_CONST(operandType(op)));
619
620   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
621
622   allocDirReg (IC_LEFT(ic));
623
624   return aop;        
625 }
626
627 int aopIdx (asmop *aop, int offset)
628 {
629   if(!aop)
630     return -1;
631
632   if(aop->type !=  AOP_REG)
633     return -2;
634         
635   return aop->aopu.aop_reg[offset]->rIdx;
636
637 }
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common       */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
642 {
643     symbol *sym1, *sym2;
644     int i;
645
646     /* if they have registers in common */
647     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
648         return FALSE ;
649
650     sym1 = OP_SYMBOL(op1);
651     sym2 = OP_SYMBOL(op2);
652
653     if (sym1->nRegs == 0 || sym2->nRegs == 0)
654         return FALSE ;
655
656     for (i = 0 ; i < sym1->nRegs ; i++) {
657         int j;
658         if (!sym1->regs[i])
659             continue ;
660
661         for (j = 0 ; j < sym2->nRegs ;j++ ) {
662             if (!sym2->regs[j])
663                 continue ;
664
665             if (sym2->regs[j] == sym1->regs[i])
666                 return TRUE ;
667         }
668     }
669
670     return FALSE ;
671 }
672
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent                                        */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
677 {
678     symbol *sym1, *sym2;
679
680     /* if they not symbols */
681     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
682         return FALSE;
683
684     sym1 = OP_SYMBOL(op1);
685     sym2 = OP_SYMBOL(op2);
686
687     /* if both are itemps & one is spilt
688        and the other is not then false */
689     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690         sym1->isspilt != sym2->isspilt )
691         return FALSE ;
692
693     /* if they are the same */
694     if (sym1 == sym2)
695         return TRUE ;
696
697     if (strcmp(sym1->rname,sym2->rname) == 0)
698         return TRUE;
699
700
701     /* if left is a tmp & right is not */
702     if (IS_ITEMP(op1)  && 
703         !IS_ITEMP(op2) &&
704         sym1->isspilt  &&
705         (sym1->usl.spillLoc == sym2))
706         return TRUE;
707
708     if (IS_ITEMP(op2)  && 
709         !IS_ITEMP(op1) &&
710         sym2->isspilt  &&
711         sym1->level > 0 &&
712         (sym2->usl.spillLoc == sym1))
713         return TRUE ;
714
715     return FALSE ;
716 }
717
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers                   */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 {
723     int i;
724
725     if (aop1 == aop2)
726         return TRUE ;
727
728     if (aop1->type != AOP_REG ||
729         aop2->type != AOP_REG )
730         return FALSE ;
731
732     if (aop1->size != aop2->size )
733         return FALSE ;
734
735     for (i = 0 ; i < aop1->size ; i++ )
736         if (aop1->aopu.aop_reg[i] !=
737             aop2->aopu.aop_reg[i] )
738             return FALSE ;
739
740     return TRUE ;
741 }
742
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand  :                    */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
747 {
748     asmop *aop;
749     symbol *sym;
750     int i;
751
752     if (!op)
753         return ;
754
755     //    DEBUGpic14_emitcode(";","%d",__LINE__);
756     /* if this a literal */
757     if (IS_OP_LITERAL(op)) {
758         op->aop = aop = newAsmop(AOP_LIT);
759         aop->aopu.aop_lit = op->operand.valOperand;
760         aop->size = getSize(operandType(op));
761         return;
762     }
763
764     {
765       sym_link *type = operandType(op);
766       if(IS_PTR_CONST(type))
767         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
768     }
769
770     /* if already has a asmop then continue */
771     if (op->aop)
772         return ;
773
774     /* if the underlying symbol has a aop */
775     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776       DEBUGpic14_emitcode(";","%d",__LINE__);
777         op->aop = OP_SYMBOL(op)->aop;
778         return;
779     }
780
781     /* if this is a true symbol */
782     if (IS_TRUE_SYMOP(op)) {    
783       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
785       return ;
786     }
787
788     /* this is a temporary : this has
789     only four choices :
790     a) register
791     b) spillocation
792     c) rematerialize 
793     d) conditional   
794     e) can be a return use only */
795
796     sym = OP_SYMBOL(op);
797
798
799     /* if the type is a conditional */
800     if (sym->regType == REG_CND) {
801         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
802         aop->size = 0;
803         return;
804     }
805
806     /* if it is spilt then two situations
807     a) is rematerialize 
808     b) has a spill location */
809     if (sym->isspilt || sym->nRegs == 0) {
810
811       DEBUGpic14_emitcode(";","%d",__LINE__);
812         /* rematerialize it NOW */
813         if (sym->remat) {
814
815             sym->aop = op->aop = aop =
816                                       aopForRemat (op);
817             aop->size = getSize(sym->type);
818             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
819             return;
820         }
821
822         if (sym->accuse) {
823             int i;
824             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825             aop->size = getSize(sym->type);
826             for ( i = 0 ; i < 2 ; i++ )
827                 aop->aopu.aop_str[i] = accUse[i];
828             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
829             return;  
830         }
831
832         if (sym->ruonly ) {
833           if(sym->isptr) {  // && sym->uptr 
834             aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
835             aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
836
837             //PCOI(aop->aopu.pcop)->_const = 0;
838             //PCOI(aop->aopu.pcop)->index = 0;
839             /*
840               DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
841               __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
842             */
843             //allocDirReg (IC_LEFT(ic));
844
845             aop->size = getSize(sym->type);
846             DEBUGpic14_emitcode(";","%d",__LINE__);
847             return;
848
849           } else {
850
851             unsigned i;
852
853             aop = op->aop = sym->aop = newAsmop(AOP_STR);
854             aop->size = getSize(sym->type);
855             for ( i = 0 ; i < fReturnSizePic ; i++ )
856               aop->aopu.aop_str[i] = fReturn[i];
857
858             DEBUGpic14_emitcode(";","%d",__LINE__);
859             return;
860           }
861         }
862
863         /* else spill location  */
864         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
865             /* force a new aop if sizes differ */
866             sym->usl.spillLoc->aop = NULL;
867         }
868         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
869                             __FUNCTION__,__LINE__,
870                             sym->usl.spillLoc->rname,
871                             sym->rname, sym->usl.spillLoc->offset);
872
873         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
874         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
875         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
876                                           getSize(sym->type), 
877                                           sym->usl.spillLoc->offset);
878         aop->size = getSize(sym->type);
879
880         return;
881     }
882
883     {
884       sym_link *type = operandType(op);
885       if(IS_PTR_CONST(type)) 
886         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
887     }
888
889     /* must be in a register */
890     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
891     sym->aop = op->aop = aop = newAsmop(AOP_REG);
892     aop->size = sym->nRegs;
893     for ( i = 0 ; i < sym->nRegs ;i++)
894         aop->aopu.aop_reg[i] = sym->regs[i];
895 }
896
897 /*-----------------------------------------------------------------*/
898 /* freeAsmop - free up the asmop given to an operand               */
899 /*----------------------------------------------------------------*/
900 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
901 {   
902     asmop *aop ;
903
904     if (!op)
905         aop = aaop;
906     else 
907         aop = op->aop;
908
909     if (!aop)
910         return ;
911
912     if (aop->freed)
913         goto dealloc; 
914
915     aop->freed = 1;
916
917     /* depending on the asmop type only three cases need work AOP_RO
918        , AOP_R1 && AOP_STK */
919 #if 0
920     switch (aop->type) {
921         case AOP_R0 :
922             if (_G.r0Pushed ) {
923                 if (pop) {
924                     pic14_emitcode ("pop","ar0");     
925                     _G.r0Pushed--;
926                 }
927             }
928             bitVectUnSetBit(ic->rUsed,R0_IDX);
929             break;
930
931         case AOP_R1 :
932             if (_G.r1Pushed ) {
933                 if (pop) {
934                     pic14_emitcode ("pop","ar1");
935                     _G.r1Pushed--;
936                 }
937             }
938             bitVectUnSetBit(ic->rUsed,R1_IDX);          
939             break;
940
941         case AOP_STK :
942         {
943             int sz = aop->size;    
944             int stk = aop->aopu.aop_stk + aop->size;
945             bitVectUnSetBit(ic->rUsed,R0_IDX);
946             bitVectUnSetBit(ic->rUsed,R1_IDX);          
947
948             getFreePtr(ic,&aop,FALSE);
949             
950             if (options.stack10bit)
951             {
952                 /* I'm not sure what to do here yet... */
953                 /* #STUB */
954                 fprintf(stderr, 
955                         "*** Warning: probably generating bad code for "
956                         "10 bit stack mode.\n");
957             }
958             
959             if (stk) {
960                 pic14_emitcode ("mov","a,_bp");
961                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
962                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
963             } else {
964                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
965             }
966
967             while (sz--) {
968                 pic14_emitcode("pop","acc");
969                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
970                 if (!sz) break;
971                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
972             }
973             op->aop = aop;
974             freeAsmop(op,NULL,ic,TRUE);
975             if (_G.r0Pushed) {
976                 pic14_emitcode("pop","ar0");
977                 _G.r0Pushed--;
978             }
979
980             if (_G.r1Pushed) {
981                 pic14_emitcode("pop","ar1");
982                 _G.r1Pushed--;
983             }       
984         }
985     }
986 #endif
987
988 dealloc:
989     /* all other cases just dealloc */
990     if (op ) {
991         op->aop = NULL;
992         if (IS_SYMOP(op)) {
993             OP_SYMBOL(op)->aop = NULL;    
994             /* if the symbol has a spill */
995             if (SPIL_LOC(op))
996                 SPIL_LOC(op)->aop = NULL;
997         }
998     }
999 }
1000
1001 /*-----------------------------------------------------------------*/
1002 /* aopGet - for fetching value of the aop                          */
1003 /*-----------------------------------------------------------------*/
1004 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1005 {
1006     char *s = buffer ;
1007     char *rs;
1008
1009     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1010     /* offset is greater than
1011     size then zero */
1012     if (offset > (aop->size - 1) &&
1013         aop->type != AOP_LIT)
1014         return zero;
1015
1016     /* depending on type */
1017     switch (aop->type) {
1018         
1019     case AOP_R0:
1020     case AOP_R1:
1021         DEBUGpic14_emitcode(";","%d",__LINE__);
1022         /* if we need to increment it */       
1023         while (offset > aop->coff) {        
1024             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1025             aop->coff++;
1026         }
1027         
1028         while (offset < aop->coff) {
1029             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1030             aop->coff--;
1031         }
1032         
1033         aop->coff = offset ;
1034         if (aop->paged) {
1035             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1036             return (dname ? "acc" : "a");
1037         }       
1038         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1039         rs = Safe_calloc(1,strlen(s)+1);
1040         strcpy(rs,s);   
1041         return rs;
1042         
1043     case AOP_DPTR:
1044     case AOP_DPTR2:
1045         DEBUGpic14_emitcode(";","%d",__LINE__);
1046     if (aop->type == AOP_DPTR2)
1047     {
1048         genSetDPTR(1);
1049     }
1050     
1051         while (offset > aop->coff) {
1052             pic14_emitcode ("inc","dptr");
1053             aop->coff++;
1054         }
1055         
1056         while (offset < aop->coff) {        
1057             pic14_emitcode("lcall","__decdptr");
1058             aop->coff--;
1059         }
1060         
1061         aop->coff = offset;
1062         if (aop->code) {
1063             pic14_emitcode("clr","a");
1064             pic14_emitcode("movc","a,@a+dptr");
1065         }
1066     else {
1067             pic14_emitcode("movx","a,@dptr");
1068     }
1069             
1070     if (aop->type == AOP_DPTR2)
1071     {
1072         genSetDPTR(0);
1073     }
1074             
1075     return (dname ? "acc" : "a");
1076         
1077         
1078     case AOP_IMMD:
1079         if (bit16) 
1080             sprintf (s,"%s",aop->aopu.aop_immd);
1081         else
1082             if (offset) 
1083                 sprintf(s,"(%s >> %d)",
1084                         aop->aopu.aop_immd,
1085                         offset*8);
1086             else
1087                 sprintf(s,"%s",
1088                         aop->aopu.aop_immd);
1089         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1090         rs = Safe_calloc(1,strlen(s)+1);
1091         strcpy(rs,s);   
1092         return rs;
1093         
1094     case AOP_DIR:
1095       if (offset) {
1096         sprintf(s,"(%s + %d)",
1097                 aop->aopu.aop_dir,
1098                 offset);
1099         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1100       } else
1101             sprintf(s,"%s",aop->aopu.aop_dir);
1102         rs = Safe_calloc(1,strlen(s)+1);
1103         strcpy(rs,s);   
1104         return rs;
1105         
1106     case AOP_REG:
1107       //if (dname) 
1108       //    return aop->aopu.aop_reg[offset]->dname;
1109       //else
1110             return aop->aopu.aop_reg[offset]->name;
1111         
1112     case AOP_CRY:
1113       //pic14_emitcode(";","%d",__LINE__);
1114       return aop->aopu.aop_dir;
1115         
1116     case AOP_ACC:
1117         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1118         return "AOP_accumulator_bug";
1119
1120     case AOP_LIT:
1121         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1122         rs = Safe_calloc(1,strlen(s)+1);
1123         strcpy(rs,s);   
1124         return rs;
1125         
1126     case AOP_STR:
1127         aop->coff = offset ;
1128         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1129             dname)
1130             return "acc";
1131         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1132         
1133         return aop->aopu.aop_str[offset];
1134         
1135     case AOP_PCODE:
1136       {
1137         pCodeOp *pcop = aop->aopu.pcop;
1138         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1139         if(pcop->name) {
1140           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1141           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1142           sprintf(s,"%s", pcop->name);
1143         } else
1144           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1145
1146       }
1147       rs = Safe_calloc(1,strlen(s)+1);
1148       strcpy(rs,s);   
1149       return rs;
1150
1151     }
1152
1153     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1154            "aopget got unsupported aop->type");
1155     exit(0);
1156 }
1157
1158
1159 /*-----------------------------------------------------------------*/
1160 /* popGetTempReg - create a new temporary pCodeOp                  */
1161 /*-----------------------------------------------------------------*/
1162 pCodeOp *popGetTempReg(void)
1163 {
1164
1165   pCodeOp *pcop;
1166
1167   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1168   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1169     PCOR(pcop)->r->wasUsed=1;
1170     PCOR(pcop)->r->isFree=0;
1171   }
1172
1173   return pcop;
1174 }
1175
1176 /*-----------------------------------------------------------------*/
1177 /* popGetTempReg - create a new temporary pCodeOp                  */
1178 /*-----------------------------------------------------------------*/
1179 void popReleaseTempReg(pCodeOp *pcop)
1180 {
1181
1182   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1183     PCOR(pcop)->r->isFree = 1;
1184
1185 }
1186 /*-----------------------------------------------------------------*/
1187 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1188 /*-----------------------------------------------------------------*/
1189 pCodeOp *popGetLabel(unsigned int key)
1190 {
1191
1192   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1193
1194   if(key>(unsigned int)max_key)
1195     max_key = key;
1196
1197   return newpCodeOpLabel(NULL,key+100+labelOffset);
1198 }
1199
1200 /*-------------------------------------------------------------------*/
1201 /* popGetLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1202 /*-------------------------------------------------------------------*/
1203 pCodeOp *popGetHighLabel(unsigned int key)
1204 {
1205   pCodeOp *pcop;
1206   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1207
1208   if(key>(unsigned int)max_key)
1209     max_key = key;
1210
1211   pcop = newpCodeOpLabel(NULL,key+100+labelOffset);
1212   PCOLAB(pcop)->offset = 1;
1213   return pcop;
1214 }
1215
1216 /*-----------------------------------------------------------------*/
1217 /* popCopyReg - copy a pcode operator                              */
1218 /*-----------------------------------------------------------------*/
1219 pCodeOp *popCopyReg(pCodeOpReg *pc)
1220 {
1221   pCodeOpReg *pcor;
1222
1223   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1224   pcor->pcop.type = pc->pcop.type;
1225   if(pc->pcop.name) {
1226     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1227       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1228   } else
1229     pcor->pcop.name = NULL;
1230
1231   pcor->r = pc->r;
1232   pcor->rIdx = pc->rIdx;
1233   pcor->r->wasUsed=1;
1234
1235   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1236
1237   return PCOP(pcor);
1238 }
1239 /*-----------------------------------------------------------------*/
1240 /* popGet - asm operator to pcode operator conversion              */
1241 /*-----------------------------------------------------------------*/
1242 pCodeOp *popGetLit(unsigned int lit)
1243 {
1244
1245   return newpCodeOpLit(lit);
1246 }
1247
1248
1249 /*-----------------------------------------------------------------*/
1250 /* popGetImmd - asm operator to pcode immediate conversion         */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1253 {
1254
1255   return newpCodeOpImmd(name, offset,index, 0, is_func);
1256 }
1257
1258
1259 /*-----------------------------------------------------------------*/
1260 /* popGet - asm operator to pcode operator conversion              */
1261 /*-----------------------------------------------------------------*/
1262 pCodeOp *popGetWithString(char *str)
1263 {
1264   pCodeOp *pcop;
1265
1266
1267   if(!str) {
1268     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1269     exit (1);
1270   }
1271
1272   pcop = newpCodeOp(str,PO_STR);
1273
1274   return pcop;
1275 }
1276
1277 /*-----------------------------------------------------------------*/
1278 /* popRegFromString -                                              */
1279 /*-----------------------------------------------------------------*/
1280 pCodeOp *popRegFromString(char *str, int size, int offset)
1281 {
1282
1283   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284   pcop->type = PO_DIR;
1285
1286   DEBUGpic14_emitcode(";","%d",__LINE__);
1287
1288   if(!str)
1289     str = "BAD_STRING";
1290
1291   pcop->name = Safe_calloc(1,strlen(str)+1);
1292   strcpy(pcop->name,str);
1293
1294   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1295
1296   PCOR(pcop)->r = dirregWithName(pcop->name);
1297   if(PCOR(pcop)->r == NULL) {
1298     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1299     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1300     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1301   } else {
1302     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1303   }
1304   PCOR(pcop)->instance = offset;
1305
1306   return pcop;
1307 }
1308
1309 pCodeOp *popRegFromIdx(int rIdx)
1310 {
1311   pCodeOp *pcop;
1312
1313   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1314                        __FUNCTION__,__LINE__,rIdx);
1315
1316   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1317
1318   PCOR(pcop)->rIdx = rIdx;
1319   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1320   PCOR(pcop)->r->isFree = 0;
1321   PCOR(pcop)->r->wasUsed = 1;
1322
1323   pcop->type = PCOR(pcop)->r->pc_type;
1324
1325
1326   return pcop;
1327 }
1328 /*-----------------------------------------------------------------*/
1329 /* popGet - asm operator to pcode operator conversion              */
1330 /*-----------------------------------------------------------------*/
1331 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1332 {
1333   //char *s = buffer ;
1334     //char *rs;
1335
1336     pCodeOp *pcop;
1337
1338     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1339     /* offset is greater than
1340     size then zero */
1341
1342     if (offset > (aop->size - 1) &&
1343         aop->type != AOP_LIT)
1344       return NULL;  //zero;
1345
1346     /* depending on type */
1347     switch (aop->type) {
1348         
1349     case AOP_R0:
1350     case AOP_R1:
1351     case AOP_DPTR:
1352     case AOP_DPTR2:
1353     case AOP_ACC:
1354         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1355         return NULL;
1356         
1357     case AOP_IMMD:
1358       DEBUGpic14_emitcode(";","%d",__LINE__);
1359       return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1360
1361     case AOP_DIR:
1362       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1363 #if 0
1364         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365         pcop->type = PO_DIR;
1366
1367         /*
1368         if (offset)
1369             sprintf(s,"(%s + %d)",
1370                     aop->aopu.aop_dir,
1371                     offset);
1372         else
1373             sprintf(s,"%s",aop->aopu.aop_dir);
1374         pcop->name = Safe_calloc(1,strlen(s)+1);
1375         strcpy(pcop->name,s);   
1376         */
1377         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1378         strcpy(pcop->name,aop->aopu.aop_dir);   
1379         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380         if(PCOR(pcop)->r == NULL) {
1381           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1382           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1383           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1384         } else {
1385           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1386         }
1387         PCOR(pcop)->instance = offset;
1388
1389         return pcop;
1390 #endif
1391         
1392     case AOP_REG:
1393       {
1394         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1395
1396         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1397         PCOR(pcop)->rIdx = rIdx;
1398         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1399         PCOR(pcop)->r->wasUsed=1;
1400         PCOR(pcop)->r->isFree=0;
1401
1402         PCOR(pcop)->instance = offset;
1403         pcop->type = PCOR(pcop)->r->pc_type;
1404         //rs = aop->aopu.aop_reg[offset]->name;
1405         DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1406         return pcop;
1407       }
1408
1409     case AOP_CRY:
1410       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1411       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1412       //if(PCOR(pcop)->r == NULL)
1413       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1414       return pcop;
1415         
1416     case AOP_LIT:
1417       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1418
1419     case AOP_STR:
1420       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1421       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1422       /*
1423       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1424       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1425       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1426       pcop->type = PCOR(pcop)->r->pc_type;
1427       pcop->name = PCOR(pcop)->r->name;
1428
1429       return pcop;
1430       */
1431
1432     case AOP_PCODE:
1433       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1434                           __LINE__, 
1435                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1436       pcop = pCodeOpCopy(aop->aopu.pcop);
1437       PCOI(pcop)->offset = offset;
1438       return pcop;
1439     }
1440
1441     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1442            "popGet got unsupported aop->type");
1443     exit(0);
1444 }
1445 /*-----------------------------------------------------------------*/
1446 /* aopPut - puts a string for a aop                                */
1447 /*-----------------------------------------------------------------*/
1448 void aopPut (asmop *aop, char *s, int offset)
1449 {
1450     char *d = buffer ;
1451     symbol *lbl ;
1452
1453     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1454
1455     if (aop->size && offset > ( aop->size - 1)) {
1456         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1457                "aopPut got offset > aop->size");
1458         exit(0);
1459     }
1460
1461     /* will assign value to value */
1462     /* depending on where it is ofcourse */
1463     switch (aop->type) {
1464     case AOP_DIR:
1465       if (offset) {
1466         sprintf(d,"(%s + %d)",
1467                 aop->aopu.aop_dir,offset);
1468         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1469
1470       } else
1471             sprintf(d,"%s",aop->aopu.aop_dir);
1472         
1473         if (strcmp(d,s)) {
1474           DEBUGpic14_emitcode(";","%d",__LINE__);
1475           if(strcmp(s,"W"))
1476             pic14_emitcode("movf","%s,w",s);
1477           pic14_emitcode("movwf","%s",d);
1478
1479           if(strcmp(s,"W")) {
1480             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1481             if(offset >= aop->size) {
1482               emitpcode(POC_CLRF,popGet(aop,offset));
1483               break;
1484             } else
1485               emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1486           }
1487
1488           emitpcode(POC_MOVWF,popGet(aop,offset));
1489
1490
1491         }
1492         break;
1493         
1494     case AOP_REG:
1495       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1496         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1497           /*
1498             if (*s == '@'           ||
1499                 strcmp(s,"r0") == 0 ||
1500                 strcmp(s,"r1") == 0 ||
1501                 strcmp(s,"r2") == 0 ||
1502                 strcmp(s,"r3") == 0 ||
1503                 strcmp(s,"r4") == 0 ||
1504                 strcmp(s,"r5") == 0 ||
1505                 strcmp(s,"r6") == 0 || 
1506                 strcmp(s,"r7") == 0 )
1507                 pic14_emitcode("mov","%s,%s  ; %d",
1508                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1509             else
1510           */
1511
1512           if(strcmp(s,"W")==0 )
1513             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1514
1515           pic14_emitcode("movwf","%s",
1516                    aop->aopu.aop_reg[offset]->name);
1517
1518           if(strcmp(s,zero)==0) {
1519             emitpcode(POC_CLRF,popGet(aop,offset));
1520
1521           } else if(strcmp(s,"W")==0) {
1522             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1523             pcop->type = PO_GPR_REGISTER;
1524
1525             PCOR(pcop)->rIdx = -1;
1526             PCOR(pcop)->r = NULL;
1527
1528             DEBUGpic14_emitcode(";","%d",__LINE__);
1529             pcop->name = Safe_strdup(s);
1530             emitpcode(POC_MOVFW,pcop);
1531             emitpcode(POC_MOVWF,popGet(aop,offset));
1532           } else if(strcmp(s,one)==0) {
1533             emitpcode(POC_CLRF,popGet(aop,offset));
1534             emitpcode(POC_INCF,popGet(aop,offset));
1535           } else {
1536             emitpcode(POC_MOVWF,popGet(aop,offset));
1537           }
1538         }
1539         break;
1540         
1541     case AOP_DPTR:
1542     case AOP_DPTR2:
1543     
1544     if (aop->type == AOP_DPTR2)
1545     {
1546         genSetDPTR(1);
1547     }
1548     
1549         if (aop->code) {
1550             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1551                    "aopPut writting to code space");
1552             exit(0);
1553         }
1554         
1555         while (offset > aop->coff) {
1556             aop->coff++;
1557             pic14_emitcode ("inc","dptr");
1558         }
1559         
1560         while (offset < aop->coff) {
1561             aop->coff-- ;
1562             pic14_emitcode("lcall","__decdptr");
1563         }
1564         
1565         aop->coff = offset;
1566         
1567         /* if not in accumulater */
1568         MOVA(s);        
1569         
1570         pic14_emitcode ("movx","@dptr,a");
1571         
1572     if (aop->type == AOP_DPTR2)
1573     {
1574         genSetDPTR(0);
1575     }
1576         break;
1577         
1578     case AOP_R0:
1579     case AOP_R1:
1580         while (offset > aop->coff) {
1581             aop->coff++;
1582             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1583         }
1584         while (offset < aop->coff) {
1585             aop->coff-- ;
1586             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1587         }
1588         aop->coff = offset;
1589         
1590         if (aop->paged) {
1591             MOVA(s);           
1592             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1593             
1594         } else
1595             if (*s == '@') {
1596                 MOVA(s);
1597                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1598             } else
1599                 if (strcmp(s,"r0") == 0 ||
1600                     strcmp(s,"r1") == 0 ||
1601                     strcmp(s,"r2") == 0 ||
1602                     strcmp(s,"r3") == 0 ||
1603                     strcmp(s,"r4") == 0 ||
1604                     strcmp(s,"r5") == 0 ||
1605                     strcmp(s,"r6") == 0 || 
1606                     strcmp(s,"r7") == 0 ) {
1607                     char buffer[10];
1608                     sprintf(buffer,"a%s",s);
1609                     pic14_emitcode("mov","@%s,%s",
1610                              aop->aopu.aop_ptr->name,buffer);
1611                 } else
1612                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1613         
1614         break;
1615         
1616     case AOP_STK:
1617         if (strcmp(s,"a") == 0)
1618             pic14_emitcode("push","acc");
1619         else
1620             pic14_emitcode("push","%s",s);
1621         
1622         break;
1623         
1624     case AOP_CRY:
1625         /* if bit variable */
1626         if (!aop->aopu.aop_dir) {
1627             pic14_emitcode("clr","a");
1628             pic14_emitcode("rlc","a");
1629         } else {
1630             if (s == zero) 
1631                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1632             else
1633                 if (s == one)
1634                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1635                 else
1636                     if (!strcmp(s,"c"))
1637                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1638                     else {
1639                         lbl = newiTempLabel(NULL);
1640                         
1641                         if (strcmp(s,"a")) {
1642                             MOVA(s);
1643                         }
1644                         pic14_emitcode("clr","c");
1645                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1646                         pic14_emitcode("cpl","c");
1647                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1648                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1649                     }
1650         }
1651         break;
1652         
1653     case AOP_STR:
1654         aop->coff = offset;
1655         if (strcmp(aop->aopu.aop_str[offset],s))
1656             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1657         break;
1658         
1659     case AOP_ACC:
1660         aop->coff = offset;
1661         if (!offset && (strcmp(s,"acc") == 0))
1662             break;
1663         
1664         if (strcmp(aop->aopu.aop_str[offset],s))
1665             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1666         break;
1667
1668     default :
1669         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1670                "aopPut got unsupported aop->type");
1671         exit(0);    
1672     }    
1673
1674 }
1675
1676 /*-----------------------------------------------------------------*/
1677 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1678 /*-----------------------------------------------------------------*/
1679 void mov2w (asmop *aop, int offset)
1680 {
1681
1682   if(!aop)
1683     return;
1684
1685   DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1686
1687   if ( aop->type == AOP_PCODE ||
1688        aop->type == AOP_LIT ||
1689        aop->type == AOP_IMMD )
1690     emitpcode(POC_MOVLW,popGet(aop,offset));
1691   else
1692     emitpcode(POC_MOVFW,popGet(aop,offset));
1693
1694 }
1695
1696 /*-----------------------------------------------------------------*/
1697 /* reAdjustPreg - points a register back to where it should        */
1698 /*-----------------------------------------------------------------*/
1699 static void reAdjustPreg (asmop *aop)
1700 {
1701     int size ;
1702
1703     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1704     aop->coff = 0;
1705     if ((size = aop->size) <= 1)
1706         return ;
1707     size-- ;
1708     switch (aop->type) {
1709         case AOP_R0 :
1710         case AOP_R1 :
1711             while (size--)
1712                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1713             break;          
1714         case AOP_DPTR :
1715         case AOP_DPTR2:
1716             if (aop->type == AOP_DPTR2)
1717             {
1718                 genSetDPTR(1);
1719             } 
1720             while (size--)
1721             {
1722                 pic14_emitcode("lcall","__decdptr");
1723             }
1724                 
1725             if (aop->type == AOP_DPTR2)
1726             {
1727                 genSetDPTR(0);
1728             }                
1729             break;  
1730
1731     }   
1732
1733 }
1734
1735
1736 #if 0
1737 /*-----------------------------------------------------------------*/
1738 /* opIsGptr: returns non-zero if the passed operand is             */   
1739 /* a generic pointer type.                                         */
1740 /*-----------------------------------------------------------------*/ 
1741 static int opIsGptr(operand *op)
1742 {
1743     sym_link *type = operandType(op);
1744     
1745     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1746     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1747     {
1748         return 1;
1749     }
1750     return 0;        
1751 }
1752 #endif
1753
1754 /*-----------------------------------------------------------------*/
1755 /* pic14_getDataSize - get the operand data size                         */
1756 /*-----------------------------------------------------------------*/
1757 int pic14_getDataSize(operand *op)
1758 {
1759     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1760
1761
1762     return AOP_SIZE(op);
1763
1764     // tsd- in the pic port, the genptr size is 1, so this code here
1765     // fails. ( in the 8051 port, the size was 4).
1766 #if 0
1767     int size;
1768     size = AOP_SIZE(op);
1769     if (size == GPTRSIZE)
1770     {
1771         sym_link *type = operandType(op);
1772         if (IS_GENPTR(type))
1773         {
1774             /* generic pointer; arithmetic operations
1775              * should ignore the high byte (pointer type).
1776              */
1777             size--;
1778     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1779         }
1780     }
1781     return size;
1782 #endif
1783 }
1784
1785 /*-----------------------------------------------------------------*/
1786 /* pic14_outAcc - output Acc                                             */
1787 /*-----------------------------------------------------------------*/
1788 void pic14_outAcc(operand *result)
1789 {
1790   int size,offset;
1791   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1792   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1793
1794
1795   size = pic14_getDataSize(result);
1796   if(size){
1797     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1798     size--;
1799     offset = 1;
1800     /* unsigned or positive */
1801     while(size--)
1802       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1803   }
1804
1805 }
1806
1807 /*-----------------------------------------------------------------*/
1808 /* pic14_outBitC - output a bit C                                        */
1809 /*-----------------------------------------------------------------*/
1810 void pic14_outBitC(operand *result)
1811 {
1812
1813     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1814     /* if the result is bit */
1815     if (AOP_TYPE(result) == AOP_CRY) 
1816         aopPut(AOP(result),"c",0);
1817     else {
1818         pic14_emitcode("clr","a  ; %d", __LINE__);
1819         pic14_emitcode("rlc","a");
1820         pic14_outAcc(result);
1821     }
1822 }
1823
1824 /*-----------------------------------------------------------------*/
1825 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1826 /*-----------------------------------------------------------------*/
1827 void pic14_toBoolean(operand *oper)
1828 {
1829     int size = AOP_SIZE(oper) - 1;
1830     int offset = 1;
1831
1832     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1833
1834     if ( AOP_TYPE(oper) != AOP_ACC) {
1835       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1836     }
1837     while (size--) {
1838       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1839     }
1840 }
1841
1842
1843 /*-----------------------------------------------------------------*/
1844 /* genNot - generate code for ! operation                          */
1845 /*-----------------------------------------------------------------*/
1846 static void genNot (iCode *ic)
1847 {
1848   symbol *tlbl;
1849   int size;
1850
1851   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1852   /* assign asmOps to operand & result */
1853   aopOp (IC_LEFT(ic),ic,FALSE);
1854   aopOp (IC_RESULT(ic),ic,TRUE);
1855
1856   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1857   /* if in bit space then a special case */
1858   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1859     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1860       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1861       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1862     } else {
1863       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1864       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1865       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1866     }
1867     goto release;
1868   }
1869
1870   size = AOP_SIZE(IC_LEFT(ic));
1871   if(size == 1) {
1872     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1873     emitpcode(POC_ANDLW,popGetLit(1));
1874     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1875     goto release;
1876   }
1877   pic14_toBoolean(IC_LEFT(ic));
1878
1879   tlbl = newiTempLabel(NULL);
1880   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1881   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1882   pic14_outBitC(IC_RESULT(ic));
1883
1884  release:    
1885   /* release the aops */
1886   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1887   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1888 }
1889
1890
1891 /*-----------------------------------------------------------------*/
1892 /* genCpl - generate code for complement                           */
1893 /*-----------------------------------------------------------------*/
1894 static void genCpl (iCode *ic)
1895 {
1896   operand *left, *result;
1897   int size, offset=0;  
1898
1899
1900   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1901   aopOp((left = IC_LEFT(ic)),ic,FALSE);
1902   aopOp((result=IC_RESULT(ic)),ic,TRUE);
1903
1904   /* if both are in bit space then 
1905      a special case */
1906   if (AOP_TYPE(result) == AOP_CRY &&
1907       AOP_TYPE(left) == AOP_CRY ) { 
1908
1909     pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1910     pic14_emitcode("cpl","c"); 
1911     pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1912     goto release; 
1913   } 
1914
1915   size = AOP_SIZE(result);
1916   while (size--) {
1917
1918     if(AOP_TYPE(left) == AOP_ACC) 
1919       emitpcode(POC_XORLW, popGetLit(0xff));
1920     else
1921       emitpcode(POC_COMFW,popGet(AOP(left),offset));
1922
1923     emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1924
1925   }
1926
1927
1928 release:
1929     /* release the aops */
1930     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1931     freeAsmop(result,NULL,ic,TRUE);
1932 }
1933
1934 /*-----------------------------------------------------------------*/
1935 /* genUminusFloat - unary minus for floating points                */
1936 /*-----------------------------------------------------------------*/
1937 static void genUminusFloat(operand *op,operand *result)
1938 {
1939     int size ,offset =0 ;
1940     char *l;
1941
1942     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1943     /* for this we just need to flip the 
1944     first it then copy the rest in place */
1945     size = AOP_SIZE(op) - 1;
1946     l = aopGet(AOP(op),3,FALSE,FALSE);
1947
1948     MOVA(l);    
1949
1950     pic14_emitcode("cpl","acc.7");
1951     aopPut(AOP(result),"a",3);    
1952
1953     while(size--) {
1954         aopPut(AOP(result),
1955                aopGet(AOP(op),offset,FALSE,FALSE),
1956                offset);
1957         offset++;
1958     }          
1959 }
1960
1961 /*-----------------------------------------------------------------*/
1962 /* genUminus - unary minus code generation                         */
1963 /*-----------------------------------------------------------------*/
1964 static void genUminus (iCode *ic)
1965 {
1966   int size, i;
1967   sym_link *optype, *rtype;
1968
1969
1970   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1971   /* assign asmops */
1972   aopOp(IC_LEFT(ic),ic,FALSE);
1973   aopOp(IC_RESULT(ic),ic,TRUE);
1974
1975   /* if both in bit space then special
1976      case */
1977   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1978       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1979
1980     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1981     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1982     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1983
1984     goto release; 
1985   } 
1986
1987   optype = operandType(IC_LEFT(ic));
1988   rtype = operandType(IC_RESULT(ic));
1989
1990   /* if float then do float stuff */
1991   if (IS_FLOAT(optype)) {
1992     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1993     goto release;
1994   }
1995
1996   /* otherwise subtract from zero by taking the 2's complement */
1997   size = AOP_SIZE(IC_LEFT(ic));
1998
1999   for(i=0; i<size; i++) {
2000     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2001       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2002     else {
2003       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2004       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2005     }
2006   }
2007
2008   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2009   for(i=1; i<size; i++) {
2010     emitSKPNZ;
2011     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2012   }
2013
2014  release:
2015   /* release the aops */
2016   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2017   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2018 }
2019
2020 /*-----------------------------------------------------------------*/
2021 /* saveRegisters - will look for a call and save the registers     */
2022 /*-----------------------------------------------------------------*/
2023 static void saveRegisters(iCode *lic) 
2024 {
2025     int i;
2026     iCode *ic;
2027     bitVect *rsave;
2028     sym_link *dtype;
2029
2030     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2031     /* look for call */
2032     for (ic = lic ; ic ; ic = ic->next) 
2033         if (ic->op == CALL || ic->op == PCALL)
2034             break;
2035
2036     if (!ic) {
2037         fprintf(stderr,"found parameter push with no function call\n");
2038         return ;
2039     }
2040
2041     /* if the registers have been saved already then
2042     do nothing */
2043     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2044         return ;
2045
2046     /* find the registers in use at this time 
2047     and push them away to safety */
2048     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2049                           ic->rUsed);
2050
2051     ic->regsSaved = 1;
2052     if (options.useXstack) {
2053         if (bitVectBitValue(rsave,R0_IDX))
2054             pic14_emitcode("mov","b,r0");
2055         pic14_emitcode("mov","r0,%s",spname);
2056         for (i = 0 ; i < pic14_nRegs ; i++) {
2057             if (bitVectBitValue(rsave,i)) {
2058                 if (i == R0_IDX)
2059                     pic14_emitcode("mov","a,b");
2060                 else
2061                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2062                 pic14_emitcode("movx","@r0,a");
2063                 pic14_emitcode("inc","r0");
2064             }
2065         }
2066         pic14_emitcode("mov","%s,r0",spname);
2067         if (bitVectBitValue(rsave,R0_IDX))
2068             pic14_emitcode("mov","r0,b");           
2069     }// else
2070     //for (i = 0 ; i < pic14_nRegs ; i++) {
2071     //    if (bitVectBitValue(rsave,i))
2072     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2073     //}
2074
2075     dtype = operandType(IC_LEFT(ic));
2076     if (currFunc && dtype && 
2077         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2078         IFFUNC_ISISR(currFunc->type) &&
2079         !ic->bankSaved) 
2080
2081         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2082
2083 }
2084 /*-----------------------------------------------------------------*/
2085 /* unsaveRegisters - pop the pushed registers                      */
2086 /*-----------------------------------------------------------------*/
2087 static void unsaveRegisters (iCode *ic)
2088 {
2089     int i;
2090     bitVect *rsave;
2091
2092     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2093     /* find the registers in use at this time 
2094     and push them away to safety */
2095     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2096                           ic->rUsed);
2097     
2098     if (options.useXstack) {
2099         pic14_emitcode("mov","r0,%s",spname);   
2100         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2101             if (bitVectBitValue(rsave,i)) {
2102                 pic14_emitcode("dec","r0");
2103                 pic14_emitcode("movx","a,@r0");
2104                 if (i == R0_IDX)
2105                     pic14_emitcode("mov","b,a");
2106                 else
2107                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2108             }       
2109
2110         }
2111         pic14_emitcode("mov","%s,r0",spname);
2112         if (bitVectBitValue(rsave,R0_IDX))
2113             pic14_emitcode("mov","r0,b");
2114     } //else
2115     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2116     //    if (bitVectBitValue(rsave,i))
2117     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2118     //}
2119
2120 }  
2121
2122
2123 /*-----------------------------------------------------------------*/
2124 /* pushSide -                                                      */
2125 /*-----------------------------------------------------------------*/
2126 static void pushSide(operand * oper, int size)
2127 {
2128 #if 0
2129         int offset = 0;
2130     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2131         while (size--) {
2132                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2133                 if (AOP_TYPE(oper) != AOP_REG &&
2134                     AOP_TYPE(oper) != AOP_DIR &&
2135                     strcmp(l,"a") ) {
2136                         pic14_emitcode("mov","a,%s",l);
2137                         pic14_emitcode("push","acc");
2138                 } else
2139                         pic14_emitcode("push","%s",l);
2140         }
2141 #endif
2142 }
2143
2144 /*-----------------------------------------------------------------*/
2145 /* assignResultValue -                                             */
2146 /*-----------------------------------------------------------------*/
2147 static void assignResultValue(operand * oper)
2148 {
2149   int size = AOP_SIZE(oper);
2150
2151   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2152
2153   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2154
2155   if(!GpsuedoStkPtr) {
2156     /* The last byte in the assignment is in W */
2157     size--;
2158     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2159     GpsuedoStkPtr++;
2160   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2161   }
2162
2163   while (size--) {
2164     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2165     GpsuedoStkPtr++;
2166     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2167   }
2168 }
2169
2170
2171 /*-----------------------------------------------------------------*/
2172 /* genIpush - genrate code for pushing this gets a little complex  */
2173 /*-----------------------------------------------------------------*/
2174 static void genIpush (iCode *ic)
2175 {
2176
2177   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2178 #if 0
2179     int size, offset = 0 ;
2180     char *l;
2181
2182
2183     /* if this is not a parm push : ie. it is spill push 
2184     and spill push is always done on the local stack */
2185     if (!ic->parmPush) {
2186
2187         /* and the item is spilt then do nothing */
2188         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2189             return ;
2190
2191         aopOp(IC_LEFT(ic),ic,FALSE);
2192         size = AOP_SIZE(IC_LEFT(ic));
2193         /* push it on the stack */
2194         while(size--) {
2195             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2196             if (*l == '#') {
2197                 MOVA(l);
2198                 l = "acc";
2199             }
2200             pic14_emitcode("push","%s",l);
2201         }
2202         return ;        
2203     }
2204
2205     /* this is a paramter push: in this case we call
2206     the routine to find the call and save those
2207     registers that need to be saved */   
2208     saveRegisters(ic);
2209
2210     /* then do the push */
2211     aopOp(IC_LEFT(ic),ic,FALSE);
2212
2213
2214         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2215     size = AOP_SIZE(IC_LEFT(ic));
2216
2217     while (size--) {
2218         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2219         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2220             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2221             strcmp(l,"a") ) {
2222             pic14_emitcode("mov","a,%s",l);
2223             pic14_emitcode("push","acc");
2224         } else
2225             pic14_emitcode("push","%s",l);
2226     }       
2227
2228     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2229 #endif
2230 }
2231
2232 /*-----------------------------------------------------------------*/
2233 /* genIpop - recover the registers: can happen only for spilling   */
2234 /*-----------------------------------------------------------------*/
2235 static void genIpop (iCode *ic)
2236 {
2237   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2238 #if 0
2239     int size,offset ;
2240
2241
2242     /* if the temp was not pushed then */
2243     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2244         return ;
2245
2246     aopOp(IC_LEFT(ic),ic,FALSE);
2247     size = AOP_SIZE(IC_LEFT(ic));
2248     offset = (size-1);
2249     while (size--) 
2250         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2251                                    FALSE,TRUE));
2252
2253     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2254 #endif
2255 }
2256
2257 /*-----------------------------------------------------------------*/
2258 /* unsaverbank - restores the resgister bank from stack            */
2259 /*-----------------------------------------------------------------*/
2260 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2261 {
2262   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2263 #if 0
2264     int i;
2265     asmop *aop ;
2266     regs *r = NULL;
2267
2268     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2269     if (popPsw) {
2270         if (options.useXstack) {
2271             aop = newAsmop(0);
2272             r = getFreePtr(ic,&aop,FALSE);
2273             
2274             
2275             pic14_emitcode("mov","%s,_spx",r->name);
2276             pic14_emitcode("movx","a,@%s",r->name);
2277             pic14_emitcode("mov","psw,a");
2278             pic14_emitcode("dec","%s",r->name);
2279             
2280         }else
2281             pic14_emitcode ("pop","psw");
2282     }
2283
2284     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2285         if (options.useXstack) {       
2286             pic14_emitcode("movx","a,@%s",r->name);
2287             //pic14_emitcode("mov","(%s+%d),a",
2288             //       regspic14[i].base,8*bank+regspic14[i].offset);
2289             pic14_emitcode("dec","%s",r->name);
2290
2291         } else 
2292           pic14_emitcode("pop",""); //"(%s+%d)",
2293         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2294     }
2295
2296     if (options.useXstack) {
2297
2298         pic14_emitcode("mov","_spx,%s",r->name);
2299         freeAsmop(NULL,aop,ic,TRUE);
2300
2301     }
2302 #endif 
2303 }
2304
2305 /*-----------------------------------------------------------------*/
2306 /* saverbank - saves an entire register bank on the stack          */
2307 /*-----------------------------------------------------------------*/
2308 static void saverbank (int bank, iCode *ic, bool pushPsw)
2309 {
2310   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2311 #if 0
2312     int i;
2313     asmop *aop ;
2314     regs *r = NULL;
2315
2316     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2317     if (options.useXstack) {
2318
2319         aop = newAsmop(0);
2320         r = getFreePtr(ic,&aop,FALSE);  
2321         pic14_emitcode("mov","%s,_spx",r->name);
2322
2323     }
2324
2325     for (i = 0 ; i < pic14_nRegs ;i++) {
2326         if (options.useXstack) {
2327             pic14_emitcode("inc","%s",r->name);
2328             //pic14_emitcode("mov","a,(%s+%d)",
2329             //         regspic14[i].base,8*bank+regspic14[i].offset);
2330             pic14_emitcode("movx","@%s,a",r->name);           
2331         } else 
2332           pic14_emitcode("push","");// "(%s+%d)",
2333                      //regspic14[i].base,8*bank+regspic14[i].offset);
2334     }
2335     
2336     if (pushPsw) {
2337         if (options.useXstack) {
2338             pic14_emitcode("mov","a,psw");
2339             pic14_emitcode("movx","@%s,a",r->name);     
2340             pic14_emitcode("inc","%s",r->name);
2341             pic14_emitcode("mov","_spx,%s",r->name);       
2342             freeAsmop (NULL,aop,ic,TRUE);
2343             
2344         } else
2345             pic14_emitcode("push","psw");
2346         
2347         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2348     }
2349     ic->bankSaved = 1;
2350 #endif
2351 }
2352
2353 /*-----------------------------------------------------------------*/
2354 /* genCall - generates a call statement                            */
2355 /*-----------------------------------------------------------------*/
2356 static void genCall (iCode *ic)
2357 {
2358   sym_link *dtype;   
2359
2360   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2361
2362   /* if caller saves & we have not saved then */
2363   if (!ic->regsSaved)
2364     saveRegisters(ic);
2365
2366   /* if we are calling a function that is not using
2367      the same register bank then we need to save the
2368      destination registers on the stack */
2369   dtype = operandType(IC_LEFT(ic));
2370   if (currFunc && dtype && 
2371       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2372       IFFUNC_ISISR(currFunc->type) &&
2373       !ic->bankSaved) 
2374
2375     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2376
2377   /* if send set is not empty the assign */
2378   if (_G.sendSet) {
2379     iCode *sic;
2380     /* For the Pic port, there is no data stack.
2381      * So parameters passed to functions are stored
2382      * in registers. (The pCode optimizer will get
2383      * rid of most of these :).
2384      */
2385     int psuedoStkPtr=-1; 
2386     int firstTimeThruLoop = 1;
2387
2388     _G.sendSet = reverseSet(_G.sendSet);
2389
2390     /* First figure how many parameters are getting passed */
2391     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2392          sic = setNextItem(_G.sendSet)) {
2393
2394       aopOp(IC_LEFT(sic),sic,FALSE);
2395       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2396       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2397     }
2398
2399     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2400          sic = setNextItem(_G.sendSet)) {
2401       int size, offset = 0;
2402
2403       aopOp(IC_LEFT(sic),sic,FALSE);
2404       size = AOP_SIZE(IC_LEFT(sic));
2405
2406       while (size--) {
2407         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2408                              AopType(AOP_TYPE(IC_LEFT(sic))));
2409
2410         if(!firstTimeThruLoop) {
2411           /* If this is not the first time we've been through the loop
2412            * then we need to save the parameter in a temporary
2413            * register. The last byte of the last parameter is
2414            * passed in W. */
2415           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2416
2417         }
2418         firstTimeThruLoop=0;
2419
2420         //if (strcmp(l,fReturn[offset])) {
2421         mov2w (AOP(IC_LEFT(sic)),  offset);
2422 /*
2423         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2424              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2425           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2426         else
2427           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2428 */
2429         //}
2430         offset++;
2431       }
2432       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2433     }
2434     _G.sendSet = NULL;
2435   }
2436   /* make the call */
2437   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2438                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2439                                       OP_SYMBOL(IC_LEFT(ic))->name));
2440
2441   GpsuedoStkPtr=0;
2442   /* if we need assign a result value */
2443   if ((IS_ITEMP(IC_RESULT(ic)) && 
2444        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2445         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2446       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2447
2448     _G.accInUse++;
2449     aopOp(IC_RESULT(ic),ic,FALSE);
2450     _G.accInUse--;
2451
2452     assignResultValue(IC_RESULT(ic));
2453
2454     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2455                          AopType(AOP_TYPE(IC_RESULT(ic))));
2456                 
2457     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2458   }
2459
2460   /* adjust the stack for parameters if 
2461      required */
2462   if (ic->parmBytes) {
2463     int i;
2464     if (ic->parmBytes > 3) {
2465       pic14_emitcode("mov","a,%s",spname);
2466       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2467       pic14_emitcode("mov","%s,a",spname);
2468     } else 
2469       for ( i = 0 ; i <  ic->parmBytes ;i++)
2470         pic14_emitcode("dec","%s",spname);
2471
2472   }
2473
2474   /* if register bank was saved then pop them */
2475   if (ic->bankSaved)
2476     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2477
2478   /* if we hade saved some registers then unsave them */
2479   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2480     unsaveRegisters (ic);
2481
2482
2483 }
2484
2485 /*-----------------------------------------------------------------*/
2486 /* genPcall - generates a call by pointer statement                */
2487 /*-----------------------------------------------------------------*/
2488 static void genPcall (iCode *ic)
2489 {
2490     sym_link *dtype;
2491     symbol *albl = newiTempLabel(NULL);
2492     symbol *blbl = newiTempLabel(NULL);
2493     PIC_OPCODE poc;
2494     operand *left;
2495
2496     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2497     /* if caller saves & we have not saved then */
2498     if (!ic->regsSaved)
2499         saveRegisters(ic);
2500
2501     /* if we are calling a function that is not using
2502     the same register bank then we need to save the
2503     destination registers on the stack */
2504     dtype = operandType(IC_LEFT(ic));
2505     if (currFunc && dtype && 
2506         IFFUNC_ISISR(currFunc->type) &&
2507         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2508         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2509
2510     left = IC_LEFT(ic);
2511     aopOp(left,ic,FALSE);
2512     DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2513
2514     pushSide(IC_LEFT(ic), FPTRSIZE);
2515
2516     /* if send set is not empty, assign parameters */
2517     if (_G.sendSet) {
2518
2519         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2520         /* no way to pass args - W always gets used to make the call */
2521     }
2522 /* first idea - factor out a common helper function and call it.
2523    But don't know how to get it generated only once in its own block
2524
2525     if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2526             char *rname;
2527             char *buffer;
2528             rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2529             DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2530             buffer = Safe_calloc(1,strlen(rname)+16);
2531             sprintf(buffer, "%s_goto_helper", rname);
2532             addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2533             free(buffer);
2534     }
2535 */
2536     emitpcode(POC_CALL,popGetLabel(albl->key));
2537     emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
2538     emitpcode(POC_GOTO,popGetLabel(blbl->key));
2539     emitpLabel(albl->key);
2540
2541     poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2542     
2543     emitpcode(poc,popGet(AOP(left),1));
2544     emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2545     emitpcode(poc,popGet(AOP(left),0));
2546     emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2547
2548     emitpLabel(blbl->key);
2549
2550     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2551
2552     /* if we need to assign a result value */
2553     if ((IS_ITEMP(IC_RESULT(ic)) &&
2554          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2555           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2556         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2557
2558         _G.accInUse++;
2559         aopOp(IC_RESULT(ic),ic,FALSE);
2560         _G.accInUse--;
2561         
2562         assignResultValue(IC_RESULT(ic));
2563
2564         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2565     }
2566
2567     /* if register bank was saved then unsave them */
2568     if (currFunc && dtype && 
2569         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2570         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2571
2572     /* if we hade saved some registers then
2573     unsave them */
2574     if (ic->regsSaved)
2575         unsaveRegisters (ic);
2576
2577 }
2578
2579 /*-----------------------------------------------------------------*/
2580 /* resultRemat - result  is rematerializable                       */
2581 /*-----------------------------------------------------------------*/
2582 static int resultRemat (iCode *ic)
2583 {
2584   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2585   if (SKIP_IC(ic) || ic->op == IFX)
2586     return 0;
2587
2588   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2589     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2590     if (sym->remat && !POINTER_SET(ic)) 
2591       return 1;
2592   }
2593
2594   return 0;
2595 }
2596
2597 #if defined(__BORLANDC__) || defined(_MSC_VER)
2598 #define STRCASECMP stricmp
2599 #else
2600 #define STRCASECMP strcasecmp
2601 #endif
2602
2603 #if 0
2604 /*-----------------------------------------------------------------*/
2605 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2606 /*-----------------------------------------------------------------*/
2607 static bool inExcludeList(char *s)
2608 {
2609   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2610     int i =0;
2611     
2612     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2613     if (options.excludeRegs[i] &&
2614     STRCASECMP(options.excludeRegs[i],"none") == 0)
2615         return FALSE ;
2616
2617     for ( i = 0 ; options.excludeRegs[i]; i++) {
2618         if (options.excludeRegs[i] &&
2619         STRCASECMP(s,options.excludeRegs[i]) == 0)
2620             return TRUE;
2621     }
2622     return FALSE ;
2623 }
2624 #endif
2625
2626 /*-----------------------------------------------------------------*/
2627 /* genFunction - generated code for function entry                 */
2628 /*-----------------------------------------------------------------*/
2629 static void genFunction (iCode *ic)
2630 {
2631     symbol *sym;
2632     sym_link *ftype;
2633
2634     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2635
2636     labelOffset += (max_key+4);
2637     max_key=0;
2638     GpsuedoStkPtr=0;
2639     _G.nRegsSaved = 0;
2640     /* create the function header */
2641     pic14_emitcode(";","-----------------------------------------");
2642     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2643     pic14_emitcode(";","-----------------------------------------");
2644
2645     pic14_emitcode("","%s:",sym->rname);
2646     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2647
2648     ftype = operandType(IC_LEFT(ic));
2649
2650     /* if critical function then turn interrupts off */
2651     if (IFFUNC_ISCRITICAL(ftype))
2652         pic14_emitcode("clr","ea");
2653
2654     /* here we need to generate the equates for the
2655        register bank if required */
2656 #if 0
2657     if (FUNC_REGBANK(ftype) != rbank) {
2658         int i ;
2659
2660         rbank = FUNC_REGBANK(ftype);
2661         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2662             if (strcmp(regspic14[i].base,"0") == 0)
2663                 pic14_emitcode("","%s = 0x%02x",
2664                          regspic14[i].dname,
2665                          8*rbank+regspic14[i].offset);
2666             else
2667                 pic14_emitcode ("","%s = %s + 0x%02x",
2668                           regspic14[i].dname,
2669                           regspic14[i].base,
2670                           8*rbank+regspic14[i].offset);
2671         }
2672     }
2673 #endif
2674
2675     /* if this is an interrupt service routine */
2676     if (IFFUNC_ISISR(sym->type)) {
2677 /*  already done in pic14createInterruptVect() - delete me
2678       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2679       emitpcodeNULLop(POC_NOP);
2680       emitpcodeNULLop(POC_NOP);
2681       emitpcodeNULLop(POC_NOP);
2682 */
2683       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2684       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2685       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2686       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2687       emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2688       emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2689       emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
2690
2691       pBlockConvert2ISR(pb);
2692 #if 0  
2693         if (!inExcludeList("acc"))          
2694             pic14_emitcode ("push","acc");      
2695         if (!inExcludeList("b"))
2696             pic14_emitcode ("push","b");
2697         if (!inExcludeList("dpl"))
2698             pic14_emitcode ("push","dpl");
2699         if (!inExcludeList("dph"))
2700             pic14_emitcode ("push","dph");
2701         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2702         {
2703             pic14_emitcode ("push", "dpx");
2704             /* Make sure we're using standard DPTR */
2705             pic14_emitcode ("push", "dps");
2706             pic14_emitcode ("mov", "dps, #0x00");
2707             if (options.stack10bit)
2708             {   
2709                 /* This ISR could conceivably use DPTR2. Better save it. */
2710                 pic14_emitcode ("push", "dpl1");
2711                 pic14_emitcode ("push", "dph1");
2712                 pic14_emitcode ("push", "dpx1");
2713             }
2714         }
2715         /* if this isr has no bank i.e. is going to
2716            run with bank 0 , then we need to save more
2717            registers :-) */
2718         if (!FUNC_REGBANK(sym->type)) {
2719
2720             /* if this function does not call any other
2721                function then we can be economical and
2722                save only those registers that are used */
2723             if (! IFFUNC_HASFCALL(sym->type)) {
2724                 int i;
2725
2726                 /* if any registers used */
2727                 if (sym->regsUsed) {
2728                     /* save the registers used */
2729                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2730                         if (bitVectBitValue(sym->regsUsed,i) ||
2731                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2732                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2733                     }
2734                 }
2735                 
2736             } else {
2737                 /* this function has  a function call cannot
2738                    determines register usage so we will have the
2739                    entire bank */
2740                 saverbank(0,ic,FALSE);
2741             }       
2742         }
2743 #endif
2744     } else {
2745         /* if callee-save to be used for this function
2746            then save the registers being used in this function */
2747         if (IFFUNC_CALLEESAVES(sym->type)) {
2748             int i;
2749             
2750             /* if any registers used */
2751             if (sym->regsUsed) {
2752                 /* save the registers used */
2753                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2754                     if (bitVectBitValue(sym->regsUsed,i) ||
2755                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2756                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2757                         _G.nRegsSaved++;
2758                     }
2759                 }
2760             }
2761         }
2762     }
2763
2764     /* set the register bank to the desired value */
2765     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2766         pic14_emitcode("push","psw");
2767         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2768     }
2769
2770     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2771
2772         if (options.useXstack) {
2773             pic14_emitcode("mov","r0,%s",spname);
2774             pic14_emitcode("mov","a,_bp");
2775             pic14_emitcode("movx","@r0,a");
2776             pic14_emitcode("inc","%s",spname);
2777         }
2778         else
2779         {
2780             /* set up the stack */
2781             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2782         }
2783         pic14_emitcode ("mov","_bp,%s",spname);
2784     }
2785
2786     /* adjust the stack for the function */
2787     if (sym->stack) {
2788
2789         int i = sym->stack;
2790         if (i > 256 ) 
2791             werror(W_STACK_OVERFLOW,sym->name);
2792
2793         if (i > 3 && sym->recvSize < 4) {              
2794
2795             pic14_emitcode ("mov","a,sp");
2796             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2797             pic14_emitcode ("mov","sp,a");
2798            
2799         }
2800         else
2801             while(i--)
2802                 pic14_emitcode("inc","sp");
2803     }
2804
2805      if (sym->xstack) {
2806
2807         pic14_emitcode ("mov","a,_spx");
2808         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2809         pic14_emitcode ("mov","_spx,a");
2810     }    
2811
2812 }
2813
2814 /*-----------------------------------------------------------------*/
2815 /* genEndFunction - generates epilogue for functions               */
2816 /*-----------------------------------------------------------------*/
2817 static void genEndFunction (iCode *ic)
2818 {
2819     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2820
2821     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2822
2823     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2824     {
2825         pic14_emitcode ("mov","%s,_bp",spname);
2826     }
2827
2828     /* if use external stack but some variables were
2829     added to the local stack then decrement the
2830     local stack */
2831     if (options.useXstack && sym->stack) {      
2832         pic14_emitcode("mov","a,sp");
2833         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2834         pic14_emitcode("mov","sp,a");
2835     }
2836
2837
2838     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2839         if (options.useXstack) {
2840             pic14_emitcode("mov","r0,%s",spname);
2841             pic14_emitcode("movx","a,@r0");
2842             pic14_emitcode("mov","_bp,a");
2843             pic14_emitcode("dec","%s",spname);
2844         }
2845         else
2846         {
2847             pic14_emitcode ("pop","_bp");
2848         }
2849     }
2850
2851     /* restore the register bank  */    
2852     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2853         pic14_emitcode ("pop","psw");
2854
2855     if (IFFUNC_ISISR(sym->type)) {
2856
2857         /* now we need to restore the registers */
2858         /* if this isr has no bank i.e. is going to
2859            run with bank 0 , then we need to save more
2860            registers :-) */
2861         if (!FUNC_REGBANK(sym->type)) {
2862             
2863             /* if this function does not call any other
2864                function then we can be economical and
2865                save only those registers that are used */
2866             if (! IFFUNC_HASFCALL(sym->type)) {
2867                 int i;
2868                 
2869                 /* if any registers used */
2870                 if (sym->regsUsed) {
2871                     /* save the registers used */
2872                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2873                         if (bitVectBitValue(sym->regsUsed,i) ||
2874                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2875                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2876                     }
2877                 }
2878                 
2879             } else {
2880                 /* this function has  a function call cannot
2881                    determines register usage so we will have the
2882                    entire bank */
2883                 unsaverbank(0,ic,FALSE);
2884             }       
2885         }
2886 #if 0
2887         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2888         {
2889             if (options.stack10bit)
2890             {
2891                 pic14_emitcode ("pop", "dpx1");
2892                 pic14_emitcode ("pop", "dph1");
2893                 pic14_emitcode ("pop", "dpl1");
2894             }   
2895             pic14_emitcode ("pop", "dps");
2896             pic14_emitcode ("pop", "dpx");
2897         }
2898         if (!inExcludeList("dph"))
2899             pic14_emitcode ("pop","dph");
2900         if (!inExcludeList("dpl"))
2901             pic14_emitcode ("pop","dpl");
2902         if (!inExcludeList("b"))
2903             pic14_emitcode ("pop","b");
2904         if (!inExcludeList("acc"))
2905             pic14_emitcode ("pop","acc");
2906
2907         if (IFFUNC_ISCRITICAL(sym->type))
2908             pic14_emitcode("setb","ea");
2909 #endif
2910
2911         /* if debug then send end of function */
2912 /*      if (options.debug && currFunc) { */
2913         if (currFunc) {
2914             _G.debugLine = 1;
2915             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2916                      FileBaseName(ic->filename),currFunc->lastLine,
2917                      ic->level,ic->block); 
2918             if (IS_STATIC(currFunc->etype))         
2919                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2920             else
2921                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2922             _G.debugLine = 0;
2923         }
2924
2925         pic14_emitcode ("reti","");
2926         emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2927         emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2928         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2929         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2930         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2931         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2932         emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2933         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2934         emitpcodeNULLop(POC_RETFIE);
2935     }
2936     else {
2937         if (IFFUNC_ISCRITICAL(sym->type))
2938             pic14_emitcode("setb","ea");
2939         
2940         if (IFFUNC_CALLEESAVES(sym->type)) {
2941             int i;
2942             
2943             /* if any registers used */
2944             if (sym->regsUsed) {
2945                 /* save the registers used */
2946                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2947                     if (bitVectBitValue(sym->regsUsed,i) ||
2948                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2949                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2950                 }
2951             }
2952             
2953         }
2954
2955         /* if debug then send end of function */
2956         if (currFunc) {
2957             _G.debugLine = 1;
2958             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2959                      FileBaseName(ic->filename),currFunc->lastLine,
2960                      ic->level,ic->block); 
2961             if (IS_STATIC(currFunc->etype))         
2962                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2963             else
2964                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2965             _G.debugLine = 0;
2966         }
2967
2968         pic14_emitcode ("return","");
2969         emitpcodeNULLop(POC_RETURN);
2970
2971         /* Mark the end of a function */
2972         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2973     }
2974
2975 }
2976
2977 /*-----------------------------------------------------------------*/
2978 /* genRet - generate code for return statement                     */
2979 /*-----------------------------------------------------------------*/
2980 static void genRet (iCode *ic)
2981 {
2982   int size,offset = 0 , pushed = 0;
2983     
2984   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2985   /* if we have no return value then
2986      just generate the "ret" */
2987   if (!IC_LEFT(ic)) 
2988     goto jumpret;       
2989     
2990   /* we have something to return then
2991      move the return value into place */
2992   aopOp(IC_LEFT(ic),ic,FALSE);
2993   size = AOP_SIZE(IC_LEFT(ic));
2994     
2995   while (size--) {
2996     char *l ;
2997     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2998       /* #NOCHANGE */
2999       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3000                  FALSE,TRUE);
3001       pic14_emitcode("push","%s",l);
3002       pushed++;
3003     } else {
3004       l = aopGet(AOP(IC_LEFT(ic)),offset,
3005                  FALSE,FALSE);
3006       if (strcmp(fReturn[offset],l)) {
3007       if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
3008            AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3009           ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3010           ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3011           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3012         }else {
3013           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3014         }
3015         if(size) {
3016           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3017         }
3018         offset++;
3019       }
3020     }
3021   }    
3022
3023   if (pushed) {
3024     while(pushed) {
3025       pushed--;
3026       if (strcmp(fReturn[pushed],"a"))
3027         pic14_emitcode("pop",fReturn[pushed]);
3028       else
3029         pic14_emitcode("pop","acc");
3030     }
3031   }
3032   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3033     
3034  jumpret:
3035   /* generate a jump to the return label
3036      if the next is not the return statement */
3037   if (!(ic->next && ic->next->op == LABEL &&
3038         IC_LABEL(ic->next) == returnLabel)) {
3039         
3040     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3041     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3042   }
3043     
3044 }
3045
3046 /*-----------------------------------------------------------------*/
3047 /* genLabel - generates a label                                    */
3048 /*-----------------------------------------------------------------*/
3049 static void genLabel (iCode *ic)
3050 {
3051     /* special case never generate */
3052     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3053     if (IC_LABEL(ic) == entryLabel)
3054         return ;
3055
3056     emitpLabel(IC_LABEL(ic)->key);
3057     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3058 }
3059
3060 /*-----------------------------------------------------------------*/
3061 /* genGoto - generates a goto                                      */
3062 /*-----------------------------------------------------------------*/
3063 //tsd
3064 static void genGoto (iCode *ic)
3065 {
3066   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3067   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3068 }
3069
3070
3071 /*-----------------------------------------------------------------*/
3072 /* genMultbits :- multiplication of bits                           */
3073 /*-----------------------------------------------------------------*/
3074 static void genMultbits (operand *left, 
3075                          operand *right, 
3076                          operand *result)
3077 {
3078   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3079
3080   if(!pic14_sameRegs(AOP(result),AOP(right)))
3081     emitpcode(POC_BSF,  popGet(AOP(result),0));
3082
3083   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3084   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3085   emitpcode(POC_BCF,  popGet(AOP(result),0));
3086
3087 }
3088
3089
3090 /*-----------------------------------------------------------------*/
3091 /* genMultOneByte : 8 bit multiplication & division                */
3092 /*-----------------------------------------------------------------*/
3093 static void genMultOneByte (operand *left,
3094                             operand *right,
3095                             operand *result)
3096 {
3097   sym_link *opetype = operandType(result);
3098
3099   // symbol *lbl ;
3100   int size,offset;
3101
3102   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3103   DEBUGpic14_AopType(__LINE__,left,right,result);
3104   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3105
3106   /* (if two literals, the value is computed before) */
3107   /* if one literal, literal on the right */
3108   if (AOP_TYPE(left) == AOP_LIT){
3109     operand *t = right;
3110     right = left;
3111     left = t;
3112   }
3113
3114   size = AOP_SIZE(result);
3115   if(size == 1) {
3116
3117     if (AOP_TYPE(right) == AOP_LIT){
3118       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3119                      aopGet(AOP(right),0,FALSE,FALSE), 
3120                      aopGet(AOP(left),0,FALSE,FALSE), 
3121                      aopGet(AOP(result),0,FALSE,FALSE));
3122       pic14_emitcode("call","genMultLit");
3123     } else {
3124       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3125                      aopGet(AOP(right),0,FALSE,FALSE), 
3126                      aopGet(AOP(left),0,FALSE,FALSE), 
3127                      aopGet(AOP(result),0,FALSE,FALSE));
3128       pic14_emitcode("call","genMult8X8_8");
3129
3130     }
3131     genMult8X8_8 (left, right,result);
3132
3133
3134     /* signed or unsigned */
3135     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3136     //l = aopGet(AOP(left),0,FALSE,FALSE);
3137     //MOVA(l);       
3138     //pic14_emitcode("mul","ab");
3139     /* if result size = 1, mul signed = mul unsigned */
3140     //aopPut(AOP(result),"a",0);
3141
3142   } else {  // (size > 1)
3143
3144     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3145                    aopGet(AOP(right),0,FALSE,FALSE), 
3146                    aopGet(AOP(left),0,FALSE,FALSE), 
3147                    aopGet(AOP(result),0,FALSE,FALSE));
3148
3149     if (SPEC_USIGN(opetype)){
3150       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3151       genUMult8X8_16 (left, right, result, NULL);
3152
3153       if (size > 2) {
3154         /* for filling the MSBs */
3155         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3156         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3157       }
3158     }
3159     else{
3160       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3161
3162       pic14_emitcode("mov","a,b");
3163
3164       /* adjust the MSB if left or right neg */
3165
3166       /* if one literal */
3167       if (AOP_TYPE(right) == AOP_LIT){
3168         pic14_emitcode("multiply ","right is a lit");
3169         /* AND literal negative */
3170         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3171           /* adjust MSB (c==0 after mul) */
3172           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3173         }
3174       }
3175       else{
3176         genSMult8X8_16 (left, right, result, NULL);
3177       }
3178
3179       if(size > 2){
3180         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3181         /* get the sign */
3182         pic14_emitcode("rlc","a");
3183         pic14_emitcode("subb","a,acc");
3184       }
3185     }
3186
3187     size -= 2;   
3188     offset = 2;
3189     if (size > 0)
3190       while (size--)
3191         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3192     //aopPut(AOP(result),"a",offset++);
3193   }
3194 }
3195
3196 /*-----------------------------------------------------------------*/
3197 /* genMult - generates code for multiplication                     */
3198 /*-----------------------------------------------------------------*/
3199 static void genMult (iCode *ic)
3200 {
3201     operand *left = IC_LEFT(ic);
3202     operand *right = IC_RIGHT(ic);
3203     operand *result= IC_RESULT(ic);   
3204
3205     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3206     /* assign the amsops */
3207     aopOp (left,ic,FALSE);
3208     aopOp (right,ic,FALSE);
3209     aopOp (result,ic,TRUE);
3210
3211   DEBUGpic14_AopType(__LINE__,left,right,result);
3212
3213     /* special cases first */
3214     /* both are bits */
3215     if (AOP_TYPE(left) == AOP_CRY &&
3216         AOP_TYPE(right)== AOP_CRY) {
3217         genMultbits(left,right,result);
3218         goto release ;
3219     }
3220
3221     /* if both are of size == 1 */
3222     if (AOP_SIZE(left) == 1 &&
3223         AOP_SIZE(right) == 1 ) {
3224         genMultOneByte(left,right,result);
3225         goto release ;
3226     }
3227
3228     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3229
3230     /* should have been converted to function call */
3231     //assert(0) ;
3232
3233 release :
3234     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3235     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3236     freeAsmop(result,NULL,ic,TRUE); 
3237 }
3238
3239 /*-----------------------------------------------------------------*/
3240 /* genDivbits :- division of bits                                  */
3241 /*-----------------------------------------------------------------*/
3242 static void genDivbits (operand *left, 
3243                         operand *right, 
3244                         operand *result)
3245 {
3246
3247     char *l;
3248
3249     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3250     /* the result must be bit */    
3251     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3252     l = aopGet(AOP(left),0,FALSE,FALSE);
3253
3254     MOVA(l);    
3255
3256     pic14_emitcode("div","ab");
3257     pic14_emitcode("rrc","a");
3258     aopPut(AOP(result),"c",0);
3259 }
3260
3261 /*-----------------------------------------------------------------*/
3262 /* genDivOneByte : 8 bit division                                  */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivOneByte (operand *left,
3265                            operand *right,
3266                            operand *result)
3267 {
3268     sym_link *opetype = operandType(result);
3269     char *l ;
3270     symbol *lbl ;
3271     int size,offset;
3272
3273     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3274     size = AOP_SIZE(result) - 1;
3275     offset = 1;
3276     /* signed or unsigned */
3277     if (SPEC_USIGN(opetype)) {
3278         /* unsigned is easy */
3279         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3280         l = aopGet(AOP(left),0,FALSE,FALSE);
3281         MOVA(l);        
3282         pic14_emitcode("div","ab");
3283         aopPut(AOP(result),"a",0);
3284         while (size--)
3285             aopPut(AOP(result),zero,offset++);
3286         return ;
3287     }
3288
3289     /* signed is a little bit more difficult */
3290
3291     /* save the signs of the operands */
3292     l = aopGet(AOP(left),0,FALSE,FALSE);    
3293     MOVA(l);    
3294     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3295     pic14_emitcode("push","acc"); /* save it on the stack */
3296
3297     /* now sign adjust for both left & right */
3298     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3299     MOVA(l);       
3300     lbl = newiTempLabel(NULL);
3301     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3302     pic14_emitcode("cpl","a");   
3303     pic14_emitcode("inc","a");
3304     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3305     pic14_emitcode("mov","b,a");
3306
3307     /* sign adjust left side */
3308     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3309     MOVA(l);
3310
3311     lbl = newiTempLabel(NULL);
3312     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3313     pic14_emitcode("cpl","a");
3314     pic14_emitcode("inc","a");
3315     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3316
3317     /* now the division */
3318     pic14_emitcode("div","ab");
3319     /* we are interested in the lower order
3320     only */
3321     pic14_emitcode("mov","b,a");
3322     lbl = newiTempLabel(NULL);
3323     pic14_emitcode("pop","acc");   
3324     /* if there was an over flow we don't 
3325     adjust the sign of the result */
3326     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3327     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3328     CLRC;
3329     pic14_emitcode("clr","a");
3330     pic14_emitcode("subb","a,b");
3331     pic14_emitcode("mov","b,a");
3332     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3333
3334     /* now we are done */
3335     aopPut(AOP(result),"b",0);
3336     if(size > 0){
3337         pic14_emitcode("mov","c,b.7");
3338         pic14_emitcode("subb","a,acc");   
3339     }
3340     while (size--)
3341         aopPut(AOP(result),"a",offset++);
3342
3343 }
3344
3345 /*-----------------------------------------------------------------*/
3346 /* genDiv - generates code for division                            */
3347 /*-----------------------------------------------------------------*/
3348 static void genDiv (iCode *ic)
3349 {
3350     operand *left = IC_LEFT(ic);
3351     operand *right = IC_RIGHT(ic);
3352     operand *result= IC_RESULT(ic);   
3353
3354     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3355     /* assign the amsops */
3356     aopOp (left,ic,FALSE);
3357     aopOp (right,ic,FALSE);
3358     aopOp (result,ic,TRUE);
3359
3360     /* special cases first */
3361     /* both are bits */
3362     if (AOP_TYPE(left) == AOP_CRY &&
3363         AOP_TYPE(right)== AOP_CRY) {
3364         genDivbits(left,right,result);
3365         goto release ;
3366     }
3367
3368     /* if both are of size == 1 */
3369     if (AOP_SIZE(left) == 1 &&
3370         AOP_SIZE(right) == 1 ) {
3371         genDivOneByte(left,right,result);
3372         goto release ;
3373     }
3374
3375     /* should have been converted to function call */
3376     assert(0);
3377 release :
3378     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3379     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3380     freeAsmop(result,NULL,ic,TRUE); 
3381 }
3382
3383 /*-----------------------------------------------------------------*/
3384 /* genModbits :- modulus of bits                                   */
3385 /*-----------------------------------------------------------------*/
3386 static void genModbits (operand *left, 
3387                         operand *right, 
3388                         operand *result)
3389 {
3390
3391     char *l;
3392
3393     /* the result must be bit */    
3394     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3395     l = aopGet(AOP(left),0,FALSE,FALSE);
3396
3397     MOVA(l);       
3398
3399     pic14_emitcode("div","ab");
3400     pic14_emitcode("mov","a,b");
3401     pic14_emitcode("rrc","a");
3402     aopPut(AOP(result),"c",0);
3403 }
3404
3405 /*-----------------------------------------------------------------*/
3406 /* genModOneByte : 8 bit modulus                                   */
3407 /*-----------------------------------------------------------------*/
3408 static void genModOneByte (operand *left,
3409                            operand *right,
3410                            operand *result)
3411 {
3412     sym_link *opetype = operandType(result);
3413     char *l ;
3414     symbol *lbl ;
3415
3416     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3417     /* signed or unsigned */
3418     if (SPEC_USIGN(opetype)) {
3419         /* unsigned is easy */
3420         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3421         l = aopGet(AOP(left),0,FALSE,FALSE);
3422         MOVA(l);    
3423         pic14_emitcode("div","ab");
3424         aopPut(AOP(result),"b",0);
3425         return ;
3426     }
3427
3428     /* signed is a little bit more difficult */
3429
3430     /* save the signs of the operands */
3431     l = aopGet(AOP(left),0,FALSE,FALSE);    
3432     MOVA(l);
3433
3434     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3435     pic14_emitcode("push","acc"); /* save it on the stack */
3436
3437     /* now sign adjust for both left & right */
3438     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3439     MOVA(l);
3440
3441     lbl = newiTempLabel(NULL);
3442     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3443     pic14_emitcode("cpl","a");   
3444     pic14_emitcode("inc","a");
3445     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3446     pic14_emitcode("mov","b,a"); 
3447
3448     /* sign adjust left side */
3449     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3450     MOVA(l);
3451
3452     lbl = newiTempLabel(NULL);
3453     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3454     pic14_emitcode("cpl","a");   
3455     pic14_emitcode("inc","a");
3456     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3457
3458     /* now the multiplication */
3459     pic14_emitcode("div","ab");
3460     /* we are interested in the lower order
3461     only */
3462     lbl = newiTempLabel(NULL);
3463     pic14_emitcode("pop","acc");   
3464     /* if there was an over flow we don't 
3465     adjust the sign of the result */
3466     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3467     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3468     CLRC ;
3469     pic14_emitcode("clr","a");
3470     pic14_emitcode("subb","a,b");
3471     pic14_emitcode("mov","b,a");
3472     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3473
3474     /* now we are done */
3475     aopPut(AOP(result),"b",0);
3476
3477 }
3478
3479 /*-----------------------------------------------------------------*/
3480 /* genMod - generates code for division                            */
3481 /*-----------------------------------------------------------------*/
3482 static void genMod (iCode *ic)
3483 {
3484     operand *left = IC_LEFT(ic);
3485     operand *right = IC_RIGHT(ic);
3486     operand *result= IC_RESULT(ic);  
3487
3488     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3489     /* assign the amsops */
3490     aopOp (left,ic,FALSE);
3491     aopOp (right,ic,FALSE);
3492     aopOp (result,ic,TRUE);
3493
3494     /* special cases first */
3495     /* both are bits */
3496     if (AOP_TYPE(left) == AOP_CRY &&
3497         AOP_TYPE(right)== AOP_CRY) {
3498         genModbits(left,right,result);
3499         goto release ;
3500     }
3501
3502     /* if both are of size == 1 */
3503     if (AOP_SIZE(left) == 1 &&
3504         AOP_SIZE(right) == 1 ) {
3505         genModOneByte(left,right,result);
3506         goto release ;
3507     }
3508
3509     /* should have been converted to function call */
3510     assert(0);
3511
3512 release :
3513     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3514     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3515     freeAsmop(result,NULL,ic,TRUE); 
3516 }
3517
3518 /*-----------------------------------------------------------------*/
3519 /* genIfxJump :- will create a jump depending on the ifx           */
3520 /*-----------------------------------------------------------------*/
3521 /*
3522   note: May need to add parameter to indicate when a variable is in bit space.
3523 */
3524 static void genIfxJump (iCode *ic, char *jval)
3525 {
3526
3527     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3528     /* if true label then we jump if condition
3529     supplied is true */
3530     if ( IC_TRUE(ic) ) {
3531
3532         if(strcmp(jval,"a") == 0)
3533           emitSKPZ;
3534         else if (strcmp(jval,"c") == 0)
3535           emitSKPC;
3536         else {
3537           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3538           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3539         }
3540
3541         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3542         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3543
3544     }
3545     else {
3546         /* false label is present */
3547         if(strcmp(jval,"a") == 0)
3548           emitSKPNZ;
3549         else if (strcmp(jval,"c") == 0)
3550           emitSKPNC;
3551         else {
3552           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3553           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3554         }
3555
3556         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3557         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3558
3559     }
3560
3561
3562     /* mark the icode as generated */
3563     ic->generated = 1;
3564 }
3565
3566 /*-----------------------------------------------------------------*/
3567 /* genSkip                                                         */
3568 /*-----------------------------------------------------------------*/
3569 static void genSkip(iCode *ifx,int status_bit)
3570 {
3571   if(!ifx)
3572     return;
3573
3574   if ( IC_TRUE(ifx) ) {
3575     switch(status_bit) {
3576     case 'z':
3577       emitSKPNZ;
3578       break;
3579
3580     case 'c':
3581       emitSKPNC;
3582       break;
3583
3584     case 'd':
3585       emitSKPDC;
3586       break;
3587
3588     }
3589
3590     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3591     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3592
3593   } else {
3594
3595     switch(status_bit) {
3596
3597     case 'z':
3598       emitSKPZ;
3599       break;
3600
3601     case 'c':
3602       emitSKPC;
3603       break;
3604
3605     case 'd':
3606       emitSKPDC;
3607       break;
3608     }
3609     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3610     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3611
3612   }
3613
3614 }
3615
3616 /*-----------------------------------------------------------------*/
3617 /* genSkipc                                                        */
3618 /*-----------------------------------------------------------------*/
3619 static void genSkipc(resolvedIfx *rifx)
3620 {
3621   if(!rifx)
3622     return;
3623
3624   if(rifx->condition)
3625     emitSKPC;
3626   else
3627     emitSKPNC;
3628
3629   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3630   rifx->generated = 1;
3631 }
3632
3633 /*-----------------------------------------------------------------*/
3634 /* genSkipz2                                                       */
3635 /*-----------------------------------------------------------------*/
3636 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3637 {
3638   if(!rifx)
3639     return;
3640
3641   if( (rifx->condition ^ invert_condition) & 1)
3642     emitSKPZ;
3643   else
3644     emitSKPNZ;
3645
3646   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3647   rifx->generated = 1;
3648 }
3649
3650 /*-----------------------------------------------------------------*/
3651 /* genSkipz                                                        */
3652 /*-----------------------------------------------------------------*/
3653 static void genSkipz(iCode *ifx, int condition)
3654 {
3655   if(!ifx)
3656     return;
3657
3658   if(condition)
3659     emitSKPNZ;
3660   else
3661     emitSKPZ;
3662
3663   if ( IC_TRUE(ifx) )
3664     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3665   else
3666     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3667
3668   if ( IC_TRUE(ifx) )
3669     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3670   else
3671     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3672
3673 }
3674 /*-----------------------------------------------------------------*/
3675 /* genSkipCond                                                     */
3676 /*-----------------------------------------------------------------*/
3677 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3678 {
3679   if(!rifx)
3680     return;
3681
3682   if(rifx->condition)
3683     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3684   else
3685     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3686
3687
3688   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3689   rifx->generated = 1;
3690 }
3691
3692 #if 0
3693 /*-----------------------------------------------------------------*/
3694 /* genChkZeroes :- greater or less than comparison                 */
3695 /*     For each byte in a literal that is zero, inclusive or the   */
3696 /*     the corresponding byte in the operand with W                */
3697 /*     returns true if any of the bytes are zero                   */
3698 /*-----------------------------------------------------------------*/
3699 static int genChkZeroes(operand *op, int lit,  int size)
3700 {
3701
3702   int i;
3703   int flag =1;
3704
3705   while(size--) {
3706     i = (lit >> (size*8)) & 0xff;
3707
3708     if(i==0) {
3709       if(flag) 
3710         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3711       else
3712         emitpcode(POC_IORFW, popGet(AOP(op),size));
3713       flag = 0;
3714     }
3715   }
3716
3717   return (flag==0);
3718 }
3719 #endif
3720
3721 /*-----------------------------------------------------------------*/
3722 /* genCmp :- greater or less than comparison                       */
3723 /*-----------------------------------------------------------------*/
3724 static void genCmp (operand *left,operand *right,
3725                     operand *result, iCode *ifx, int sign)
3726 {
3727   int size; //, offset = 0 ;
3728   unsigned long lit = 0L,i = 0;
3729   resolvedIfx rFalseIfx;
3730   //  resolvedIfx rTrueIfx;
3731   symbol *truelbl;
3732   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3733 /*
3734   if(ifx) {
3735     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3736     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3737   }
3738 */
3739
3740   resolveIfx(&rFalseIfx,ifx);
3741   truelbl  = newiTempLabel(NULL);
3742   size = max(AOP_SIZE(left),AOP_SIZE(right));
3743
3744   DEBUGpic14_AopType(__LINE__,left,right,result);
3745
3746 #define _swapp
3747
3748   /* if literal is on the right then swap with left */
3749   if ((AOP_TYPE(right) == AOP_LIT)) {
3750     operand *tmp = right ;
3751     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3752     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3753 #ifdef _swapp
3754
3755     lit = (lit - 1) & mask;
3756     right = left;
3757     left = tmp;
3758     rFalseIfx.condition ^= 1;
3759 #endif
3760
3761   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3762     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3763   }
3764
3765
3766   //if(IC_TRUE(ifx) == NULL)
3767   /* if left & right are bit variables */
3768   if (AOP_TYPE(left) == AOP_CRY &&
3769       AOP_TYPE(right) == AOP_CRY ) {
3770     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3771     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3772   } else {
3773     /* subtract right from left if at the
3774        end the carry flag is set then we know that
3775        left is greater than right */
3776
3777     //    {
3778
3779     symbol *lbl  = newiTempLabel(NULL);
3780
3781 #ifndef _swapp
3782     if(AOP_TYPE(right) == AOP_LIT) {
3783
3784       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3785
3786       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3787
3788       /* special cases */
3789
3790       if(lit == 0) {
3791
3792         if(sign != 0) 
3793           genSkipCond(&rFalseIfx,left,size-1,7);
3794         else 
3795           /* no need to compare to 0...*/
3796           /* NOTE: this is a de-generate compare that most certainly 
3797            *       creates some dead code. */
3798           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3799
3800         if(ifx) ifx->generated = 1;
3801         return;
3802
3803       }
3804       size--;
3805
3806       if(size == 0) {
3807         //i = (lit >> (size*8)) & 0xff;
3808         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3809         
3810         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3811
3812         i = ((0-lit) & 0xff);
3813         if(sign) {
3814           if( i == 0x81) { 
3815             /* lit is 0x7f, all signed chars are less than
3816              * this except for 0x7f itself */
3817             emitpcode(POC_XORLW, popGetLit(0x7f));
3818             genSkipz2(&rFalseIfx,0);
3819           } else {
3820             emitpcode(POC_ADDLW, popGetLit(0x80));
3821             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3822             genSkipc(&rFalseIfx);
3823           }
3824
3825         } else {
3826           if(lit == 1) {
3827             genSkipz2(&rFalseIfx,1);
3828           } else {
3829             emitpcode(POC_ADDLW, popGetLit(i));
3830             genSkipc(&rFalseIfx);
3831           }
3832         }
3833
3834         if(ifx) ifx->generated = 1;
3835         return;
3836       }
3837
3838       /* chars are out of the way. now do ints and longs */
3839
3840
3841       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3842         
3843       /* special cases */
3844
3845       if(sign) {
3846
3847         if(lit == 0) {
3848           genSkipCond(&rFalseIfx,left,size,7);
3849           if(ifx) ifx->generated = 1;
3850           return;
3851         }
3852
3853         if(lit <0x100) {
3854           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3855
3856           //rFalseIfx.condition ^= 1;
3857           //genSkipCond(&rFalseIfx,left,size,7);
3858           //rFalseIfx.condition ^= 1;
3859
3860           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3861           if(rFalseIfx.condition)
3862             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3863           else
3864             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3865
3866           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3867           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3868           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3869
3870           while(size > 1)
3871             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3872
3873           if(rFalseIfx.condition) {
3874             emitSKPZ;
3875             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3876
3877           } else {
3878             emitSKPNZ;
3879           }
3880
3881           genSkipc(&rFalseIfx);
3882           emitpLabel(truelbl->key);
3883           if(ifx) ifx->generated = 1;
3884           return;
3885
3886         }
3887
3888         if(size == 1) {
3889
3890           if( (lit & 0xff) == 0) {
3891             /* lower byte is zero */
3892             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3893             i = ((lit >> 8) & 0xff) ^0x80;
3894             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3895             emitpcode(POC_ADDLW, popGetLit( 0x80));
3896             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3897             genSkipc(&rFalseIfx);
3898
3899
3900             if(ifx) ifx->generated = 1;
3901             return;
3902
3903           }
3904         } else {
3905           /* Special cases for signed longs */
3906           if( (lit & 0xffffff) == 0) {
3907             /* lower byte is zero */
3908             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3909             i = ((lit >> 8*3) & 0xff) ^0x80;
3910             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3911             emitpcode(POC_ADDLW, popGetLit( 0x80));
3912             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3913             genSkipc(&rFalseIfx);
3914
3915
3916             if(ifx) ifx->generated = 1;
3917             return;
3918
3919           }
3920
3921         }
3922
3923
3924         if(lit & (0x80 << (size*8))) {
3925           /* lit is negative */
3926           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3927
3928           //genSkipCond(&rFalseIfx,left,size,7);
3929
3930           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3931
3932           if(rFalseIfx.condition)
3933             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3934           else
3935             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3936
3937
3938         } else {
3939           /* lit is positive */
3940           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3941           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3942           if(rFalseIfx.condition)
3943             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3944           else
3945             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3946
3947         }
3948
3949         /*
3950           This works, but is only good for ints.
3951           It also requires a "known zero" register.
3952           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3953           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3954           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3955           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3956           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3957           genSkipc(&rFalseIfx);
3958
3959           emitpLabel(truelbl->key);
3960           if(ifx) ifx->generated = 1;
3961           return;
3962         **/
3963           
3964         /* There are no more special cases, so perform a general compare */
3965   
3966         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3967         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3968
3969         while(size--) {
3970
3971           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3972           emitSKPNZ;
3973           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3974         }
3975         //rFalseIfx.condition ^= 1;
3976         genSkipc(&rFalseIfx);
3977
3978         emitpLabel(truelbl->key);
3979
3980         if(ifx) ifx->generated = 1;
3981         return;
3982
3983
3984       }
3985
3986
3987       /* sign is out of the way. So now do an unsigned compare */
3988       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3989
3990
3991       /* General case - compare to an unsigned literal on the right.*/
3992
3993       i = (lit >> (size*8)) & 0xff;
3994       emitpcode(POC_MOVLW, popGetLit(i));
3995       emitpcode(POC_SUBFW, popGet(AOP(left),size));
3996       while(size--) {
3997         i = (lit >> (size*8)) & 0xff;
3998
3999         if(i) {
4000           emitpcode(POC_MOVLW, popGetLit(i));
4001           emitSKPNZ;
4002           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4003         } else {
4004           /* this byte of the lit is zero, 
4005            *if it's not the last then OR in the variable */
4006           if(size)
4007             emitpcode(POC_IORFW, popGet(AOP(left),size));
4008         }
4009       }
4010
4011
4012       emitpLabel(lbl->key);
4013       //if(emitFinalCheck)
4014       genSkipc(&rFalseIfx);
4015       if(sign)
4016         emitpLabel(truelbl->key);
4017
4018       if(ifx) ifx->generated = 1;
4019       return;
4020
4021
4022     }
4023 #endif  // _swapp
4024
4025     if(AOP_TYPE(left) == AOP_LIT) {
4026       //symbol *lbl = newiTempLabel(NULL);
4027
4028       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4029
4030
4031       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4032
4033       /* Special cases */
4034       if((lit == 0) && (sign == 0)){
4035
4036         size--;
4037         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4038         while(size) 
4039           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4040
4041         genSkipz2(&rFalseIfx,0);
4042         if(ifx) ifx->generated = 1;
4043         return;
4044       }
4045
4046       if(size==1) {
4047         /* Special cases */
4048         lit &= 0xff;
4049         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4050           /* degenerate compare can never be true */
4051           if(rFalseIfx.condition == 0)
4052             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4053
4054           if(ifx) ifx->generated = 1;
4055           return;
4056         }
4057
4058         if(sign) {
4059           /* signed comparisons to a literal byte */
4060
4061           int lp1 = (lit+1) & 0xff;
4062
4063           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4064           switch (lp1) {
4065           case 0:
4066             rFalseIfx.condition ^= 1;
4067             genSkipCond(&rFalseIfx,right,0,7);
4068             break;
4069           case 0x7f:
4070             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4071             emitpcode(POC_XORLW, popGetLit(0x7f));
4072             genSkipz2(&rFalseIfx,1);
4073             break;
4074           default:
4075             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4076             emitpcode(POC_ADDLW, popGetLit(0x80));
4077             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4078             rFalseIfx.condition ^= 1;
4079             genSkipc(&rFalseIfx);
4080             break;
4081           }
4082           if(ifx) ifx->generated = 1;
4083         } else {
4084           /* unsigned comparisons to a literal byte */
4085
4086           switch(lit & 0xff ) {
4087           case 0:
4088             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4089             genSkipz2(&rFalseIfx,0);
4090             if(ifx) ifx->generated = 1;
4091             break;
4092           case 0x7f:
4093             rFalseIfx.condition ^= 1;
4094             genSkipCond(&rFalseIfx,right,0,7);
4095             if(ifx) ifx->generated = 1;
4096             break;
4097
4098           default:
4099             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4100             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4101             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4102             rFalseIfx.condition ^= 1;
4103             if (AOP_TYPE(result) == AOP_CRY) {
4104               genSkipc(&rFalseIfx);
4105               if(ifx) ifx->generated = 1;
4106             } else {
4107               DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4108               emitpcode(POC_CLRF, popGet(AOP(result),0));
4109               emitpcode(POC_RLF, popGet(AOP(result),0));
4110               emitpcode(POC_MOVLW, popGetLit(0x01));
4111               emitpcode(POC_XORWF, popGet(AOP(result),0));
4112             }         
4113             break;
4114           }
4115         }
4116
4117         //goto check_carry;
4118         return;
4119
4120       } else {
4121
4122         /* Size is greater than 1 */
4123
4124         if(sign) {
4125           int lp1 = lit+1;
4126
4127           size--;
4128
4129           if(lp1 == 0) {
4130             /* this means lit = 0xffffffff, or -1 */
4131
4132
4133             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4134             rFalseIfx.condition ^= 1;
4135             genSkipCond(&rFalseIfx,right,size,7);
4136             if(ifx) ifx->generated = 1;
4137             return;
4138           }
4139
4140           if(lit == 0) {
4141             int s = size;
4142
4143             if(rFalseIfx.condition) {
4144               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4145               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4146             }
4147
4148             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4149             while(size--)
4150               emitpcode(POC_IORFW, popGet(AOP(right),size));
4151
4152
4153             emitSKPZ;
4154             if(rFalseIfx.condition) {
4155               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4156               emitpLabel(truelbl->key);
4157             }else {
4158               rFalseIfx.condition ^= 1;
4159               genSkipCond(&rFalseIfx,right,s,7);
4160             }
4161
4162             if(ifx) ifx->generated = 1;
4163             return;
4164           }
4165
4166           if((size == 1) &&  (0 == (lp1&0xff))) {
4167             /* lower byte of signed word is zero */
4168             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4169             i = ((lp1 >> 8) & 0xff) ^0x80;
4170             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4171             emitpcode(POC_ADDLW, popGetLit( 0x80));
4172             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4173             rFalseIfx.condition ^= 1;
4174             genSkipc(&rFalseIfx);
4175
4176
4177             if(ifx) ifx->generated = 1;
4178             return;
4179           }
4180
4181           if(lit & (0x80 << (size*8))) {
4182             /* Lit is less than zero */
4183             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4184             //rFalseIfx.condition ^= 1;
4185             //genSkipCond(&rFalseIfx,left,size,7);
4186             //rFalseIfx.condition ^= 1;
4187             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4188             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4189
4190             if(rFalseIfx.condition)
4191               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4192             else
4193               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4194
4195
4196           } else {
4197             /* Lit is greater than or equal to zero */
4198             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4199             //rFalseIfx.condition ^= 1;
4200             //genSkipCond(&rFalseIfx,right,size,7);
4201             //rFalseIfx.condition ^= 1;
4202
4203             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4205
4206             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4207             if(rFalseIfx.condition)
4208               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4209             else
4210               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4211
4212           }
4213
4214
4215           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4216           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4217
4218           while(size--) {
4219
4220             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4221             emitSKPNZ;
4222             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4223           }
4224           rFalseIfx.condition ^= 1;
4225           //rFalseIfx.condition = 1;
4226           genSkipc(&rFalseIfx);
4227
4228           emitpLabel(truelbl->key);
4229
4230           if(ifx) ifx->generated = 1;
4231           return;
4232           // end of if (sign)
4233         } else {
4234
4235           /* compare word or long to an unsigned literal on the right.*/
4236
4237
4238           size--;
4239           if(lit < 0xff) {
4240             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4241             switch (lit) {
4242             case 0:
4243               break; /* handled above */
4244 /*
4245             case 0xff:
4246               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4247               while(size--)
4248                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4249               genSkipz2(&rFalseIfx,0);
4250               break;
4251 */
4252             default:
4253               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4254               while(--size)
4255                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256
4257               emitSKPZ;
4258               if(rFalseIfx.condition)
4259                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4260               else
4261                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4262
4263
4264               emitpcode(POC_MOVLW, popGetLit(lit+1));
4265               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4266
4267               rFalseIfx.condition ^= 1;
4268               genSkipc(&rFalseIfx);
4269             }
4270
4271             emitpLabel(truelbl->key);
4272
4273             if(ifx) ifx->generated = 1;
4274             return;
4275           }
4276
4277
4278           lit++;
4279           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4280           i = (lit >> (size*8)) & 0xff;
4281
4282           emitpcode(POC_MOVLW, popGetLit(i));
4283           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4284
4285           while(size--) {
4286             i = (lit >> (size*8)) & 0xff;
4287
4288             if(i) {
4289               emitpcode(POC_MOVLW, popGetLit(i));
4290               emitSKPNZ;
4291               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4292             } else {
4293               /* this byte of the lit is zero, 
4294                *if it's not the last then OR in the variable */
4295               if(size)
4296                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4297             }
4298           }
4299
4300
4301           emitpLabel(lbl->key);
4302
4303           rFalseIfx.condition ^= 1;
4304           genSkipc(&rFalseIfx);
4305         }
4306
4307         if(sign)
4308           emitpLabel(truelbl->key);
4309         if(ifx) ifx->generated = 1;
4310         return;
4311       }
4312     }
4313     /* Compare two variables */
4314
4315     DEBUGpic14_emitcode(";sign","%d",sign);
4316
4317     size--;
4318     if(sign) {
4319       /* Sigh. thus sucks... */
4320       if(size) {
4321         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4322         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4323         emitpcode(POC_MOVLW, popGetLit(0x80));
4324         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4325         emitpcode(POC_XORFW, popGet(AOP(right),size));
4326         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4327       } else {
4328         /* Signed char comparison */
4329         /* Special thanks to Nikolai Golovchenko for this snippet */
4330         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4331         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4332         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4333         emitpcode(POC_XORFW, popGet(AOP(left),0));
4334         emitpcode(POC_XORFW, popGet(AOP(right),0));
4335         emitpcode(POC_ADDLW, popGetLit(0x80));
4336
4337         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4338         genSkipc(&rFalseIfx);
4339           
4340         if(ifx) ifx->generated = 1;
4341         return;
4342       }
4343
4344     } else {
4345
4346       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4347       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4348     }
4349
4350
4351     /* The rest of the bytes of a multi-byte compare */
4352     while (size) {
4353
4354       emitSKPZ;
4355       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4356       size--;
4357
4358       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4359       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4360
4361
4362     }
4363
4364     emitpLabel(lbl->key);
4365
4366     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4367     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4368         (AOP_TYPE(result) == AOP_REG)) {
4369       emitpcode(POC_CLRF, popGet(AOP(result),0));
4370       emitpcode(POC_RLF, popGet(AOP(result),0));
4371     } else {
4372       genSkipc(&rFalseIfx);
4373     }         
4374     //genSkipc(&rFalseIfx);
4375     if(ifx) ifx->generated = 1;
4376
4377     return;
4378
4379   }
4380
4381   // check_carry:
4382   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4383     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4384     pic14_outBitC(result);
4385   } else {
4386     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4387     /* if the result is used in the next
4388        ifx conditional branch then generate
4389        code a little differently */
4390     if (ifx )
4391       genIfxJump (ifx,"c");
4392     else
4393       pic14_outBitC(result);
4394     /* leave the result in acc */
4395   }
4396
4397 }
4398
4399 /*-----------------------------------------------------------------*/
4400 /* genCmpGt :- greater than comparison                             */
4401 /*-----------------------------------------------------------------*/
4402 static void genCmpGt (iCode *ic, iCode *ifx)
4403 {
4404     operand *left, *right, *result;
4405     sym_link *letype , *retype;
4406     int sign ;
4407
4408     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4409     left = IC_LEFT(ic);
4410     right= IC_RIGHT(ic);
4411     result = IC_RESULT(ic);
4412
4413     letype = getSpec(operandType(left));
4414     retype =getSpec(operandType(right));
4415     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4416     /* assign the amsops */
4417     aopOp (left,ic,FALSE);
4418     aopOp (right,ic,FALSE);
4419     aopOp (result,ic,TRUE);
4420
4421     genCmp(right, left, result, ifx, sign);
4422
4423     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4424     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4425     freeAsmop(result,NULL,ic,TRUE); 
4426 }
4427
4428 /*-----------------------------------------------------------------*/
4429 /* genCmpLt - less than comparisons                                */
4430 /*-----------------------------------------------------------------*/
4431 static void genCmpLt (iCode *ic, iCode *ifx)
4432 {
4433     operand *left, *right, *result;
4434     sym_link *letype , *retype;
4435     int sign ;
4436
4437     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4438     left = IC_LEFT(ic);
4439     right= IC_RIGHT(ic);
4440     result = IC_RESULT(ic);
4441
4442     letype = getSpec(operandType(left));
4443     retype =getSpec(operandType(right));
4444     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4445
4446     /* assign the amsops */
4447     aopOp (left,ic,FALSE);
4448     aopOp (right,ic,FALSE);
4449     aopOp (result,ic,TRUE);
4450
4451     genCmp(left, right, result, ifx, sign);
4452
4453     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4454     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4455     freeAsmop(result,NULL,ic,TRUE); 
4456 }
4457
4458 /*-----------------------------------------------------------------*/
4459 /* genc16bit2lit - compare a 16 bit value to a literal             */
4460 /*-----------------------------------------------------------------*/
4461 static void genc16bit2lit(operand *op, int lit, int offset)
4462 {
4463   int i;
4464
4465   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4466   if( (lit&0xff) == 0) 
4467     i=1;
4468   else
4469     i=0;
4470
4471   switch( BYTEofLONG(lit,i)) { 
4472   case 0:
4473     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4474     break;
4475   case 1:
4476     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4477     break;
4478   case 0xff:
4479     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4480     break;
4481   default:
4482     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4483     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4484   }
4485
4486   i ^= 1;
4487
4488   switch( BYTEofLONG(lit,i)) { 
4489   case 0:
4490     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4491     break;
4492   case 1:
4493     emitSKPNZ;
4494     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4495     break;
4496   case 0xff:
4497     emitSKPNZ;
4498     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4499     break;
4500   default:
4501     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4502     emitSKPNZ;
4503     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4504
4505   }
4506
4507 }
4508
4509 /*-----------------------------------------------------------------*/
4510 /* gencjneshort - compare and jump if not equal                    */
4511 /*-----------------------------------------------------------------*/
4512 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4513 {
4514   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4515   int offset = 0;
4516   int res_offset = 0;  /* the result may be a different size then left or right */
4517   int res_size = AOP_SIZE(result);
4518   resolvedIfx rIfx;
4519   symbol *lbl;
4520
4521   unsigned long lit = 0L;
4522   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4523   DEBUGpic14_AopType(__LINE__,left,right,result);
4524   if(result)
4525     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4526   resolveIfx(&rIfx,ifx);
4527   lbl =  newiTempLabel(NULL);
4528
4529
4530   /* if the left side is a literal or 
4531      if the right is in a pointer register and left 
4532      is not */
4533   if ((AOP_TYPE(left) == AOP_LIT) || 
4534       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4535     operand *t = right;
4536     right = left;
4537     left = t;
4538   }
4539   if(AOP_TYPE(right) == AOP_LIT)
4540     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4541
4542   /* if the right side is a literal then anything goes */
4543   if (AOP_TYPE(right) == AOP_LIT &&
4544       AOP_TYPE(left) != AOP_DIR ) {
4545     switch(size) {
4546     case 2:
4547       genc16bit2lit(left, lit, 0);
4548       emitSKPNZ;
4549       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4550       break;
4551     default:
4552       while (size--) {
4553         if(lit & 0xff) {
4554           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4555           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4556         } else {
4557           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4558         }
4559
4560         emitSKPNZ;
4561         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4562         offset++;
4563         if(res_offset < res_size-1)
4564           res_offset++;
4565         lit >>= 8;
4566       }
4567       break;
4568     }
4569   }
4570
4571   /* if the right side is in a register or in direct space or
4572      if the left is a pointer register & right is not */    
4573   else if (AOP_TYPE(right) == AOP_REG ||
4574            AOP_TYPE(right) == AOP_DIR || 
4575            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4576            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4577     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4578     int lbl_key = lbl->key;
4579
4580     if(result) {
4581       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4582       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4583     }else {
4584       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4585       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4586               __FUNCTION__,__LINE__);
4587       return;
4588     }
4589
4590 /*     switch(size) { */
4591 /*     case 2: */
4592 /*       genc16bit2lit(left, lit, 0); */
4593 /*       emitSKPNZ; */
4594 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4595 /*       break; */
4596 /*     default: */
4597     while (size--) {
4598       int emit_skip=1;
4599       if((AOP_TYPE(left) == AOP_DIR) && 
4600          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4601
4602         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4603         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4604
4605       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4606             
4607         switch (lit & 0xff) {
4608         case 0:
4609           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610           break;
4611         case 1:
4612           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4613           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4614           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4615           emit_skip=0;
4616           break;
4617         case 0xff:
4618           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4619           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4620           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4621           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4622           emit_skip=0;
4623           break;
4624         default:
4625           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4626           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4627         }
4628         lit >>= 8;
4629
4630       } else {
4631         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4632       }
4633       if(emit_skip) {
4634         if(AOP_TYPE(result) == AOP_CRY) {
4635           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4636           if(rIfx.condition)
4637             emitSKPNZ;
4638           else
4639             emitSKPZ;
4640           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4641         } else {
4642           /* fix me. probably need to check result size too */
4643           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4644           if(rIfx.condition)
4645             emitSKPZ;
4646           else
4647             emitSKPNZ;
4648           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4649           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4650         }
4651         if(ifx)
4652           ifx->generated=1;
4653       }
4654       emit_skip++;
4655       offset++;
4656       if(res_offset < res_size-1)
4657         res_offset++;
4658     }
4659 /*       break; */
4660 /*     } */
4661   } else if(AOP_TYPE(right) == AOP_REG &&
4662             AOP_TYPE(left) != AOP_DIR){
4663
4664     while(size--) {
4665       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4666       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4667       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4668       if(rIfx.condition)
4669         emitSKPNZ;
4670       else
4671         emitSKPZ;
4672       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4673       offset++;
4674       if(res_offset < res_size-1)
4675         res_offset++;
4676     }
4677       
4678   }else{
4679     /* right is a pointer reg need both a & b */
4680     while(size--) {
4681       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4682       if(strcmp(l,"b"))
4683         pic14_emitcode("mov","b,%s",l);
4684       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4685       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4686       offset++;
4687     }
4688   }
4689
4690   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4691   if(!rIfx.condition)
4692     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4693
4694   emitpLabel(lbl->key);
4695
4696   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4697
4698   if(ifx)
4699     ifx->generated = 1;
4700 }
4701
4702 #if 0
4703 /*-----------------------------------------------------------------*/
4704 /* gencjne - compare and jump if not equal                         */
4705 /*-----------------------------------------------------------------*/
4706 static void gencjne(operand *left, operand *right, iCode *ifx)
4707 {
4708     symbol *tlbl  = newiTempLabel(NULL);
4709
4710     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4711     gencjneshort(left, right, lbl);
4712
4713     pic14_emitcode("mov","a,%s",one);
4714     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4715     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4716     pic14_emitcode("clr","a");
4717     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4718
4719     emitpLabel(lbl->key);
4720     emitpLabel(tlbl->key);
4721
4722 }
4723 #endif
4724
4725 /*-----------------------------------------------------------------*/
4726 /* genCmpEq - generates code for equal to                          */
4727 /*-----------------------------------------------------------------*/
4728 static void genCmpEq (iCode *ic, iCode *ifx)
4729 {
4730     operand *left, *right, *result;
4731     unsigned long lit = 0L;
4732     int size,offset=0;
4733
4734     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4735
4736     if(ifx)
4737       DEBUGpic14_emitcode ("; ifx is non-null","");
4738     else
4739       DEBUGpic14_emitcode ("; ifx is null","");
4740
4741     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4742     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4743     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4744
4745     size = max(AOP_SIZE(left),AOP_SIZE(right));
4746
4747     DEBUGpic14_AopType(__LINE__,left,right,result);
4748
4749     /* if literal, literal on the right or 
4750     if the right is in a pointer register and left 
4751     is not */
4752     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4753         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4754       operand *tmp = right ;
4755       right = left;
4756       left = tmp;
4757     }
4758
4759
4760     if(ifx && !AOP_SIZE(result)){
4761         symbol *tlbl;
4762         /* if they are both bit variables */
4763         if (AOP_TYPE(left) == AOP_CRY &&
4764             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4765             if(AOP_TYPE(right) == AOP_LIT){
4766                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4767                 if(lit == 0L){
4768                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4769                     pic14_emitcode("cpl","c");
4770                 } else if(lit == 1L) {
4771                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4772                 } else {
4773                     pic14_emitcode("clr","c");
4774                 }
4775                 /* AOP_TYPE(right) == AOP_CRY */
4776             } else {
4777                 symbol *lbl = newiTempLabel(NULL);
4778                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4780                 pic14_emitcode("cpl","c");
4781                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4782             }
4783             /* if true label then we jump if condition
4784             supplied is true */
4785             tlbl = newiTempLabel(NULL);
4786             if ( IC_TRUE(ifx) ) {
4787                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4788                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4789             } else {
4790                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4791                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4792             }
4793             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4794
4795             {
4796               /* left and right are both bit variables, result is carry */
4797               resolvedIfx rIfx;
4798               
4799               resolveIfx(&rIfx,ifx);
4800
4801               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4802               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4803               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4804               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4805               genSkipz2(&rIfx,0);
4806             }
4807         } else {
4808
4809           /* They're not both bit variables. Is the right a literal? */
4810           if(AOP_TYPE(right) == AOP_LIT) {
4811             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4812             
4813             switch(size) {
4814
4815             case 1:
4816               switch(lit & 0xff) {
4817               case 1:
4818                 if ( IC_TRUE(ifx) ) {
4819                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4820                   emitSKPNZ;
4821                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4822                 } else {
4823                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4824                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4825                 }
4826                 break;
4827               case 0xff:
4828                 if ( IC_TRUE(ifx) ) {
4829                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4830                   emitSKPNZ;
4831                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4832                 } else {
4833                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4834                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4835                 }
4836                 break;
4837               default:
4838                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4839                 if(lit)
4840                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4841                 genSkip(ifx,'z');
4842               }
4843
4844
4845               /* end of size == 1 */
4846               break;
4847               
4848             case 2:
4849               genc16bit2lit(left,lit,offset);
4850               genSkip(ifx,'z');
4851               break;
4852               /* end of size == 2 */
4853
4854             default:
4855               /* size is 4 */
4856               if(lit==0) {
4857                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4858                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4859                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4860                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4861
4862               } else {
4863
4864                 /* search for patterns that can be optimized */
4865
4866                 genc16bit2lit(left,lit,0);
4867                 lit >>= 16;
4868                 if(lit) {
4869                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4870                   //genSkip(ifx,'z');
4871                   genc16bit2lit(left,lit,2);
4872                 } else {
4873                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4874                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4875
4876                 }
4877                 
4878               }
4879
4880               genSkip(ifx,'z');
4881             }
4882           
4883             ifx->generated = 1;
4884             goto release ;
4885             
4886
4887           } else if(AOP_TYPE(right) == AOP_CRY ) {
4888             /* we know the left is not a bit, but that the right is */
4889             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4890             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4891                       popGet(AOP(right),offset));
4892             emitpcode(POC_XORLW,popGetLit(1));
4893
4894             /* if the two are equal, then W will be 0 and the Z bit is set
4895              * we could test Z now, or go ahead and check the high order bytes if
4896              * the variable we're comparing is larger than a byte. */
4897
4898             while(--size)
4899               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4900
4901             if ( IC_TRUE(ifx) ) {
4902               emitSKPNZ;
4903               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4904               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4905             } else {
4906               emitSKPZ;
4907               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4908               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4909             }
4910
4911           } else {
4912             /* They're both variables that are larger than bits */
4913             int s = size;
4914
4915             tlbl = newiTempLabel(NULL);
4916
4917             while(size--) {
4918               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4919               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4920
4921               if ( IC_TRUE(ifx) ) {
4922                 if(size) {
4923                   emitSKPZ;
4924                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4925                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4926                 } else {
4927                   emitSKPNZ;
4928                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4929                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4930                 }
4931               } else {
4932                 emitSKPZ;
4933                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4934                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4935               }
4936               offset++;
4937             }
4938             if(s>1 && IC_TRUE(ifx)) {
4939               emitpLabel(tlbl->key);
4940               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4941             }
4942           }
4943         }
4944         /* mark the icode as generated */
4945         ifx->generated = 1;
4946         goto release ;
4947     }
4948
4949     /* if they are both bit variables */
4950     if (AOP_TYPE(left) == AOP_CRY &&
4951         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4952         if(AOP_TYPE(right) == AOP_LIT){
4953             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4954             if(lit == 0L){
4955                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4956                 pic14_emitcode("cpl","c");
4957             } else if(lit == 1L) {
4958                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4959             } else {
4960                 pic14_emitcode("clr","c");
4961             }
4962             /* AOP_TYPE(right) == AOP_CRY */
4963         } else {
4964             symbol *lbl = newiTempLabel(NULL);
4965             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4967             pic14_emitcode("cpl","c");
4968             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4969         }
4970         /* c = 1 if egal */
4971         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4972             pic14_outBitC(result);
4973             goto release ;
4974         }
4975         if (ifx) {
4976             genIfxJump (ifx,"c");
4977             goto release ;
4978         }
4979         /* if the result is used in an arithmetic operation
4980         then put the result in place */
4981         pic14_outBitC(result);
4982     } else {
4983       
4984       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4985       gencjne(left,right,result,ifx);
4986 /*
4987       if(ifx) 
4988         gencjne(left,right,newiTempLabel(NULL));
4989       else {
4990         if(IC_TRUE(ifx)->key)
4991           gencjne(left,right,IC_TRUE(ifx)->key);
4992         else
4993           gencjne(left,right,IC_FALSE(ifx)->key);
4994         ifx->generated = 1;
4995         goto release ;
4996       }
4997       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4998         aopPut(AOP(result),"a",0);
4999         goto release ;
5000       }
5001
5002       if (ifx) {
5003         genIfxJump (ifx,"a");
5004         goto release ;
5005       }
5006 */
5007       /* if the result is used in an arithmetic operation
5008          then put the result in place */
5009 /*
5010       if (AOP_TYPE(result) != AOP_CRY) 
5011         pic14_outAcc(result);
5012 */
5013       /* leave the result in acc */
5014     }
5015
5016 release:
5017     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5018     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5019     freeAsmop(result,NULL,ic,TRUE);
5020 }
5021
5022 /*-----------------------------------------------------------------*/
5023 /* ifxForOp - returns the icode containing the ifx for operand     */
5024 /*-----------------------------------------------------------------*/
5025 static iCode *ifxForOp ( operand *op, iCode *ic )
5026 {
5027     /* if true symbol then needs to be assigned */
5028     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5029     if (IS_TRUE_SYMOP(op))
5030         return NULL ;
5031
5032     /* if this has register type condition and
5033     the next instruction is ifx with the same operand
5034     and live to of the operand is upto the ifx only then */
5035     if (ic->next &&
5036         ic->next->op == IFX &&
5037         IC_COND(ic->next)->key == op->key &&
5038         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5039         return ic->next;
5040
5041     if (ic->next &&
5042         ic->next->op == IFX &&
5043         IC_COND(ic->next)->key == op->key) {
5044       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5045       return ic->next;
5046     }
5047
5048     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5049     if (ic->next &&
5050         ic->next->op == IFX)
5051       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5052
5053     if (ic->next &&
5054         ic->next->op == IFX &&
5055         IC_COND(ic->next)->key == op->key) {
5056       DEBUGpic14_emitcode ("; "," key is okay");
5057       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5058                            OP_SYMBOL(op)->liveTo,
5059                            ic->next->seq);
5060     }
5061
5062
5063     return NULL;
5064 }
5065 /*-----------------------------------------------------------------*/
5066 /* genAndOp - for && operation                                     */
5067 /*-----------------------------------------------------------------*/
5068 static void genAndOp (iCode *ic)
5069 {
5070     operand *left,*right, *result;
5071 /*     symbol *tlbl; */
5072
5073     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5074     /* note here that && operations that are in an
5075     if statement are taken away by backPatchLabels
5076     only those used in arthmetic operations remain */
5077     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5078     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5079     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5080
5081     DEBUGpic14_AopType(__LINE__,left,right,result);
5082
5083     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5084     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5085     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5086
5087     /* if both are bit variables */
5088 /*     if (AOP_TYPE(left) == AOP_CRY && */
5089 /*         AOP_TYPE(right) == AOP_CRY ) { */
5090 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5091 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5092 /*         pic14_outBitC(result); */
5093 /*     } else { */
5094 /*         tlbl = newiTempLabel(NULL); */
5095 /*         pic14_toBoolean(left);     */
5096 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5097 /*         pic14_toBoolean(right); */
5098 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5099 /*         pic14_outBitAcc(result); */
5100 /*     } */
5101
5102     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5103     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5104     freeAsmop(result,NULL,ic,TRUE);
5105 }
5106
5107
5108 /*-----------------------------------------------------------------*/
5109 /* genOrOp - for || operation                                      */
5110 /*-----------------------------------------------------------------*/
5111 /*
5112   tsd pic port -
5113   modified this code, but it doesn't appear to ever get called
5114 */
5115
5116 static void genOrOp (iCode *ic)
5117 {
5118     operand *left,*right, *result;
5119     symbol *tlbl;
5120
5121     /* note here that || operations that are in an
5122     if statement are taken away by backPatchLabels
5123     only those used in arthmetic operations remain */
5124     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5125     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5126     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5127     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5128
5129     DEBUGpic14_AopType(__LINE__,left,right,result);
5130
5131     /* if both are bit variables */
5132     if (AOP_TYPE(left) == AOP_CRY &&
5133         AOP_TYPE(right) == AOP_CRY ) {
5134       pic14_emitcode("clrc","");
5135       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5136                AOP(left)->aopu.aop_dir,
5137                AOP(left)->aopu.aop_dir);
5138       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5139                AOP(right)->aopu.aop_dir,
5140                AOP(right)->aopu.aop_dir);
5141       pic14_emitcode("setc","");
5142
5143     } else {
5144         tlbl = newiTempLabel(NULL);
5145         pic14_toBoolean(left);
5146         emitSKPZ;
5147         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5148         pic14_toBoolean(right);
5149         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5150
5151         pic14_outBitAcc(result);
5152     }
5153
5154     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5155     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5156     freeAsmop(result,NULL,ic,TRUE);            
5157 }
5158
5159 /*-----------------------------------------------------------------*/
5160 /* isLiteralBit - test if lit == 2^n                               */
5161 /*-----------------------------------------------------------------*/
5162 static int isLiteralBit(unsigned long lit)
5163 {
5164     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5165     0x100L,0x200L,0x400L,0x800L,
5166     0x1000L,0x2000L,0x4000L,0x8000L,
5167     0x10000L,0x20000L,0x40000L,0x80000L,
5168     0x100000L,0x200000L,0x400000L,0x800000L,
5169     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5170     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5171     int idx;
5172     
5173     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5174     for(idx = 0; idx < 32; idx++)
5175         if(lit == pw[idx])
5176             return idx+1;
5177     return 0;
5178 }
5179
5180 /*-----------------------------------------------------------------*/
5181 /* continueIfTrue -                                                */
5182 /*-----------------------------------------------------------------*/
5183 static void continueIfTrue (iCode *ic)
5184 {
5185     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5186     if(IC_TRUE(ic))
5187         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5188     ic->generated = 1;
5189 }
5190
5191 /*-----------------------------------------------------------------*/
5192 /* jmpIfTrue -                                                     */
5193 /*-----------------------------------------------------------------*/
5194 static void jumpIfTrue (iCode *ic)
5195 {
5196     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5197     if(!IC_TRUE(ic))
5198         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5199     ic->generated = 1;
5200 }
5201
5202 /*-----------------------------------------------------------------*/
5203 /* jmpTrueOrFalse -                                                */
5204 /*-----------------------------------------------------------------*/
5205 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5206 {
5207     // ugly but optimized by peephole
5208     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5209     if(IC_TRUE(ic)){
5210         symbol *nlbl = newiTempLabel(NULL);
5211         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5212         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5213         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5214         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5215     }
5216     else{
5217         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5218         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5219     }
5220     ic->generated = 1;
5221 }
5222
5223 /*-----------------------------------------------------------------*/
5224 /* genAnd  - code for and                                          */
5225 /*-----------------------------------------------------------------*/
5226 static void genAnd (iCode *ic, iCode *ifx)
5227 {
5228   operand *left, *right, *result;
5229   int size, offset=0;  
5230   unsigned long lit = 0L;
5231   int bytelit = 0;
5232   resolvedIfx rIfx;
5233
5234
5235   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5236   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5237   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5238   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5239
5240   resolveIfx(&rIfx,ifx);
5241
5242   /* if left is a literal & right is not then exchange them */
5243   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5244       AOP_NEEDSACC(left)) {
5245     operand *tmp = right ;
5246     right = left;
5247     left = tmp;
5248   }
5249
5250   /* if result = right then exchange them */
5251   if(pic14_sameRegs(AOP(result),AOP(right))){
5252     operand *tmp = right ;
5253     right = left;
5254     left = tmp;
5255   }
5256
5257   /* if right is bit then exchange them */
5258   if (AOP_TYPE(right) == AOP_CRY &&
5259       AOP_TYPE(left) != AOP_CRY){
5260     operand *tmp = right ;
5261     right = left;
5262     left = tmp;
5263   }
5264   if(AOP_TYPE(right) == AOP_LIT)
5265     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5266
5267   size = AOP_SIZE(result);
5268
5269   DEBUGpic14_AopType(__LINE__,left,right,result);
5270
5271   // if(bit & yy)
5272   // result = bit & yy;
5273   if (AOP_TYPE(left) == AOP_CRY){
5274     // c = bit & literal;
5275     if(AOP_TYPE(right) == AOP_LIT){
5276       if(lit & 1) {
5277         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5278           // no change
5279           goto release;
5280         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5281       } else {
5282         // bit(result) = 0;
5283         if(size && (AOP_TYPE(result) == AOP_CRY)){
5284           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5285           goto release;
5286         }
5287         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5288           jumpIfTrue(ifx);
5289           goto release;
5290         }
5291         pic14_emitcode("clr","c");
5292       }
5293     } else {
5294       if (AOP_TYPE(right) == AOP_CRY){
5295         // c = bit & bit;
5296         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5297         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5298       } else {
5299         // c = bit & val;
5300         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5301         // c = lsb
5302         pic14_emitcode("rrc","a");
5303         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5304       }
5305     }
5306     // bit = c
5307     // val = c
5308     if(size)
5309       pic14_outBitC(result);
5310     // if(bit & ...)
5311     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5312       genIfxJump(ifx, "c");           
5313     goto release ;
5314   }
5315
5316   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5317   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5318   if((AOP_TYPE(right) == AOP_LIT) &&
5319      (AOP_TYPE(result) == AOP_CRY) &&
5320      (AOP_TYPE(left) != AOP_CRY)){
5321     int posbit = isLiteralBit(lit);
5322     /* left &  2^n */
5323     if(posbit){
5324       posbit--;
5325       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5326       // bit = left & 2^n
5327       if(size)
5328         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5329       // if(left &  2^n)
5330       else{
5331         if(ifx){
5332 /*
5333           if(IC_TRUE(ifx)) {
5334             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5335             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5336           } else {
5337             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5338             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5339           }
5340 */
5341           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5342                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5343           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5344           
5345           ifx->generated = 1;
5346         }
5347         goto release;
5348       }
5349     } else {
5350       symbol *tlbl = newiTempLabel(NULL);
5351       int sizel = AOP_SIZE(left);
5352       if(size)
5353         pic14_emitcode("setb","c");
5354       while(sizel--){
5355         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5356           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5357           // byte ==  2^n ?
5358           if((posbit = isLiteralBit(bytelit)) != 0)
5359             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5360           else{
5361             if(bytelit != 0x0FFL)
5362               pic14_emitcode("anl","a,%s",
5363                              aopGet(AOP(right),offset,FALSE,TRUE));
5364             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5365           }
5366         }
5367         offset++;
5368       }
5369       // bit = left & literal
5370       if(size){
5371         pic14_emitcode("clr","c");
5372         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5373       }
5374       // if(left & literal)
5375       else{
5376         if(ifx)
5377           jmpTrueOrFalse(ifx, tlbl);
5378         goto release ;
5379       }
5380     }
5381     pic14_outBitC(result);
5382     goto release ;
5383   }
5384
5385   /* if left is same as result */
5386   if(pic14_sameRegs(AOP(result),AOP(left))){
5387     int know_W = -1;
5388     for(;size--; offset++,lit>>=8) {
5389       if(AOP_TYPE(right) == AOP_LIT){
5390         switch(lit & 0xff) {
5391         case 0x00:
5392           /*  and'ing with 0 has clears the result */
5393           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5394           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5395           break;
5396         case 0xff:
5397           /* and'ing with 0xff is a nop when the result and left are the same */
5398           break;
5399
5400         default:
5401           {
5402             int p = my_powof2( (~lit) & 0xff );
5403             if(p>=0) {
5404               /* only one bit is set in the literal, so use a bcf instruction */
5405               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5406               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5407
5408             } else {
5409               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5410               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5411               if(know_W != (int)(lit&0xff))
5412                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5413               know_W = lit &0xff;
5414               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5415             }
5416           }    
5417         }
5418       } else {
5419         if (AOP_TYPE(left) == AOP_ACC) {
5420           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5421         } else {                    
5422           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5423           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5424
5425         }
5426       }
5427     }
5428
5429   } else {
5430     // left & result in different registers
5431     if(AOP_TYPE(result) == AOP_CRY){
5432       // result = bit
5433       // if(size), result in bit
5434       // if(!size && ifx), conditional oper: if(left & right)
5435       symbol *tlbl = newiTempLabel(NULL);
5436       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5437       if(size)
5438         pic14_emitcode("setb","c");
5439       while(sizer--){
5440         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5441         pic14_emitcode("anl","a,%s",
5442                        aopGet(AOP(left),offset,FALSE,FALSE));
5443         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5444         offset++;
5445       }
5446       if(size){
5447         CLRC;
5448         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5449         pic14_outBitC(result);
5450       } else if(ifx)
5451         jmpTrueOrFalse(ifx, tlbl);
5452     } else {
5453       for(;(size--);offset++) {
5454         // normal case
5455         // result = left & right
5456         if(AOP_TYPE(right) == AOP_LIT){
5457           int t = (lit >> (offset*8)) & 0x0FFL;
5458           switch(t) { 
5459           case 0x00:
5460             pic14_emitcode("clrf","%s",
5461                            aopGet(AOP(result),offset,FALSE,FALSE));
5462             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5463             break;
5464           case 0xff:
5465             if(AOP_TYPE(left) != AOP_ACC) {
5466               pic14_emitcode("movf","%s,w",
5467                              aopGet(AOP(left),offset,FALSE,FALSE));
5468               pic14_emitcode("movwf","%s",
5469                              aopGet(AOP(result),offset,FALSE,FALSE));
5470               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5471             }
5472             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5473             break;
5474           default:
5475             if(AOP_TYPE(left) == AOP_ACC) {
5476               emitpcode(POC_ANDLW, popGetLit(t));
5477             } else {
5478               pic14_emitcode("movlw","0x%x",t);
5479               pic14_emitcode("andwf","%s,w",
5480                              aopGet(AOP(left),offset,FALSE,FALSE));
5481               pic14_emitcode("movwf","%s",
5482                              aopGet(AOP(result),offset,FALSE,FALSE));
5483               
5484               emitpcode(POC_MOVLW, popGetLit(t));
5485               emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5486             }
5487             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5488           }
5489           continue;
5490         }
5491
5492         if (AOP_TYPE(left) == AOP_ACC) {
5493           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5494           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5495         } else {
5496           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5497           pic14_emitcode("andwf","%s,w",
5498                          aopGet(AOP(left),offset,FALSE,FALSE));
5499           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5500           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5501         }
5502         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5503         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5504       }
5505     }
5506   }
5507
5508   release :
5509     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5510   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511   freeAsmop(result,NULL,ic,TRUE);     
5512 }
5513
5514 /*-----------------------------------------------------------------*/
5515 /* genOr  - code for or                                            */
5516 /*-----------------------------------------------------------------*/
5517 static void genOr (iCode *ic, iCode *ifx)
5518 {
5519     operand *left, *right, *result;
5520     int size, offset=0;
5521     unsigned long lit = 0L;
5522
5523     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5524
5525     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5526     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5527     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5528
5529     DEBUGpic14_AopType(__LINE__,left,right,result);
5530
5531     /* if left is a literal & right is not then exchange them */
5532     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5533         AOP_NEEDSACC(left)) {
5534         operand *tmp = right ;
5535         right = left;
5536         left = tmp;
5537     }
5538
5539     /* if result = right then exchange them */
5540     if(pic14_sameRegs(AOP(result),AOP(right))){
5541         operand *tmp = right ;
5542         right = left;
5543         left = tmp;
5544     }
5545
5546     /* if right is bit then exchange them */
5547     if (AOP_TYPE(right) == AOP_CRY &&
5548         AOP_TYPE(left) != AOP_CRY){
5549         operand *tmp = right ;
5550         right = left;
5551         left = tmp;
5552     }
5553
5554     DEBUGpic14_AopType(__LINE__,left,right,result);
5555
5556     if(AOP_TYPE(right) == AOP_LIT)
5557         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5558
5559     size = AOP_SIZE(result);
5560
5561     // if(bit | yy)
5562     // xx = bit | yy;
5563     if (AOP_TYPE(left) == AOP_CRY){
5564         if(AOP_TYPE(right) == AOP_LIT){
5565             // c = bit & literal;
5566             if(lit){
5567                 // lit != 0 => result = 1
5568                 if(AOP_TYPE(result) == AOP_CRY){
5569                   if(size)
5570                     emitpcode(POC_BSF, popGet(AOP(result),0));
5571                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5572                   //     AOP(result)->aopu.aop_dir,
5573                   //     AOP(result)->aopu.aop_dir);
5574                     else if(ifx)
5575                         continueIfTrue(ifx);
5576                     goto release;
5577                 }
5578             } else {
5579                 // lit == 0 => result = left
5580                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5581                     goto release;
5582                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5583             }
5584         } else {
5585             if (AOP_TYPE(right) == AOP_CRY){
5586               if(pic14_sameRegs(AOP(result),AOP(left))){
5587                 // c = bit | bit;
5588                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5589                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5590                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5591
5592                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5593                          AOP(result)->aopu.aop_dir,
5594                          AOP(result)->aopu.aop_dir);
5595                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5596                          AOP(right)->aopu.aop_dir,
5597                          AOP(right)->aopu.aop_dir);
5598                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5599                          AOP(result)->aopu.aop_dir,
5600                          AOP(result)->aopu.aop_dir);
5601               } else {
5602                 if( AOP_TYPE(result) == AOP_ACC) {
5603                   emitpcode(POC_MOVLW, popGetLit(0));
5604                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5605                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5606                   emitpcode(POC_MOVLW, popGetLit(1));
5607
5608                 } else {
5609
5610                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5611                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5612                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5613                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5614
5615                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5616                                  AOP(result)->aopu.aop_dir,
5617                                  AOP(result)->aopu.aop_dir);
5618                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5619                                  AOP(right)->aopu.aop_dir,
5620                                  AOP(right)->aopu.aop_dir);
5621                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5622                                  AOP(left)->aopu.aop_dir,
5623                                  AOP(left)->aopu.aop_dir);
5624                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5625                                  AOP(result)->aopu.aop_dir,
5626                                  AOP(result)->aopu.aop_dir);
5627                 }
5628               }
5629             } else {
5630                 // c = bit | val;
5631                 symbol *tlbl = newiTempLabel(NULL);
5632                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5633
5634
5635                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5636                 if( AOP_TYPE(right) == AOP_ACC) {
5637                   emitpcode(POC_IORLW, popGetLit(0));
5638                   emitSKPNZ;
5639                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5640                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5641                 }
5642
5643
5644
5645                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5646                     pic14_emitcode(";XXX setb","c");
5647                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5648                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5649                 pic14_toBoolean(right);
5650                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5651                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5652                     jmpTrueOrFalse(ifx, tlbl);
5653                     goto release;
5654                 } else {
5655                     CLRC;
5656                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5657                 }
5658             }
5659         }
5660         // bit = c
5661         // val = c
5662         if(size)
5663             pic14_outBitC(result);
5664         // if(bit | ...)
5665         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5666             genIfxJump(ifx, "c");           
5667         goto release ;
5668     }
5669
5670     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5671     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5672     if((AOP_TYPE(right) == AOP_LIT) &&
5673        (AOP_TYPE(result) == AOP_CRY) &&
5674        (AOP_TYPE(left) != AOP_CRY)){
5675         if(lit){
5676           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5677             // result = 1
5678             if(size)
5679                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5680             else 
5681                 continueIfTrue(ifx);
5682             goto release;
5683         } else {
5684           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5685             // lit = 0, result = boolean(left)
5686             if(size)
5687                 pic14_emitcode(";XXX setb","c");
5688             pic14_toBoolean(right);
5689             if(size){
5690                 symbol *tlbl = newiTempLabel(NULL);
5691                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5692                 CLRC;
5693                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5694             } else {
5695                 genIfxJump (ifx,"a");
5696                 goto release;
5697             }
5698         }
5699         pic14_outBitC(result);
5700         goto release ;
5701     }
5702
5703     /* if left is same as result */
5704     if(pic14_sameRegs(AOP(result),AOP(left))){
5705       int know_W = -1;
5706       for(;size--; offset++,lit>>=8) {
5707         if(AOP_TYPE(right) == AOP_LIT){
5708           if((lit & 0xff) == 0)
5709             /*  or'ing with 0 has no effect */
5710             continue;
5711           else {
5712             int p = my_powof2(lit & 0xff);
5713             if(p>=0) {
5714               /* only one bit is set in the literal, so use a bsf instruction */
5715               emitpcode(POC_BSF,
5716                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5717             } else {
5718               if(know_W != (int)(lit & 0xff))
5719                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5720               know_W = lit & 0xff;
5721               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5722             }
5723                     
5724           }
5725         } else {
5726           if (AOP_TYPE(left) == AOP_ACC) {
5727             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5728             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5729           } else {                  
5730             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5731             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5732
5733             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5734             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5735
5736           }
5737         }
5738       }
5739     } else {
5740         // left & result in different registers
5741         if(AOP_TYPE(result) == AOP_CRY){
5742             // result = bit
5743             // if(size), result in bit
5744             // if(!size && ifx), conditional oper: if(left | right)
5745             symbol *tlbl = newiTempLabel(NULL);
5746             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5747             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5748
5749
5750             if(size)
5751                 pic14_emitcode(";XXX setb","c");
5752             while(sizer--){
5753                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5754                 pic14_emitcode(";XXX orl","a,%s",
5755                          aopGet(AOP(left),offset,FALSE,FALSE));
5756                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5757                 offset++;
5758             }
5759             if(size){
5760                 CLRC;
5761                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5762                 pic14_outBitC(result);
5763             } else if(ifx)
5764                 jmpTrueOrFalse(ifx, tlbl);
5765         } else for(;(size--);offset++){
5766           // normal case
5767           // result = left & right
5768           if(AOP_TYPE(right) == AOP_LIT){
5769             int t = (lit >> (offset*8)) & 0x0FFL;
5770             switch(t) { 
5771             case 0x00:
5772               if (AOP_TYPE(left) != AOP_ACC) {
5773                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5774               }
5775               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5776
5777               break;
5778             default:
5779               if (AOP_TYPE(left) == AOP_ACC) {
5780                 emitpcode(POC_IORLW,  popGetLit(t));
5781               } else {
5782                 emitpcode(POC_MOVLW,  popGetLit(t));
5783                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5784               }
5785               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));              
5786             }
5787             continue;
5788           }
5789
5790           // faster than result <- left, anl result,right
5791           // and better if result is SFR
5792           if (AOP_TYPE(left) == AOP_ACC) {
5793             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5794             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5795           } else {
5796             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5797             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5798
5799             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5800             pic14_emitcode("iorwf","%s,w",
5801                      aopGet(AOP(left),offset,FALSE,FALSE));
5802           }
5803           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5804           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5805         }
5806     }
5807
5808 release :
5809     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5810     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5811     freeAsmop(result,NULL,ic,TRUE);     
5812 }
5813
5814 /*-----------------------------------------------------------------*/
5815 /* genXor - code for xclusive or                                   */
5816 /*-----------------------------------------------------------------*/
5817 static void genXor (iCode *ic, iCode *ifx)
5818 {
5819   operand *left, *right, *result;
5820   int size, offset=0;
5821   unsigned long lit = 0L;
5822
5823   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5824
5825   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5826   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5827   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5828
5829   /* if left is a literal & right is not ||
5830      if left needs acc & right does not */
5831   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5832       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5833     operand *tmp = right ;
5834     right = left;
5835     left = tmp;
5836   }
5837
5838   /* if result = right then exchange them */
5839   if(pic14_sameRegs(AOP(result),AOP(right))){
5840     operand *tmp = right ;
5841     right = left;
5842     left = tmp;
5843   }
5844
5845   /* if right is bit then exchange them */
5846   if (AOP_TYPE(right) == AOP_CRY &&
5847       AOP_TYPE(left) != AOP_CRY){
5848     operand *tmp = right ;
5849     right = left;
5850     left = tmp;
5851   }
5852   if(AOP_TYPE(right) == AOP_LIT)
5853     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5854
5855   size = AOP_SIZE(result);
5856
5857   // if(bit ^ yy)
5858   // xx = bit ^ yy;
5859   if (AOP_TYPE(left) == AOP_CRY){
5860     if(AOP_TYPE(right) == AOP_LIT){
5861       // c = bit & literal;
5862       if(lit>>1){
5863         // lit>>1  != 0 => result = 1
5864         if(AOP_TYPE(result) == AOP_CRY){
5865           if(size)
5866             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5867             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5868           else if(ifx)
5869             continueIfTrue(ifx);
5870           goto release;
5871         }
5872         pic14_emitcode("setb","c");
5873       } else{
5874         // lit == (0 or 1)
5875         if(lit == 0){
5876           // lit == 0, result = left
5877           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5878             goto release;
5879           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5880         } else{
5881           // lit == 1, result = not(left)
5882           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5883             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5884             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5885             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5886             goto release;
5887           } else {
5888             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5889             pic14_emitcode("cpl","c");
5890           }
5891         }
5892       }
5893
5894     } else {
5895       // right != literal
5896       symbol *tlbl = newiTempLabel(NULL);
5897       if (AOP_TYPE(right) == AOP_CRY){
5898         // c = bit ^ bit;
5899         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5900       }
5901       else{
5902         int sizer = AOP_SIZE(right);
5903         // c = bit ^ val
5904         // if val>>1 != 0, result = 1
5905         pic14_emitcode("setb","c");
5906         while(sizer){
5907           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5908           if(sizer == 1)
5909             // test the msb of the lsb
5910             pic14_emitcode("anl","a,#0xfe");
5911           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5912           sizer--;
5913         }
5914         // val = (0,1)
5915         pic14_emitcode("rrc","a");
5916       }
5917       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5918       pic14_emitcode("cpl","c");
5919       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5920     }
5921     // bit = c
5922     // val = c
5923     if(size)
5924       pic14_outBitC(result);
5925     // if(bit | ...)
5926     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5927       genIfxJump(ifx, "c");           
5928     goto release ;
5929   }
5930
5931   if(pic14_sameRegs(AOP(result),AOP(left))){
5932     /* if left is same as result */
5933     for(;size--; offset++) {
5934       if(AOP_TYPE(right) == AOP_LIT){
5935         int t  = (lit >> (offset*8)) & 0x0FFL;
5936         if(t == 0x00L)
5937           continue;
5938         else
5939           if (IS_AOP_PREG(left)) {
5940             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5941             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5942             aopPut(AOP(result),"a",offset);
5943           } else {
5944             emitpcode(POC_MOVLW, popGetLit(t));
5945             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5946             pic14_emitcode("xrl","%s,%s",
5947                            aopGet(AOP(left),offset,FALSE,TRUE),
5948                            aopGet(AOP(right),offset,FALSE,FALSE));
5949           }
5950       } else {
5951         if (AOP_TYPE(left) == AOP_ACC)
5952           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5953         else {
5954           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5955           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5956 /*
5957           if (IS_AOP_PREG(left)) {
5958             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5959             aopPut(AOP(result),"a",offset);
5960           } else
5961             pic14_emitcode("xrl","%s,a",
5962                            aopGet(AOP(left),offset,FALSE,TRUE));
5963 */
5964         }
5965       }
5966     }
5967   } else {
5968     // left & result in different registers
5969     if(AOP_TYPE(result) == AOP_CRY){
5970       // result = bit
5971       // if(size), result in bit
5972       // if(!size && ifx), conditional oper: if(left ^ right)
5973       symbol *tlbl = newiTempLabel(NULL);
5974       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5975       if(size)
5976         pic14_emitcode("setb","c");
5977       while(sizer--){
5978         if((AOP_TYPE(right) == AOP_LIT) &&
5979            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5980           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5981         } else {
5982           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5983           pic14_emitcode("xrl","a,%s",
5984                          aopGet(AOP(left),offset,FALSE,FALSE));
5985         }
5986         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5987         offset++;
5988       }
5989       if(size){
5990         CLRC;
5991         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5992         pic14_outBitC(result);
5993       } else if(ifx)
5994         jmpTrueOrFalse(ifx, tlbl);
5995     } else for(;(size--);offset++){
5996       // normal case
5997       // result = left & right
5998       if(AOP_TYPE(right) == AOP_LIT){
5999         int t = (lit >> (offset*8)) & 0x0FFL;
6000         switch(t) { 
6001         case 0x00:
6002           if (AOP_TYPE(left) != AOP_ACC) {
6003             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6004           }
6005           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6006           pic14_emitcode("movf","%s,w",
6007                          aopGet(AOP(left),offset,FALSE,FALSE));
6008           pic14_emitcode("movwf","%s",
6009                          aopGet(AOP(result),offset,FALSE,FALSE));
6010           break;
6011         case 0xff:
6012           if (AOP_TYPE(left) == AOP_ACC) {
6013             emitpcode(POC_XORLW, popGetLit(t));
6014           } else {
6015             emitpcode(POC_COMFW,popGet(AOP(left),offset));
6016           }
6017           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6018           break;
6019         default:
6020           if (AOP_TYPE(left) == AOP_ACC) {
6021             emitpcode(POC_XORLW, popGetLit(t));
6022           } else {
6023             emitpcode(POC_MOVLW, popGetLit(t));
6024             emitpcode(POC_XORFW,popGet(AOP(left),offset));
6025           }
6026           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027           pic14_emitcode("movlw","0x%x",t);
6028           pic14_emitcode("xorwf","%s,w",
6029                          aopGet(AOP(left),offset,FALSE,FALSE));
6030           pic14_emitcode("movwf","%s",
6031                          aopGet(AOP(result),offset,FALSE,FALSE));
6032
6033         }
6034         continue;
6035       }
6036
6037       // faster than result <- left, anl result,right
6038       // and better if result is SFR
6039       if (AOP_TYPE(left) == AOP_ACC) {
6040         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6041         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6042       } else {
6043         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6044         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6045         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6046         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6047       }
6048       if ( AOP_TYPE(result) != AOP_ACC){
6049         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6050         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6051       }
6052     }
6053   }
6054
6055   release :
6056     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6058   freeAsmop(result,NULL,ic,TRUE);     
6059 }
6060
6061 /*-----------------------------------------------------------------*/
6062 /* genInline - write the inline code out                           */
6063 /*-----------------------------------------------------------------*/
6064 static void genInline (iCode *ic)
6065 {
6066     char *buffer, *bp, *bp1;
6067     
6068     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6069
6070     _G.inLine += (!options.asmpeep);
6071
6072     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6073     strcpy(buffer,IC_INLINE(ic));
6074
6075     /* emit each line as a code */
6076     while (*bp) {
6077         if (*bp == '\n') {
6078             *bp++ = '\0';
6079
6080             if(*bp1)
6081               addpCode2pBlock(pb,AssembleLine(bp1));
6082             bp1 = bp;
6083         } else {
6084             if (*bp == ':') {
6085                 bp++;
6086                 *bp = '\0';
6087                 bp++;
6088                 pic14_emitcode(bp1,"");
6089                 bp1 = bp;
6090             } else
6091                 bp++;
6092         }
6093     }
6094     if ((bp1 != bp) && *bp1)
6095       addpCode2pBlock(pb,AssembleLine(bp1));
6096
6097     Safe_free(buffer);
6098
6099     _G.inLine -= (!options.asmpeep);
6100 }
6101
6102 /*-----------------------------------------------------------------*/
6103 /* genRRC - rotate right with carry                                */
6104 /*-----------------------------------------------------------------*/
6105 static void genRRC (iCode *ic)
6106 {
6107   operand *left , *result ;
6108   int size, offset = 0, same;
6109
6110   /* rotate right with carry */
6111   left = IC_LEFT(ic);
6112   result=IC_RESULT(ic);
6113   aopOp (left,ic,FALSE);
6114   aopOp (result,ic,FALSE);
6115
6116   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6117
6118   same = pic14_sameRegs(AOP(result),AOP(left));
6119
6120   size = AOP_SIZE(result);    
6121
6122   /* get the lsb and put it into the carry */
6123   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6124
6125   offset = 0 ;
6126
6127   while(size--) {
6128
6129     if(same) {
6130       emitpcode(POC_RRF, popGet(AOP(left),offset));
6131     } else {
6132       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6133       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6134     }
6135
6136     offset++;
6137   }
6138
6139   freeAsmop(left,NULL,ic,TRUE);
6140   freeAsmop(result,NULL,ic,TRUE);
6141 }
6142
6143 /*-----------------------------------------------------------------*/
6144 /* genRLC - generate code for rotate left with carry               */
6145 /*-----------------------------------------------------------------*/
6146 static void genRLC (iCode *ic)
6147 {    
6148   operand *left , *result ;
6149   int size, offset = 0;
6150   int same;
6151
6152   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6153   /* rotate right with carry */
6154   left = IC_LEFT(ic);
6155   result=IC_RESULT(ic);
6156   aopOp (left,ic,FALSE);
6157   aopOp (result,ic,FALSE);
6158
6159   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6160
6161   same = pic14_sameRegs(AOP(result),AOP(left));
6162
6163   /* move it to the result */
6164   size = AOP_SIZE(result);    
6165
6166   /* get the msb and put it into the carry */
6167   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6168
6169   offset = 0 ;
6170
6171   while(size--) {
6172
6173     if(same) {
6174       emitpcode(POC_RLF, popGet(AOP(left),offset));
6175     } else {
6176       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6177       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6178     }
6179
6180     offset++;
6181   }
6182
6183
6184   freeAsmop(left,NULL,ic,TRUE);
6185   freeAsmop(result,NULL,ic,TRUE);
6186 }
6187
6188 /*-----------------------------------------------------------------*/
6189 /* genGetHbit - generates code get highest order bit               */
6190 /*-----------------------------------------------------------------*/
6191 static void genGetHbit (iCode *ic)
6192 {
6193     operand *left, *result;
6194     left = IC_LEFT(ic);
6195     result=IC_RESULT(ic);
6196     aopOp (left,ic,FALSE);
6197     aopOp (result,ic,FALSE);
6198
6199     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6200     /* get the highest order byte into a */
6201     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6202     if(AOP_TYPE(result) == AOP_CRY){
6203         pic14_emitcode("rlc","a");
6204         pic14_outBitC(result);
6205     }
6206     else{
6207         pic14_emitcode("rl","a");
6208         pic14_emitcode("anl","a,#0x01");
6209         pic14_outAcc(result);
6210     }
6211
6212
6213     freeAsmop(left,NULL,ic,TRUE);
6214     freeAsmop(result,NULL,ic,TRUE);
6215 }
6216
6217 /*-----------------------------------------------------------------*/
6218 /* AccRol - rotate left accumulator by known count                 */
6219 /*-----------------------------------------------------------------*/
6220 static void AccRol (int shCount)
6221 {
6222     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6223     shCount &= 0x0007;              // shCount : 0..7
6224     switch(shCount){
6225         case 0 :
6226             break;
6227         case 1 :
6228             pic14_emitcode("rl","a");
6229             break;
6230         case 2 :
6231             pic14_emitcode("rl","a");
6232             pic14_emitcode("rl","a");
6233             break;
6234         case 3 :
6235             pic14_emitcode("swap","a");
6236             pic14_emitcode("rr","a");
6237             break;
6238         case 4 :
6239             pic14_emitcode("swap","a");
6240             break;
6241         case 5 :
6242             pic14_emitcode("swap","a");
6243             pic14_emitcode("rl","a");
6244             break;
6245         case 6 :
6246             pic14_emitcode("rr","a");
6247             pic14_emitcode("rr","a");
6248             break;
6249         case 7 :
6250             pic14_emitcode("rr","a");
6251             break;
6252     }
6253 }
6254
6255 /*-----------------------------------------------------------------*/
6256 /* AccLsh - left shift accumulator by known count                  */
6257 /*-----------------------------------------------------------------*/
6258 static void AccLsh (int shCount)
6259 {
6260     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6261     if(shCount != 0){
6262         if(shCount == 1)
6263             pic14_emitcode("add","a,acc");
6264         else 
6265             if(shCount == 2) {
6266             pic14_emitcode("add","a,acc");
6267             pic14_emitcode("add","a,acc");
6268         } else {
6269             /* rotate left accumulator */
6270             AccRol(shCount);
6271             /* and kill the lower order bits */
6272             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6273         }
6274     }
6275 }
6276
6277 /*-----------------------------------------------------------------*/
6278 /* AccRsh - right shift accumulator by known count                 */
6279 /*-----------------------------------------------------------------*/
6280 static void AccRsh (int shCount)
6281 {
6282     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6283     if(shCount != 0){
6284         if(shCount == 1){
6285             CLRC;
6286             pic14_emitcode("rrc","a");
6287         } else {
6288             /* rotate right accumulator */
6289             AccRol(8 - shCount);
6290             /* and kill the higher order bits */
6291             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6292         }
6293     }
6294 }
6295
6296 #if 0
6297 /*-----------------------------------------------------------------*/
6298 /* AccSRsh - signed right shift accumulator by known count                 */
6299 /*-----------------------------------------------------------------*/
6300 static void AccSRsh (int shCount)
6301 {
6302     symbol *tlbl ;
6303     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6304     if(shCount != 0){
6305         if(shCount == 1){
6306             pic14_emitcode("mov","c,acc.7");
6307             pic14_emitcode("rrc","a");
6308         } else if(shCount == 2){
6309             pic14_emitcode("mov","c,acc.7");
6310             pic14_emitcode("rrc","a");
6311             pic14_emitcode("mov","c,acc.7");
6312             pic14_emitcode("rrc","a");
6313         } else {
6314             tlbl = newiTempLabel(NULL);
6315             /* rotate right accumulator */
6316             AccRol(8 - shCount);
6317             /* and kill the higher order bits */
6318             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6319             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6320             pic14_emitcode("orl","a,#0x%02x",
6321                      (unsigned char)~SRMask[shCount]);
6322             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6323         }
6324     }
6325 }
6326 #endif
6327 /*-----------------------------------------------------------------*/
6328 /* shiftR1Left2Result - shift right one byte from left to result   */
6329 /*-----------------------------------------------------------------*/
6330 static void shiftR1Left2ResultSigned (operand *left, int offl,
6331                                 operand *result, int offr,
6332                                 int shCount)
6333 {
6334   int same;
6335
6336   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6337
6338   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6339
6340   switch(shCount) {
6341   case 1:
6342     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6343     if(same) 
6344       emitpcode(POC_RRF, popGet(AOP(result),offr));
6345     else {
6346       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6347       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6348     }
6349
6350     break;
6351   case 2:
6352
6353     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6354     if(same) 
6355       emitpcode(POC_RRF, popGet(AOP(result),offr));
6356     else {
6357       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6359     }
6360     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6361     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6362
6363     break;
6364
6365   case 3:
6366     if(same)
6367       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6368     else {
6369       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6370       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6371     }
6372
6373     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6374     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6375     emitpcode(POC_ANDLW, popGetLit(0x1f));
6376
6377     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6378     emitpcode(POC_IORLW, popGetLit(0xe0));
6379
6380     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381     break;
6382
6383   case 4:
6384     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6385     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6386     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6387     emitpcode(POC_IORLW,  popGetLit(0xf0));
6388     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6389     break;
6390   case 5:
6391     if(same) {
6392       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6393     } else {
6394       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6395       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6396     }
6397     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6398     emitpcode(POC_ANDLW,  popGetLit(0x07));
6399     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6400     emitpcode(POC_IORLW,  popGetLit(0xf8));
6401     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6402     break;
6403
6404   case 6:
6405     if(same) {
6406       emitpcode(POC_MOVLW, popGetLit(0x00));
6407       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6408       emitpcode(POC_MOVLW, popGetLit(0xfe));
6409       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6410       emitpcode(POC_IORLW, popGetLit(0x01));
6411       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6412     } else {
6413       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6414       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6415       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6416       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6417       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6418     }
6419     break;
6420
6421   case 7:
6422     if(same) {
6423       emitpcode(POC_MOVLW, popGetLit(0x00));
6424       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6425       emitpcode(POC_MOVLW, popGetLit(0xff));
6426       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427     } else {
6428       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6429       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6430       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6431     }
6432
6433   default:
6434     break;
6435   }
6436 }
6437
6438 /*-----------------------------------------------------------------*/
6439 /* shiftR1Left2Result - shift right one byte from left to result   */
6440 /*-----------------------------------------------------------------*/
6441 static void shiftR1Left2Result (operand *left, int offl,
6442                                 operand *result, int offr,
6443                                 int shCount, int sign)
6444 {
6445   int same;
6446
6447   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6448
6449   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6450
6451   /* Copy the msb into the carry if signed. */
6452   if(sign) {
6453     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6454     return;
6455   }
6456
6457
6458
6459   switch(shCount) {
6460   case 1:
6461     emitCLRC;
6462     if(same) 
6463       emitpcode(POC_RRF, popGet(AOP(result),offr));
6464     else {
6465       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6466       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6467     }
6468     break;
6469   case 2:
6470     emitCLRC;
6471     if(same) {
6472       emitpcode(POC_RRF, popGet(AOP(result),offr));
6473     } else {
6474       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6476     }
6477     emitCLRC;
6478     emitpcode(POC_RRF, popGet(AOP(result),offr));
6479
6480     break;
6481   case 3:
6482     if(same)
6483       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6484     else {
6485       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6486       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487     }
6488
6489     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6490     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6491     emitpcode(POC_ANDLW, popGetLit(0x1f));
6492     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6493     break;
6494       
6495   case 4:
6496     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497     emitpcode(POC_ANDLW, popGetLit(0x0f));
6498     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6499     break;
6500
6501   case 5:
6502     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6503     emitpcode(POC_ANDLW, popGetLit(0x0f));
6504     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505     emitCLRC;
6506     emitpcode(POC_RRF, popGet(AOP(result),offr));
6507
6508     break;
6509   case 6:
6510
6511     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6512     emitpcode(POC_ANDLW, popGetLit(0x80));
6513     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6515     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6516     break;
6517
6518   case 7:
6519
6520     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6522     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6523
6524     break;
6525
6526   default:
6527     break;
6528   }
6529 }
6530
6531 /*-----------------------------------------------------------------*/
6532 /* shiftL1Left2Result - shift left one byte from left to result    */
6533 /*-----------------------------------------------------------------*/
6534 static void shiftL1Left2Result (operand *left, int offl,
6535                                 operand *result, int offr, int shCount)
6536 {
6537   int same;
6538
6539   //    char *l;
6540   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6541
6542   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6543   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6544     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6545     //    MOVA(l);
6546     /* shift left accumulator */
6547     //AccLsh(shCount); // don't comment out just yet...
6548   //    aopPut(AOP(result),"a",offr);
6549
6550   switch(shCount) {
6551   case 1:
6552     /* Shift left 1 bit position */
6553     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6554     if(same) {
6555       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6556     } else {
6557       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6558       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6559     }
6560     break;
6561   case 2:
6562     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563     emitpcode(POC_ANDLW,popGetLit(0x7e));
6564     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6565     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6566     break;
6567   case 3:
6568     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6569     emitpcode(POC_ANDLW,popGetLit(0x3e));
6570     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6571     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6572     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6573     break;
6574   case 4:
6575     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6576     emitpcode(POC_ANDLW, popGetLit(0xf0));
6577     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6578     break;
6579   case 5:
6580     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6581     emitpcode(POC_ANDLW, popGetLit(0xf0));
6582     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6584     break;
6585   case 6:
6586     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587     emitpcode(POC_ANDLW, popGetLit(0x30));
6588     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6590     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6591     break;
6592   case 7:
6593     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6594     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6595     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6596     break;
6597
6598   default:
6599     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6600   }
6601
6602 }
6603
6604 /*-----------------------------------------------------------------*/
6605 /* movLeft2Result - move byte from left to result                  */
6606 /*-----------------------------------------------------------------*/
6607 static void movLeft2Result (operand *left, int offl,
6608                             operand *result, int offr)
6609 {
6610   char *l;
6611   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6612   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6613     l = aopGet(AOP(left),offl,FALSE,FALSE);
6614
6615     if (*l == '@' && (IS_AOP_PREG(result))) {
6616       pic14_emitcode("mov","a,%s",l);
6617       aopPut(AOP(result),"a",offr);
6618     } else {
6619       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6620       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6621     }
6622   }
6623 }
6624
6625 /*-----------------------------------------------------------------*/
6626 /* shiftL2Left2Result - shift left two bytes from left to result   */
6627 /*-----------------------------------------------------------------*/
6628 static void shiftL2Left2Result (operand *left, int offl,
6629                                 operand *result, int offr, int shCount)
6630 {
6631
6632
6633   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6634
6635   if(pic14_sameRegs(AOP(result), AOP(left))) {
6636     switch(shCount) {
6637     case 0:
6638       break;
6639     case 1:
6640     case 2:
6641     case 3:
6642
6643       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6644       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6645       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6646
6647       while(--shCount) {
6648         emitCLRC;
6649         emitpcode(POC_RLF, popGet(AOP(result),offr));
6650         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6651       }
6652
6653       break;
6654     case 4:
6655     case 5:
6656       emitpcode(POC_MOVLW, popGetLit(0x0f));
6657       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6658       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6659       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6660       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6661       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6662       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6663       if(shCount >=5) {
6664         emitpcode(POC_RLF, popGet(AOP(result),offr));
6665         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6666       }
6667       break;
6668     case 6:
6669       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6670       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6671       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6672       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6673       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6674       emitpcode(POC_ANDLW,popGetLit(0xc0));
6675       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6676       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6677       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6678       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6679       break;
6680     case 7:
6681       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6683       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6684       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6685       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6686     }
6687
6688   } else {
6689     switch(shCount) {
6690     case 0:
6691       break;
6692     case 1:
6693     case 2:
6694     case 3:
6695       /* note, use a mov/add for the shift since the mov has a
6696          chance of getting optimized out */
6697       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6698       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6699       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6700       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6701       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6702
6703       while(--shCount) {
6704         emitCLRC;
6705         emitpcode(POC_RLF, popGet(AOP(result),offr));
6706         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6707       }
6708       break;
6709
6710     case 4:
6711     case 5:
6712       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713       emitpcode(POC_ANDLW, popGetLit(0xF0));
6714       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6715       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6716       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6717       emitpcode(POC_ANDLW, popGetLit(0xF0));
6718       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6719       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6720
6721
6722       if(shCount == 5) {
6723         emitpcode(POC_RLF, popGet(AOP(result),offr));
6724         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6725       }
6726       break;
6727     case 6:
6728       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6729       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6730       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6731       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6732
6733       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6734       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6735       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6736       emitpcode(POC_ANDLW,popGetLit(0xc0));
6737       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6738       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6739       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6740       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741       break;
6742     case 7:
6743       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6744       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6745       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6747       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6748     }
6749   }
6750
6751 }
6752 /*-----------------------------------------------------------------*/
6753 /* shiftR2Left2Result - shift right two bytes from left to result  */
6754 /*-----------------------------------------------------------------*/
6755 static void shiftR2Left2Result (operand *left, int offl,
6756                                 operand *result, int offr,
6757                                 int shCount, int sign)
6758 {
6759   int same=0;
6760
6761   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6762   same = pic14_sameRegs(AOP(result), AOP(left));
6763
6764   if(same && ((offl + MSB16) == offr)){
6765     same=1;
6766     /* don't crash result[offr] */
6767     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6768     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6769   }
6770 /* else {
6771     movLeft2Result(left,offl, result, offr);
6772     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6773   }
6774 */
6775   /* a:x >> shCount (x = lsb(result))*/
6776 /*
6777   if(sign)
6778     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6779   else {
6780     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6781 */
6782   switch(shCount) {
6783   case 0:
6784     break;
6785   case 1:
6786   case 2:
6787   case 3:
6788     if(sign)
6789       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6790     else
6791       emitCLRC;
6792
6793     if(same) {
6794       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6795       emitpcode(POC_RRF,popGet(AOP(result),offr));
6796     } else {
6797       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6798       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6799       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6800       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6801     }
6802
6803     while(--shCount) {
6804       if(sign)
6805         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6806       else
6807         emitCLRC;
6808       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6809       emitpcode(POC_RRF,popGet(AOP(result),offr));
6810     }
6811     break;
6812   case 4:
6813   case 5:
6814     if(same) {
6815
6816       emitpcode(POC_MOVLW, popGetLit(0xf0));
6817       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6818       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6819
6820       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6821       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6822       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6823       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6824     } else {
6825       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6826       emitpcode(POC_ANDLW, popGetLit(0x0f));
6827       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6828
6829       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6830       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6831       emitpcode(POC_ANDLW, popGetLit(0xf0));
6832       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6834     }
6835
6836     if(shCount >=5) {
6837       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6838       emitpcode(POC_RRF, popGet(AOP(result),offr));
6839     }
6840
6841     if(sign) {
6842       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6843       emitpcode(POC_BTFSC, 
6844                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6845       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6846     }
6847
6848     break;
6849
6850   case 6:
6851     if(same) {
6852
6853       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6854       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6855
6856       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6857       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6858       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6859       emitpcode(POC_ANDLW,popGetLit(0x03));
6860       if(sign) {
6861         emitpcode(POC_BTFSC, 
6862                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6863         emitpcode(POC_IORLW,popGetLit(0xfc));
6864       }
6865       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6866       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6867       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6868       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6869     } else {
6870       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6871       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6872       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6873       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6874       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6875       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6876       emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6877       emitpcode(POC_ANDLW,popGetLit(0x03));
6878       if(sign) {
6879         emitpcode(POC_BTFSC, 
6880                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6881         emitpcode(POC_IORLW,popGetLit(0xfc));
6882       }
6883       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6884       //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6885
6886         
6887     }
6888
6889     break;
6890   case 7:
6891     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6892     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6893     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6894     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6895     if(sign) {
6896       emitSKPNC;
6897       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6898     } else 
6899       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6900   }
6901 }
6902
6903
6904 /*-----------------------------------------------------------------*/
6905 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6906 /*-----------------------------------------------------------------*/
6907 static void shiftLLeftOrResult (operand *left, int offl,
6908                                 operand *result, int offr, int shCount)
6909 {
6910     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6911     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6912     /* shift left accumulator */
6913     AccLsh(shCount);
6914     /* or with result */
6915     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6916     /* back to result */
6917     aopPut(AOP(result),"a",offr);
6918 }
6919
6920 /*-----------------------------------------------------------------*/
6921 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftRLeftOrResult (operand *left, int offl,
6924                                 operand *result, int offr, int shCount)
6925 {
6926     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6927     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6928     /* shift right accumulator */
6929     AccRsh(shCount);
6930     /* or with result */
6931     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6932     /* back to result */
6933     aopPut(AOP(result),"a",offr);
6934 }
6935
6936 /*-----------------------------------------------------------------*/
6937 /* genlshOne - left shift a one byte quantity by known count       */
6938 /*-----------------------------------------------------------------*/
6939 static void genlshOne (operand *result, operand *left, int shCount)
6940 {       
6941     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6942     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6943 }
6944
6945 /*-----------------------------------------------------------------*/
6946 /* genlshTwo - left shift two bytes by known amount != 0           */
6947 /*-----------------------------------------------------------------*/
6948 static void genlshTwo (operand *result,operand *left, int shCount)
6949 {
6950     int size;
6951     
6952     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6953     size = pic14_getDataSize(result);
6954
6955     /* if shCount >= 8 */
6956     if (shCount >= 8) {
6957         shCount -= 8 ;
6958
6959         if (size > 1){
6960             if (shCount)
6961                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6962             else 
6963                 movLeft2Result(left, LSB, result, MSB16);
6964         }
6965         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6966     }
6967
6968     /*  1 <= shCount <= 7 */
6969     else {  
6970         if(size == 1)
6971             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6972         else 
6973             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6974     }
6975 }
6976
6977 /*-----------------------------------------------------------------*/
6978 /* shiftLLong - shift left one long from left to result            */
6979 /* offl = LSB or MSB16                                             */
6980 /*-----------------------------------------------------------------*/
6981 static void shiftLLong (operand *left, operand *result, int offr )
6982 {
6983     char *l;
6984     int size = AOP_SIZE(result);
6985
6986     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6987     if(size >= LSB+offr){
6988         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6989         MOVA(l);
6990         pic14_emitcode("add","a,acc");
6991         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6992             size >= MSB16+offr && offr != LSB )
6993             pic14_emitcode("xch","a,%s",
6994                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6995         else        
6996             aopPut(AOP(result),"a",LSB+offr);
6997     }
6998
6999     if(size >= MSB16+offr){
7000         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7001             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7002             MOVA(l);
7003         }
7004         pic14_emitcode("rlc","a");
7005         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7006             size >= MSB24+offr && offr != LSB)
7007             pic14_emitcode("xch","a,%s",
7008                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7009         else        
7010             aopPut(AOP(result),"a",MSB16+offr);
7011     }
7012
7013     if(size >= MSB24+offr){
7014         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7015             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7016             MOVA(l);
7017         }
7018         pic14_emitcode("rlc","a");
7019         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7020             size >= MSB32+offr && offr != LSB )
7021             pic14_emitcode("xch","a,%s",
7022                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7023         else        
7024             aopPut(AOP(result),"a",MSB24+offr);
7025     }
7026
7027     if(size > MSB32+offr){
7028         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7029             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7030             MOVA(l);    
7031         }
7032         pic14_emitcode("rlc","a");
7033         aopPut(AOP(result),"a",MSB32+offr);
7034     }
7035     if(offr != LSB)
7036         aopPut(AOP(result),zero,LSB);       
7037 }
7038
7039 /*-----------------------------------------------------------------*/
7040 /* genlshFour - shift four byte by a known amount != 0             */
7041 /*-----------------------------------------------------------------*/
7042 static void genlshFour (operand *result, operand *left, int shCount)
7043 {
7044     int size;
7045
7046     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7047     size = AOP_SIZE(result);
7048
7049     /* if shifting more that 3 bytes */
7050     if (shCount >= 24 ) {
7051         shCount -= 24;
7052         if (shCount)
7053             /* lowest order of left goes to the highest
7054             order of the destination */
7055             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7056         else
7057             movLeft2Result(left, LSB, result, MSB32);
7058         aopPut(AOP(result),zero,LSB);
7059         aopPut(AOP(result),zero,MSB16);
7060         aopPut(AOP(result),zero,MSB32);
7061         return;
7062     }
7063
7064     /* more than two bytes */
7065     else if ( shCount >= 16 ) {
7066         /* lower order two bytes goes to higher order two bytes */
7067         shCount -= 16;
7068         /* if some more remaining */
7069         if (shCount)
7070             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7071         else {
7072             movLeft2Result(left, MSB16, result, MSB32);
7073             movLeft2Result(left, LSB, result, MSB24);
7074         }
7075         aopPut(AOP(result),zero,MSB16);
7076         aopPut(AOP(result),zero,LSB);
7077         return;
7078     }    
7079
7080     /* if more than 1 byte */
7081     else if ( shCount >= 8 ) {
7082         /* lower order three bytes goes to higher order  three bytes */
7083         shCount -= 8;
7084         if(size == 2){
7085             if(shCount)
7086                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7087             else
7088                 movLeft2Result(left, LSB, result, MSB16);
7089         }
7090         else{   /* size = 4 */
7091             if(shCount == 0){
7092                 movLeft2Result(left, MSB24, result, MSB32);
7093                 movLeft2Result(left, MSB16, result, MSB24);
7094                 movLeft2Result(left, LSB, result, MSB16);
7095                 aopPut(AOP(result),zero,LSB);
7096             }
7097             else if(shCount == 1)
7098                 shiftLLong(left, result, MSB16);
7099             else{
7100                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7101                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7102                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7103                 aopPut(AOP(result),zero,LSB);
7104             }
7105         }
7106     }
7107
7108     /* 1 <= shCount <= 7 */
7109     else if(shCount <= 2){
7110         shiftLLong(left, result, LSB);
7111         if(shCount == 2)
7112             shiftLLong(result, result, LSB);
7113     }
7114     /* 3 <= shCount <= 7, optimize */
7115     else{
7116         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7117         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7118         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7119     }
7120 }
7121
7122 /*-----------------------------------------------------------------*/
7123 /* genLeftShiftLiteral - left shifting by known count              */
7124 /*-----------------------------------------------------------------*/
7125 static void genLeftShiftLiteral (operand *left,
7126                                  operand *right,
7127                                  operand *result,
7128                                  iCode *ic)
7129 {    
7130     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7131     int size;
7132
7133     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7134     freeAsmop(right,NULL,ic,TRUE);
7135
7136     aopOp(left,ic,FALSE);
7137     aopOp(result,ic,FALSE);
7138
7139     size = getSize(operandType(result));
7140
7141 #if VIEW_SIZE
7142     pic14_emitcode("; shift left ","result %d, left %d",size,
7143              AOP_SIZE(left));
7144 #endif
7145
7146     /* I suppose that the left size >= result size */
7147     if(shCount == 0){
7148         while(size--){
7149             movLeft2Result(left, size, result, size);
7150         }
7151     }
7152
7153     else if(shCount >= (size * 8))
7154         while(size--)
7155             aopPut(AOP(result),zero,size);
7156     else{
7157         switch (size) {
7158             case 1:
7159                 genlshOne (result,left,shCount);
7160                 break;
7161
7162             case 2:
7163             case 3:
7164                 genlshTwo (result,left,shCount);
7165                 break;
7166
7167             case 4:
7168                 genlshFour (result,left,shCount);
7169                 break;
7170         }
7171     }
7172     freeAsmop(left,NULL,ic,TRUE);
7173     freeAsmop(result,NULL,ic,TRUE);
7174 }
7175
7176 /*-----------------------------------------------------------------*
7177  * genMultiAsm - repeat assembly instruction for size of register.
7178  * if endian == 1, then the high byte (i.e base address + size of 
7179  * register) is used first else the low byte is used first;
7180  *-----------------------------------------------------------------*/
7181 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7182 {
7183
7184   int offset = 0;
7185
7186   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7187
7188   if(!reg)
7189     return;
7190
7191   if(!endian) {
7192     endian = 1;
7193   } else {
7194     endian = -1;
7195     offset = size-1;
7196   }
7197
7198   while(size--) {
7199     emitpcode(poc,    popGet(AOP(reg),offset));
7200     offset += endian;
7201   }
7202
7203 }
7204 /*-----------------------------------------------------------------*/
7205 /* genLeftShift - generates code for left shifting                 */
7206 /*-----------------------------------------------------------------*/
7207 static void genLeftShift (iCode *ic)
7208 {
7209   operand *left,*right, *result;
7210   int size, offset;
7211   char *l;
7212   symbol *tlbl , *tlbl1;
7213   pCodeOp *pctemp;
7214
7215   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7216
7217   right = IC_RIGHT(ic);
7218   left  = IC_LEFT(ic);
7219   result = IC_RESULT(ic);
7220
7221   aopOp(right,ic,FALSE);
7222
7223   /* if the shift count is known then do it 
7224      as efficiently as possible */
7225   if (AOP_TYPE(right) == AOP_LIT) {
7226     genLeftShiftLiteral (left,right,result,ic);
7227     return ;
7228   }
7229
7230   /* shift count is unknown then we have to form 
7231      a loop get the loop count in B : Note: we take
7232      only the lower order byte since shifting
7233      more that 32 bits make no sense anyway, ( the
7234      largest size of an object can be only 32 bits ) */  
7235
7236     
7237   aopOp(left,ic,FALSE);
7238   aopOp(result,ic,FALSE);
7239
7240   /* now move the left to the result if they are not the
7241      same */
7242   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7243       AOP_SIZE(result) > 1) {
7244
7245     size = AOP_SIZE(result);
7246     offset=0;
7247     while (size--) {
7248       l = aopGet(AOP(left),offset,FALSE,TRUE);
7249       if (*l == '@' && (IS_AOP_PREG(result))) {
7250
7251         pic14_emitcode("mov","a,%s",l);
7252         aopPut(AOP(result),"a",offset);
7253       } else {
7254         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7255         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7256         //aopPut(AOP(result),l,offset);
7257       }
7258       offset++;
7259     }
7260   }
7261
7262   size = AOP_SIZE(result);
7263
7264   /* if it is only one byte then */
7265   if (size == 1) {
7266     if(optimized_for_speed) {
7267       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7268       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7269       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7270       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7271       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7272       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7273       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7274       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7275       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7276       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7277       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7278       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7279     } else {
7280
7281       tlbl = newiTempLabel(NULL);
7282       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7283         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7284         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7285       }
7286
7287       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7288       emitpcode(POC_RRF,    popGet(AOP(result),0));
7289       emitpLabel(tlbl->key);
7290       emitpcode(POC_RLF,    popGet(AOP(result),0));
7291       emitpcode(POC_ADDLW,  popGetLit(1));
7292       emitSKPC;
7293       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7294     }
7295     goto release ;
7296   }
7297     
7298   if (pic14_sameRegs(AOP(left),AOP(result))) {
7299
7300     tlbl = newiTempLabel(NULL);
7301     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7302     genMultiAsm(POC_RRF, result, size,1);
7303     emitpLabel(tlbl->key);
7304     genMultiAsm(POC_RLF, result, size,0);
7305     emitpcode(POC_ADDLW,  popGetLit(1));
7306     emitSKPC;
7307     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7308     goto release;
7309   }
7310
7311   //tlbl = newiTempLabel(NULL);
7312   //offset = 0 ;   
7313   //tlbl1 = newiTempLabel(NULL);
7314
7315   //reAdjustPreg(AOP(result));    
7316     
7317   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7318   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7319   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7320   //MOVA(l);
7321   //pic14_emitcode("add","a,acc");         
7322   //aopPut(AOP(result),"a",offset++);
7323   //while (--size) {
7324   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7325   //  MOVA(l);
7326   //  pic14_emitcode("rlc","a");         
7327   //  aopPut(AOP(result),"a",offset++);
7328   //}
7329   //reAdjustPreg(AOP(result));
7330
7331   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7332   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7333
7334
7335   tlbl = newiTempLabel(NULL);
7336   tlbl1= newiTempLabel(NULL);
7337
7338   size = AOP_SIZE(result);
7339   offset = 1;
7340
7341   pctemp = popGetTempReg();  /* grab a temporary working register. */
7342
7343   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7344
7345   /* offset should be 0, 1 or 3 */
7346   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7347   emitSKPNZ;
7348   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7349
7350   emitpcode(POC_MOVWF, pctemp);
7351
7352
7353   emitpLabel(tlbl->key);
7354
7355   emitCLRC;
7356   emitpcode(POC_RLF,  popGet(AOP(result),0));
7357   while(--size)
7358     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7359
7360   emitpcode(POC_DECFSZ,  pctemp);
7361   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7362   emitpLabel(tlbl1->key);
7363
7364   popReleaseTempReg(pctemp);
7365
7366
7367  release:
7368   freeAsmop (right,NULL,ic,TRUE);
7369   freeAsmop(left,NULL,ic,TRUE);
7370   freeAsmop(result,NULL,ic,TRUE);
7371 }
7372
7373 /*-----------------------------------------------------------------*/
7374 /* genrshOne - right shift a one byte quantity by known count      */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshOne (operand *result, operand *left,
7377                        int shCount, int sign)
7378 {
7379     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7380     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7381 }
7382
7383 /*-----------------------------------------------------------------*/
7384 /* genrshTwo - right shift two bytes by known amount != 0          */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshTwo (operand *result,operand *left,
7387                        int shCount, int sign)
7388 {
7389   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7390   /* if shCount >= 8 */
7391   if (shCount >= 8) {
7392     shCount -= 8 ;
7393     if (shCount)
7394       shiftR1Left2Result(left, MSB16, result, LSB,
7395                          shCount, sign);
7396     else
7397       movLeft2Result(left, MSB16, result, LSB);
7398
7399     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7400
7401     if(sign) {
7402       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7403       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7404     }
7405   }
7406
7407   /*  1 <= shCount <= 7 */
7408   else
7409     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7410 }
7411
7412 /*-----------------------------------------------------------------*/
7413 /* shiftRLong - shift right one long from left to result           */
7414 /* offl = LSB or MSB16                                             */
7415 /*-----------------------------------------------------------------*/
7416 static void shiftRLong (operand *left, int offl,
7417                         operand *result, int sign)
7418 {
7419     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7420     if(!sign)
7421         pic14_emitcode("clr","c");
7422     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7423     if(sign)
7424         pic14_emitcode("mov","c,acc.7");
7425     pic14_emitcode("rrc","a");
7426     aopPut(AOP(result),"a",MSB32-offl);
7427     if(offl == MSB16)
7428         /* add sign of "a" */
7429         addSign(result, MSB32, sign);
7430
7431     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7432     pic14_emitcode("rrc","a");
7433     aopPut(AOP(result),"a",MSB24-offl);
7434
7435     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7436     pic14_emitcode("rrc","a");
7437     aopPut(AOP(result),"a",MSB16-offl);
7438
7439     if(offl == LSB){
7440         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7441         pic14_emitcode("rrc","a");
7442         aopPut(AOP(result),"a",LSB);
7443     }
7444 }
7445
7446 /*-----------------------------------------------------------------*/
7447 /* genrshFour - shift four byte by a known amount != 0             */
7448 /*-----------------------------------------------------------------*/
7449 static void genrshFour (operand *result, operand *left,
7450                         int shCount, int sign)
7451 {
7452   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7453   /* if shifting more that 3 bytes */
7454   if(shCount >= 24 ) {
7455     shCount -= 24;
7456     if(shCount)
7457       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7458     else
7459       movLeft2Result(left, MSB32, result, LSB);
7460
7461     addSign(result, MSB16, sign);
7462   }
7463   else if(shCount >= 16){
7464     shCount -= 16;
7465     if(shCount)
7466       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7467     else{
7468       movLeft2Result(left, MSB24, result, LSB);
7469       movLeft2Result(left, MSB32, result, MSB16);
7470     }
7471     addSign(result, MSB24, sign);
7472   }
7473   else if(shCount >= 8){
7474     shCount -= 8;
7475     if(shCount == 1)
7476       shiftRLong(left, MSB16, result, sign);
7477     else if(shCount == 0){
7478       movLeft2Result(left, MSB16, result, LSB);
7479       movLeft2Result(left, MSB24, result, MSB16);
7480       movLeft2Result(left, MSB32, result, MSB24);
7481       addSign(result, MSB32, sign);
7482     }
7483     else{
7484       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7485       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7486       /* the last shift is signed */
7487       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7488       addSign(result, MSB32, sign);
7489     }
7490   }
7491   else{   /* 1 <= shCount <= 7 */
7492     if(shCount <= 2){
7493       shiftRLong(left, LSB, result, sign);
7494       if(shCount == 2)
7495         shiftRLong(result, LSB, result, sign);
7496     }
7497     else{
7498       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7499       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7500       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7501     }
7502   }
7503 }
7504
7505 /*-----------------------------------------------------------------*/
7506 /* genRightShiftLiteral - right shifting by known count            */
7507 /*-----------------------------------------------------------------*/
7508 static void genRightShiftLiteral (operand *left,
7509                                   operand *right,
7510                                   operand *result,
7511                                   iCode *ic,
7512                                   int sign)
7513 {    
7514   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7515   int lsize,res_size;
7516
7517   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7518   freeAsmop(right,NULL,ic,TRUE);
7519
7520   aopOp(left,ic,FALSE);
7521   aopOp(result,ic,FALSE);
7522
7523 #if VIEW_SIZE
7524   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7525                  AOP_SIZE(left));
7526 #endif
7527
7528   lsize = pic14_getDataSize(left);
7529   res_size = pic14_getDataSize(result);
7530   /* test the LEFT size !!! */
7531
7532   /* I suppose that the left size >= result size */
7533   if(shCount == 0){
7534     while(res_size--)
7535       movLeft2Result(left, lsize, result, res_size);
7536   }
7537
7538   else if(shCount >= (lsize * 8)){
7539
7540     if(res_size == 1) {
7541       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7542       if(sign) {
7543         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7544         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7545       }
7546     } else {
7547
7548       if(sign) {
7549         emitpcode(POC_MOVLW, popGetLit(0));
7550         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551         emitpcode(POC_MOVLW, popGetLit(0xff));
7552         while(res_size--)
7553           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7554
7555       } else {
7556
7557         while(res_size--)
7558           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7559       }
7560     }
7561   } else {
7562
7563     switch (res_size) {
7564     case 1:
7565       genrshOne (result,left,shCount,sign);
7566       break;
7567
7568     case 2:
7569       genrshTwo (result,left,shCount,sign);
7570       break;
7571
7572     case 4:
7573       genrshFour (result,left,shCount,sign);
7574       break;
7575     default :
7576       break;
7577     }
7578
7579   }
7580
7581   freeAsmop(left,NULL,ic,TRUE);
7582   freeAsmop(result,NULL,ic,TRUE);
7583 }
7584
7585 /*-----------------------------------------------------------------*/
7586 /* genSignedRightShift - right shift of signed number              */
7587 /*-----------------------------------------------------------------*/
7588 static void genSignedRightShift (iCode *ic)
7589 {
7590   operand *right, *left, *result;
7591   int size, offset;
7592   //  char *l;
7593   symbol *tlbl, *tlbl1 ;
7594   pCodeOp *pctemp;
7595
7596   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7597
7598   /* we do it the hard way put the shift count in b
7599      and loop thru preserving the sign */
7600   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7601
7602   right = IC_RIGHT(ic);
7603   left  = IC_LEFT(ic);
7604   result = IC_RESULT(ic);
7605
7606   aopOp(right,ic,FALSE);  
7607   aopOp(left,ic,FALSE);
7608   aopOp(result,ic,FALSE);
7609
7610
7611   if ( AOP_TYPE(right) == AOP_LIT) {
7612     genRightShiftLiteral (left,right,result,ic,1);
7613     return ;
7614   }
7615   /* shift count is unknown then we have to form 
7616      a loop get the loop count in B : Note: we take
7617      only the lower order byte since shifting
7618      more that 32 bits make no sense anyway, ( the
7619      largest size of an object can be only 32 bits ) */  
7620
7621   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7622   //pic14_emitcode("inc","b");
7623   //freeAsmop (right,NULL,ic,TRUE);
7624   //aopOp(left,ic,FALSE);
7625   //aopOp(result,ic,FALSE);
7626
7627   /* now move the left to the result if they are not the
7628      same */
7629   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7630       AOP_SIZE(result) > 1) {
7631
7632     size = AOP_SIZE(result);
7633     offset=0;
7634     while (size--) { 
7635       /*
7636         l = aopGet(AOP(left),offset,FALSE,TRUE);
7637         if (*l == '@' && IS_AOP_PREG(result)) {
7638
7639         pic14_emitcode("mov","a,%s",l);
7640         aopPut(AOP(result),"a",offset);
7641         } else
7642         aopPut(AOP(result),l,offset);
7643       */
7644       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7645       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7646
7647       offset++;
7648     }
7649   }
7650
7651   /* mov the highest order bit to OVR */    
7652   tlbl = newiTempLabel(NULL);
7653   tlbl1= newiTempLabel(NULL);
7654
7655   size = AOP_SIZE(result);
7656   offset = size - 1;
7657
7658   pctemp = popGetTempReg();  /* grab a temporary working register. */
7659
7660   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7661
7662   /* offset should be 0, 1 or 3 */
7663   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7664   emitSKPNZ;
7665   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7666
7667   emitpcode(POC_MOVWF, pctemp);
7668
7669
7670   emitpLabel(tlbl->key);
7671
7672   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7673   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7674
7675   while(--size) {
7676     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7677   }
7678
7679   emitpcode(POC_DECFSZ,  pctemp);
7680   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7681   emitpLabel(tlbl1->key);
7682
7683   popReleaseTempReg(pctemp);
7684 #if 0
7685   size = AOP_SIZE(result);
7686   offset = size - 1;
7687   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7688   pic14_emitcode("rlc","a");
7689   pic14_emitcode("mov","ov,c");
7690   /* if it is only one byte then */
7691   if (size == 1) {
7692     l = aopGet(AOP(left),0,FALSE,FALSE);
7693     MOVA(l);
7694     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7695     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7696     pic14_emitcode("mov","c,ov");
7697     pic14_emitcode("rrc","a");
7698     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7699     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7700     aopPut(AOP(result),"a",0);
7701     goto release ;
7702   }
7703
7704   reAdjustPreg(AOP(result));
7705   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7707   pic14_emitcode("mov","c,ov");
7708   while (size--) {
7709     l = aopGet(AOP(result),offset,FALSE,FALSE);
7710     MOVA(l);
7711     pic14_emitcode("rrc","a");         
7712     aopPut(AOP(result),"a",offset--);
7713   }
7714   reAdjustPreg(AOP(result));
7715   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7717
7718  release:
7719 #endif
7720
7721   freeAsmop(left,NULL,ic,TRUE);
7722   freeAsmop(result,NULL,ic,TRUE);
7723   freeAsmop(right,NULL,ic,TRUE);
7724 }
7725
7726 /*-----------------------------------------------------------------*/
7727 /* genRightShift - generate code for right shifting                */
7728 /*-----------------------------------------------------------------*/
7729 static void genRightShift (iCode *ic)
7730 {
7731     operand *right, *left, *result;
7732     sym_link *retype ;
7733     int size, offset;
7734     char *l;
7735     symbol *tlbl, *tlbl1 ;
7736
7737     /* if signed then we do it the hard way preserve the
7738     sign bit moving it inwards */
7739     retype = getSpec(operandType(IC_RESULT(ic)));
7740     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7741
7742     if (!SPEC_USIGN(retype)) {
7743         genSignedRightShift (ic);
7744         return ;
7745     }
7746
7747     /* signed & unsigned types are treated the same : i.e. the
7748     signed is NOT propagated inwards : quoting from the
7749     ANSI - standard : "for E1 >> E2, is equivalent to division
7750     by 2**E2 if unsigned or if it has a non-negative value,
7751     otherwise the result is implementation defined ", MY definition
7752     is that the sign does not get propagated */
7753
7754     right = IC_RIGHT(ic);
7755     left  = IC_LEFT(ic);
7756     result = IC_RESULT(ic);
7757
7758     aopOp(right,ic,FALSE);
7759
7760     /* if the shift count is known then do it 
7761     as efficiently as possible */
7762     if (AOP_TYPE(right) == AOP_LIT) {
7763         genRightShiftLiteral (left,right,result,ic, 0);
7764         return ;
7765     }
7766
7767     /* shift count is unknown then we have to form 
7768     a loop get the loop count in B : Note: we take
7769     only the lower order byte since shifting
7770     more that 32 bits make no sense anyway, ( the
7771     largest size of an object can be only 32 bits ) */  
7772
7773     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7774     pic14_emitcode("inc","b");
7775     aopOp(left,ic,FALSE);
7776     aopOp(result,ic,FALSE);
7777
7778     /* now move the left to the result if they are not the
7779     same */
7780     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7781         AOP_SIZE(result) > 1) {
7782
7783         size = AOP_SIZE(result);
7784         offset=0;
7785         while (size--) {
7786             l = aopGet(AOP(left),offset,FALSE,TRUE);
7787             if (*l == '@' && IS_AOP_PREG(result)) {
7788
7789                 pic14_emitcode("mov","a,%s",l);
7790                 aopPut(AOP(result),"a",offset);
7791             } else
7792                 aopPut(AOP(result),l,offset);
7793             offset++;
7794         }
7795     }
7796
7797     tlbl = newiTempLabel(NULL);
7798     tlbl1= newiTempLabel(NULL);
7799     size = AOP_SIZE(result);
7800     offset = size - 1;
7801
7802     /* if it is only one byte then */
7803     if (size == 1) {
7804
7805       tlbl = newiTempLabel(NULL);
7806       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7807         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7808         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7809       }
7810
7811       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7812       emitpcode(POC_RLF,    popGet(AOP(result),0));
7813       emitpLabel(tlbl->key);
7814       emitpcode(POC_RRF,    popGet(AOP(result),0));
7815       emitpcode(POC_ADDLW,  popGetLit(1));
7816       emitSKPC;
7817       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7818
7819       goto release ;
7820     }
7821
7822     reAdjustPreg(AOP(result));
7823     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7824     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7825     CLRC;
7826     while (size--) {
7827         l = aopGet(AOP(result),offset,FALSE,FALSE);
7828         MOVA(l);
7829         pic14_emitcode("rrc","a");         
7830         aopPut(AOP(result),"a",offset--);
7831     }
7832     reAdjustPreg(AOP(result));
7833
7834     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7835     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7836
7837 release:
7838     freeAsmop(left,NULL,ic,TRUE);
7839     freeAsmop (right,NULL,ic,TRUE);
7840     freeAsmop(result,NULL,ic,TRUE);
7841 }
7842
7843 /*-----------------------------------------------------------------*/
7844 /* genUnpackBits - generates code for unpacking bits               */
7845 /*-----------------------------------------------------------------*/
7846 static void genUnpackBits (operand *result, char *rname, int ptype)
7847 {    
7848     int shCnt ;
7849     int rlen = 0 ;
7850     sym_link *etype;
7851     int offset = 0 ;
7852
7853     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7854     etype = getSpec(operandType(result));
7855
7856     /* read the first byte  */
7857     switch (ptype) {
7858
7859     case POINTER:
7860     case IPOINTER:
7861         pic14_emitcode("mov","a,@%s",rname);
7862         break;
7863         
7864     case PPOINTER:
7865         pic14_emitcode("movx","a,@%s",rname);
7866         break;
7867         
7868     case FPOINTER:
7869         pic14_emitcode("movx","a,@dptr");
7870         break;
7871
7872     case CPOINTER:
7873         pic14_emitcode("clr","a");
7874         pic14_emitcode("movc","a","@a+dptr");
7875         break;
7876
7877     case GPOINTER:
7878         pic14_emitcode("lcall","__gptrget");
7879         break;
7880     }
7881
7882     /* if we have bitdisplacement then it fits   */
7883     /* into this byte completely or if length is */
7884     /* less than a byte                          */
7885     if ((shCnt = SPEC_BSTR(etype)) || 
7886         (SPEC_BLEN(etype) <= 8))  {
7887
7888         /* shift right acc */
7889         AccRsh(shCnt);
7890
7891         pic14_emitcode("anl","a,#0x%02x",
7892                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7893         aopPut(AOP(result),"a",offset);
7894         return ;
7895     }
7896
7897     /* bit field did not fit in a byte  */
7898     rlen = SPEC_BLEN(etype) - 8;
7899     aopPut(AOP(result),"a",offset++);
7900
7901     while (1)  {
7902
7903         switch (ptype) {
7904         case POINTER:
7905         case IPOINTER:
7906             pic14_emitcode("inc","%s",rname);
7907             pic14_emitcode("mov","a,@%s",rname);
7908             break;
7909             
7910         case PPOINTER:
7911             pic14_emitcode("inc","%s",rname);
7912             pic14_emitcode("movx","a,@%s",rname);
7913             break;
7914
7915         case FPOINTER:
7916             pic14_emitcode("inc","dptr");
7917             pic14_emitcode("movx","a,@dptr");
7918             break;
7919             
7920         case CPOINTER:
7921             pic14_emitcode("clr","a");
7922             pic14_emitcode("inc","dptr");
7923             pic14_emitcode("movc","a","@a+dptr");
7924             break;
7925             
7926         case GPOINTER:
7927             pic14_emitcode("inc","dptr");
7928             pic14_emitcode("lcall","__gptrget");
7929             break;
7930         }
7931
7932         rlen -= 8;            
7933         /* if we are done */
7934         if ( rlen <= 0 )
7935             break ;
7936         
7937         aopPut(AOP(result),"a",offset++);
7938                               
7939     }
7940     
7941     if (rlen) {
7942         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7943         aopPut(AOP(result),"a",offset);        
7944     }
7945     
7946     return ;
7947 }
7948
7949 #if 0
7950 /*-----------------------------------------------------------------*/
7951 /* genDataPointerGet - generates code when ptr offset is known     */
7952 /*-----------------------------------------------------------------*/
7953 static void genDataPointerGet (operand *left, 
7954                                operand *result, 
7955                                iCode *ic)
7956 {
7957   int size , offset = 0;
7958
7959
7960   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7961
7962
7963   /* optimization - most of the time, left and result are the same
7964    * address, but different types. for the pic code, we could omit
7965    * the following
7966    */
7967
7968   aopOp(result,ic,TRUE);
7969
7970   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7971
7972   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7973
7974   size = AOP_SIZE(result);
7975
7976   while (size--) {
7977     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7978     offset++;
7979   }
7980
7981   freeAsmop(left,NULL,ic,TRUE);
7982   freeAsmop(result,NULL,ic,TRUE);
7983 }
7984 #endif
7985 /*-----------------------------------------------------------------*/
7986 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7987 /*-----------------------------------------------------------------*/
7988 static void genNearPointerGet (operand *left, 
7989                                operand *result, 
7990                                iCode *ic)
7991 {
7992     asmop *aop = NULL;
7993     //regs *preg = NULL ;
7994     char *rname ;
7995     sym_link *rtype, *retype;
7996     sym_link *ltype = operandType(left);    
7997     //char buffer[80];
7998
7999     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8000
8001     rtype = operandType(result);
8002     retype= getSpec(rtype);
8003     
8004     aopOp(left,ic,FALSE);
8005     
8006     /* if left is rematerialisable and
8007        result is not bit variable type and
8008        the left is pointer to data space i.e
8009        lower 128 bytes of space */
8010     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8011         !IS_BITVAR(retype)         &&
8012         DCL_TYPE(ltype) == POINTER) {
8013       //genDataPointerGet (left,result,ic);
8014         return ;
8015     }
8016     
8017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8018
8019         /* if the value is already in a pointer register
8020        then don't need anything more */
8021     if (!AOP_INPREG(AOP(left))) {
8022         /* otherwise get a free pointer register */
8023     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8024 /*
8025         aop = newAsmop(0);
8026         preg = getFreePtr(ic,&aop,FALSE);
8027         pic14_emitcode("mov","%s,%s",
8028                 preg->name,
8029                 aopGet(AOP(left),0,FALSE,TRUE));
8030         rname = preg->name ;
8031 */
8032     rname ="BAD";
8033     } else
8034         rname = aopGet(AOP(left),0,FALSE,FALSE);
8035     
8036     aopOp (result,ic,FALSE);
8037     
8038       /* if bitfield then unpack the bits */
8039     if (IS_BITVAR(retype)) 
8040         genUnpackBits (result,rname,POINTER);
8041     else {
8042         /* we have can just get the values */
8043       int size = AOP_SIZE(result);
8044       int offset = 0 ;  
8045         
8046       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8047
8048       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8049       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8050       while(size--) {
8051         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8052         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8053         if(size)
8054           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8055       }
8056 /*
8057         while (size--) {
8058             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8059
8060                 pic14_emitcode("mov","a,@%s",rname);
8061                 aopPut(AOP(result),"a",offset);
8062             } else {
8063                 sprintf(buffer,"@%s",rname);
8064                 aopPut(AOP(result),buffer,offset);
8065             }
8066             offset++ ;
8067             if (size)
8068                 pic14_emitcode("inc","%s",rname);
8069         }
8070 */
8071     }
8072
8073     /* now some housekeeping stuff */
8074     if (aop) {
8075         /* we had to allocate for this iCode */
8076     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8077         freeAsmop(NULL,aop,ic,TRUE);
8078     } else { 
8079         /* we did not allocate which means left
8080            already in a pointer register, then
8081            if size > 0 && this could be used again
8082            we have to point it back to where it 
8083            belongs */
8084     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8085         if (AOP_SIZE(result) > 1 &&
8086             !OP_SYMBOL(left)->remat &&
8087             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8088               ic->depth )) {
8089             int size = AOP_SIZE(result) - 1;
8090             while (size--)
8091                 pic14_emitcode("dec","%s",rname);
8092         }
8093     }
8094
8095     /* done */
8096     freeAsmop(left,NULL,ic,TRUE);
8097     freeAsmop(result,NULL,ic,TRUE);
8098      
8099 }
8100
8101 /*-----------------------------------------------------------------*/
8102 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8103 /*-----------------------------------------------------------------*/
8104 static void genPagedPointerGet (operand *left, 
8105                                operand *result, 
8106                                iCode *ic)
8107 {
8108     asmop *aop = NULL;
8109     regs *preg = NULL ;
8110     char *rname ;
8111     sym_link *rtype, *retype;    
8112
8113     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8114
8115     rtype = operandType(result);
8116     retype= getSpec(rtype);
8117     
8118     aopOp(left,ic,FALSE);
8119
8120   /* if the value is already in a pointer register
8121        then don't need anything more */
8122     if (!AOP_INPREG(AOP(left))) {
8123         /* otherwise get a free pointer register */
8124         aop = newAsmop(0);
8125         preg = getFreePtr(ic,&aop,FALSE);
8126         pic14_emitcode("mov","%s,%s",
8127                 preg->name,
8128                 aopGet(AOP(left),0,FALSE,TRUE));
8129         rname = preg->name ;
8130     } else
8131         rname = aopGet(AOP(left),0,FALSE,FALSE);
8132     
8133     freeAsmop(left,NULL,ic,TRUE);
8134     aopOp (result,ic,FALSE);
8135
8136     /* if bitfield then unpack the bits */
8137     if (IS_BITVAR(retype)) 
8138         genUnpackBits (result,rname,PPOINTER);
8139     else {
8140         /* we have can just get the values */
8141         int size = AOP_SIZE(result);
8142         int offset = 0 ;        
8143         
8144         while (size--) {
8145             
8146             pic14_emitcode("movx","a,@%s",rname);
8147             aopPut(AOP(result),"a",offset);
8148             
8149             offset++ ;
8150             
8151             if (size)
8152                 pic14_emitcode("inc","%s",rname);
8153         }
8154     }
8155
8156     /* now some housekeeping stuff */
8157     if (aop) {
8158         /* we had to allocate for this iCode */
8159         freeAsmop(NULL,aop,ic,TRUE);
8160     } else { 
8161         /* we did not allocate which means left
8162            already in a pointer register, then
8163            if size > 0 && this could be used again
8164            we have to point it back to where it 
8165            belongs */
8166         if (AOP_SIZE(result) > 1 &&
8167             !OP_SYMBOL(left)->remat &&
8168             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8169               ic->depth )) {
8170             int size = AOP_SIZE(result) - 1;
8171             while (size--)
8172                 pic14_emitcode("dec","%s",rname);
8173         }
8174     }
8175
8176     /* done */
8177     freeAsmop(result,NULL,ic,TRUE);
8178     
8179         
8180 }
8181
8182 /*-----------------------------------------------------------------*/
8183 /* genFarPointerGet - gget value from far space                    */
8184 /*-----------------------------------------------------------------*/
8185 static void genFarPointerGet (operand *left,
8186                               operand *result, iCode *ic)
8187 {
8188     int size, offset ;
8189     sym_link *retype = getSpec(operandType(result));
8190
8191     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8192
8193     aopOp(left,ic,FALSE);
8194
8195     /* if the operand is already in dptr 
8196     then we do nothing else we move the value to dptr */
8197     if (AOP_TYPE(left) != AOP_STR) {
8198         /* if this is remateriazable */
8199         if (AOP_TYPE(left) == AOP_IMMD)
8200             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201         else { /* we need to get it byte by byte */
8202             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204             if (options.model == MODEL_FLAT24)
8205             {
8206                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8207             }
8208         }
8209     }
8210     /* so dptr know contains the address */
8211     freeAsmop(left,NULL,ic,TRUE);
8212     aopOp(result,ic,FALSE);
8213
8214     /* if bit then unpack */
8215     if (IS_BITVAR(retype)) 
8216         genUnpackBits(result,"dptr",FPOINTER);
8217     else {
8218         size = AOP_SIZE(result);
8219         offset = 0 ;
8220
8221         while (size--) {
8222             pic14_emitcode("movx","a,@dptr");
8223             aopPut(AOP(result),"a",offset++);
8224             if (size)
8225                 pic14_emitcode("inc","dptr");
8226         }
8227     }
8228
8229     freeAsmop(result,NULL,ic,TRUE);
8230 }
8231 #if 0
8232 /*-----------------------------------------------------------------*/
8233 /* genCodePointerGet - get value from code space                  */
8234 /*-----------------------------------------------------------------*/
8235 static void genCodePointerGet (operand *left,
8236                                 operand *result, iCode *ic)
8237 {
8238     int size, offset ;
8239     sym_link *retype = getSpec(operandType(result));
8240
8241     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8242
8243     aopOp(left,ic,FALSE);
8244
8245     /* if the operand is already in dptr 
8246     then we do nothing else we move the value to dptr */
8247     if (AOP_TYPE(left) != AOP_STR) {
8248         /* if this is remateriazable */
8249         if (AOP_TYPE(left) == AOP_IMMD)
8250             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8251         else { /* we need to get it byte by byte */
8252             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8253             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8254             if (options.model == MODEL_FLAT24)
8255             {
8256                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8257             }
8258         }
8259     }
8260     /* so dptr know contains the address */
8261     freeAsmop(left,NULL,ic,TRUE);
8262     aopOp(result,ic,FALSE);
8263
8264     /* if bit then unpack */
8265     if (IS_BITVAR(retype)) 
8266         genUnpackBits(result,"dptr",CPOINTER);
8267     else {
8268         size = AOP_SIZE(result);
8269         offset = 0 ;
8270
8271         while (size--) {
8272             pic14_emitcode("clr","a");
8273             pic14_emitcode("movc","a,@a+dptr");
8274             aopPut(AOP(result),"a",offset++);
8275             if (size)
8276                 pic14_emitcode("inc","dptr");
8277         }
8278     }
8279
8280     freeAsmop(result,NULL,ic,TRUE);
8281 }
8282 #endif
8283 /*-----------------------------------------------------------------*/
8284 /* genGenPointerGet - gget value from generic pointer space        */
8285 /*-----------------------------------------------------------------*/
8286 static void genGenPointerGet (operand *left,
8287                               operand *result, iCode *ic)
8288 {
8289   int size, offset ;
8290   sym_link *retype = getSpec(operandType(result));
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   /* if the operand is already in dptr 
8300      then we do nothing else we move the value to dptr */
8301   //  if (AOP_TYPE(left) != AOP_STR) {
8302     /* if this is remateriazable */
8303     if (AOP_TYPE(left) == AOP_IMMD) {
8304       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8305       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8306     }
8307     else { /* we need to get it byte by byte */
8308
8309       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8310       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8311
8312       size = AOP_SIZE(result);
8313       offset = 0 ;
8314
8315       while(size--) {
8316         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8317         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8318         if(size)
8319           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8320       }
8321       goto release;
8322     }
8323     //}
8324   /* so dptr know contains the address */
8325
8326   /* if bit then unpack */
8327   //if (IS_BITVAR(retype)) 
8328   //  genUnpackBits(result,"dptr",GPOINTER);
8329
8330  release:
8331   freeAsmop(left,NULL,ic,TRUE);
8332   freeAsmop(result,NULL,ic,TRUE);
8333
8334 }
8335
8336 /*-----------------------------------------------------------------*/
8337 /* genConstPointerGet - get value from const generic pointer space */
8338 /*-----------------------------------------------------------------*/
8339 static void genConstPointerGet (operand *left,
8340                                 operand *result, iCode *ic)
8341 {
8342   //sym_link *retype = getSpec(operandType(result));
8343   symbol *albl = newiTempLabel(NULL);
8344   symbol *blbl = newiTempLabel(NULL);
8345   PIC_OPCODE poc;
8346
8347   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8348   aopOp(left,ic,FALSE);
8349   aopOp(result,ic,FALSE);
8350
8351
8352   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8353
8354   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8355
8356   emitpcode(POC_CALL,popGetLabel(albl->key));
8357   emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
8358   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8359   emitpLabel(albl->key);
8360
8361   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8362     
8363   emitpcode(poc,popGet(AOP(left),1));
8364   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8365   emitpcode(poc,popGet(AOP(left),0));
8366   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8367
8368   emitpLabel(blbl->key);
8369
8370   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8371
8372
8373   freeAsmop(left,NULL,ic,TRUE);
8374   freeAsmop(result,NULL,ic,TRUE);
8375
8376 }
8377 /*-----------------------------------------------------------------*/
8378 /* genPointerGet - generate code for pointer get                   */
8379 /*-----------------------------------------------------------------*/
8380 static void genPointerGet (iCode *ic)
8381 {
8382     operand *left, *result ;
8383     sym_link *type, *etype;
8384     int p_type;
8385
8386     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8387
8388     left = IC_LEFT(ic);
8389     result = IC_RESULT(ic) ;
8390
8391     /* depending on the type of pointer we need to
8392     move it to the correct pointer register */
8393     type = operandType(left);
8394     etype = getSpec(type);
8395
8396     if (IS_PTR_CONST(type))
8397       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8398
8399     /* if left is of type of pointer then it is simple */
8400     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8401         p_type = DCL_TYPE(type);
8402     else {
8403         /* we have to go by the storage class */
8404         p_type = PTR_TYPE(SPEC_OCLS(etype));
8405
8406         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8407
8408         if (SPEC_OCLS(etype)->codesp ) {
8409           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8410           //p_type = CPOINTER ; 
8411         }
8412         else
8413             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8414               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8415                /*p_type = FPOINTER ;*/ 
8416             else
8417                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8418                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8419 /*                  p_type = PPOINTER; */
8420                 else
8421                     if (SPEC_OCLS(etype) == idata )
8422                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8423 /*                      p_type = IPOINTER; */
8424                     else
8425                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8426 /*                      p_type = POINTER ; */
8427     }
8428
8429     /* now that we have the pointer type we assign
8430     the pointer values */
8431     switch (p_type) {
8432
8433     case POINTER:       
8434     case IPOINTER:
8435         genNearPointerGet (left,result,ic);
8436         break;
8437
8438     case PPOINTER:
8439         genPagedPointerGet(left,result,ic);
8440         break;
8441
8442     case FPOINTER:
8443         genFarPointerGet (left,result,ic);
8444         break;
8445
8446     case CPOINTER:
8447         genConstPointerGet (left,result,ic);
8448         //pic14_emitcodePointerGet (left,result,ic);
8449         break;
8450
8451     case GPOINTER:
8452       if (IS_PTR_CONST(type))
8453         genConstPointerGet (left,result,ic);
8454       else
8455         genGenPointerGet (left,result,ic);
8456       break;
8457     }
8458
8459 }
8460
8461 /*-----------------------------------------------------------------*/
8462 /* genPackBits - generates code for packed bit storage             */
8463 /*-----------------------------------------------------------------*/
8464 static void genPackBits (sym_link    *etype ,
8465                          operand *right ,
8466                          char *rname, int p_type)
8467 {
8468     int shCount = 0 ;
8469     int offset = 0  ;
8470     int rLen = 0 ;
8471     int blen, bstr ;   
8472     char *l ;
8473
8474     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8475     blen = SPEC_BLEN(etype);
8476     bstr = SPEC_BSTR(etype);
8477
8478     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8479     MOVA(l);   
8480
8481     /* if the bit lenth is less than or    */
8482     /* it exactly fits a byte then         */
8483     if (SPEC_BLEN(etype) <= 8 )  {
8484         shCount = SPEC_BSTR(etype) ;
8485
8486         /* shift left acc */
8487         AccLsh(shCount);
8488
8489         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8490
8491
8492             switch (p_type) {
8493                 case POINTER:
8494                     pic14_emitcode ("mov","b,a");
8495                     pic14_emitcode("mov","a,@%s",rname);
8496                     break;
8497
8498                 case FPOINTER:
8499                     pic14_emitcode ("mov","b,a");
8500                     pic14_emitcode("movx","a,@dptr");
8501                     break;
8502
8503                 case GPOINTER:
8504                     pic14_emitcode ("push","b");
8505                     pic14_emitcode ("push","acc");
8506                     pic14_emitcode ("lcall","__gptrget");
8507                     pic14_emitcode ("pop","b");
8508                     break;
8509             }
8510
8511             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8512                       ((unsigned char)(0xFF << (blen+bstr)) | 
8513                        (unsigned char)(0xFF >> (8-bstr)) ) );
8514             pic14_emitcode ("orl","a,b");
8515             if (p_type == GPOINTER)
8516                 pic14_emitcode("pop","b");
8517         }
8518     }
8519
8520     switch (p_type) {
8521         case POINTER:
8522             pic14_emitcode("mov","@%s,a",rname);
8523             break;
8524
8525         case FPOINTER:
8526             pic14_emitcode("movx","@dptr,a");
8527             break;
8528
8529         case GPOINTER:
8530             DEBUGpic14_emitcode(";lcall","__gptrput");
8531             break;
8532     }
8533
8534     /* if we r done */
8535     if ( SPEC_BLEN(etype) <= 8 )
8536         return ;
8537
8538     pic14_emitcode("inc","%s",rname);
8539     rLen = SPEC_BLEN(etype) ;     
8540
8541     /* now generate for lengths greater than one byte */
8542     while (1) {
8543
8544         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8545
8546         rLen -= 8 ;
8547         if (rLen <= 0 )
8548             break ;
8549
8550         switch (p_type) {
8551             case POINTER:
8552                 if (*l == '@') {
8553                     MOVA(l);
8554                     pic14_emitcode("mov","@%s,a",rname);
8555                 } else
8556                     pic14_emitcode("mov","@%s,%s",rname,l);
8557                 break;
8558
8559             case FPOINTER:
8560                 MOVA(l);
8561                 pic14_emitcode("movx","@dptr,a");
8562                 break;
8563
8564             case GPOINTER:
8565                 MOVA(l);
8566                 DEBUGpic14_emitcode(";lcall","__gptrput");
8567                 break;  
8568         }   
8569         pic14_emitcode ("inc","%s",rname);
8570     }
8571
8572     MOVA(l);
8573
8574     /* last last was not complete */
8575     if (rLen)   {
8576         /* save the byte & read byte */
8577         switch (p_type) {
8578             case POINTER:
8579                 pic14_emitcode ("mov","b,a");
8580                 pic14_emitcode("mov","a,@%s",rname);
8581                 break;
8582
8583             case FPOINTER:
8584                 pic14_emitcode ("mov","b,a");
8585                 pic14_emitcode("movx","a,@dptr");
8586                 break;
8587
8588             case GPOINTER:
8589                 pic14_emitcode ("push","b");
8590                 pic14_emitcode ("push","acc");
8591                 pic14_emitcode ("lcall","__gptrget");
8592                 pic14_emitcode ("pop","b");
8593                 break;
8594         }
8595
8596         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8597         pic14_emitcode ("orl","a,b");
8598     }
8599
8600     if (p_type == GPOINTER)
8601         pic14_emitcode("pop","b");
8602
8603     switch (p_type) {
8604
8605     case POINTER:
8606         pic14_emitcode("mov","@%s,a",rname);
8607         break;
8608         
8609     case FPOINTER:
8610         pic14_emitcode("movx","@dptr,a");
8611         break;
8612         
8613     case GPOINTER:
8614         DEBUGpic14_emitcode(";lcall","__gptrput");
8615         break;                  
8616     }
8617 }
8618 /*-----------------------------------------------------------------*/
8619 /* genDataPointerSet - remat pointer to data space                 */
8620 /*-----------------------------------------------------------------*/
8621 static void genDataPointerSet(operand *right,
8622                               operand *result,
8623                               iCode *ic)
8624 {
8625     int size, offset = 0 ;
8626     char *l, buffer[256];
8627
8628     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8629     aopOp(right,ic,FALSE);
8630     
8631     l = aopGet(AOP(result),0,FALSE,TRUE);
8632     size = AOP_SIZE(right);
8633 /*
8634     if ( AOP_TYPE(result) == AOP_PCODE) {
8635       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8636               AOP(result)->aopu.pcop->name,
8637               PCOI(AOP(result)->aopu.pcop)->offset);
8638     }
8639 */
8640
8641     // tsd, was l+1 - the underline `_' prefix was being stripped
8642     while (size--) {
8643       if (offset) {
8644         sprintf(buffer,"(%s + %d)",l,offset);
8645         fprintf(stderr,"oops  %s\n",buffer);
8646       } else
8647         sprintf(buffer,"%s",l);
8648
8649         if (AOP_TYPE(right) == AOP_LIT) {
8650           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8651           lit = lit >> (8*offset);
8652           if(lit&0xff) {
8653             pic14_emitcode("movlw","%d",lit);
8654             pic14_emitcode("movwf","%s",buffer);
8655
8656             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8657             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8658             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8659
8660           } else {
8661             pic14_emitcode("clrf","%s",buffer);
8662             //emitpcode(POC_CLRF, popRegFromString(buffer));
8663             emitpcode(POC_CLRF, popGet(AOP(result),0));
8664           }
8665         }else {
8666           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8667           pic14_emitcode("movwf","%s",buffer);
8668
8669           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8670           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8671           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8672
8673         }
8674
8675         offset++;
8676     }
8677
8678     freeAsmop(right,NULL,ic,TRUE);
8679     freeAsmop(result,NULL,ic,TRUE);
8680 }
8681
8682 /*-----------------------------------------------------------------*/
8683 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8684 /*-----------------------------------------------------------------*/
8685 static void genNearPointerSet (operand *right,
8686                                operand *result, 
8687                                iCode *ic)
8688 {
8689   asmop *aop = NULL;
8690   char *l;
8691   sym_link *retype;
8692   sym_link *ptype = operandType(result);
8693
8694     
8695   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8696   retype= getSpec(operandType(right));
8697
8698   aopOp(result,ic,FALSE);
8699
8700     
8701   /* if the result is rematerializable &
8702      in data space & not a bit variable */
8703   //if (AOP_TYPE(result) == AOP_IMMD &&
8704   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8705       DCL_TYPE(ptype) == POINTER   &&
8706       !IS_BITVAR(retype)) {
8707     genDataPointerSet (right,result,ic);
8708     freeAsmop(result,NULL,ic,TRUE);
8709     return;
8710   }
8711
8712   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8713   aopOp(right,ic,FALSE);
8714   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8715
8716   /* if the value is already in a pointer register
8717      then don't need anything more */
8718   if (!AOP_INPREG(AOP(result))) {
8719     /* otherwise get a free pointer register */
8720     //aop = newAsmop(0);
8721     //preg = getFreePtr(ic,&aop,FALSE);
8722     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8723     //pic14_emitcode("mov","%s,%s",
8724     //         preg->name,
8725     //         aopGet(AOP(result),0,FALSE,TRUE));
8726     //rname = preg->name ;
8727     //pic14_emitcode("movwf","fsr");
8728     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8729     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8730     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8731     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8732     goto release;
8733
8734   }// else
8735   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8736
8737
8738   /* if bitfield then unpack the bits */
8739   if (IS_BITVAR(retype)) {
8740     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8741            "The programmer is obviously confused");
8742     //genPackBits (retype,right,rname,POINTER);
8743     exit(1);
8744   }
8745   else {
8746     /* we have can just get the values */
8747     int size = AOP_SIZE(right);
8748     int offset = 0 ;    
8749
8750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8751     while (size--) {
8752       l = aopGet(AOP(right),offset,FALSE,TRUE);
8753       if (*l == '@' ) {
8754         //MOVA(l);
8755         //pic14_emitcode("mov","@%s,a",rname);
8756         pic14_emitcode("movf","indf,w ;1");
8757       } else {
8758
8759         if (AOP_TYPE(right) == AOP_LIT) {
8760           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8761           if(lit) {
8762             pic14_emitcode("movlw","%s",l);
8763             pic14_emitcode("movwf","indf ;2");
8764           } else 
8765             pic14_emitcode("clrf","indf");
8766         }else {
8767           pic14_emitcode("movf","%s,w",l);
8768           pic14_emitcode("movwf","indf ;2");
8769         }
8770         //pic14_emitcode("mov","@%s,%s",rname,l);
8771       }
8772       if (size)
8773         pic14_emitcode("incf","fsr,f ;3");
8774       //pic14_emitcode("inc","%s",rname);
8775       offset++;
8776     }
8777   }
8778
8779   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8780   /* now some housekeeping stuff */
8781   if (aop) {
8782     /* we had to allocate for this iCode */
8783     freeAsmop(NULL,aop,ic,TRUE);
8784   } else { 
8785     /* we did not allocate which means left
8786        already in a pointer register, then
8787        if size > 0 && this could be used again
8788        we have to point it back to where it 
8789        belongs */
8790     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8791     if (AOP_SIZE(right) > 1 &&
8792         !OP_SYMBOL(result)->remat &&
8793         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8794           ic->depth )) {
8795       int size = AOP_SIZE(right) - 1;
8796       while (size--)
8797         pic14_emitcode("decf","fsr,f");
8798       //pic14_emitcode("dec","%s",rname);
8799     }
8800   }
8801
8802   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8803   /* done */
8804  release:
8805   freeAsmop(right,NULL,ic,TRUE);
8806   freeAsmop(result,NULL,ic,TRUE);
8807 }
8808
8809 /*-----------------------------------------------------------------*/
8810 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8811 /*-----------------------------------------------------------------*/
8812 static void genPagedPointerSet (operand *right,
8813                                operand *result, 
8814                                iCode *ic)
8815 {
8816     asmop *aop = NULL;
8817     regs *preg = NULL ;
8818     char *rname , *l;
8819     sym_link *retype;
8820        
8821     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8822
8823     retype= getSpec(operandType(right));
8824     
8825     aopOp(result,ic,FALSE);
8826     
8827     /* if the value is already in a pointer register
8828        then don't need anything more */
8829     if (!AOP_INPREG(AOP(result))) {
8830         /* otherwise get a free pointer register */
8831         aop = newAsmop(0);
8832         preg = getFreePtr(ic,&aop,FALSE);
8833         pic14_emitcode("mov","%s,%s",
8834                 preg->name,
8835                 aopGet(AOP(result),0,FALSE,TRUE));
8836         rname = preg->name ;
8837     } else
8838         rname = aopGet(AOP(result),0,FALSE,FALSE);
8839     
8840     freeAsmop(result,NULL,ic,TRUE);
8841     aopOp (right,ic,FALSE);
8842
8843     /* if bitfield then unpack the bits */
8844     if (IS_BITVAR(retype)) 
8845         genPackBits (retype,right,rname,PPOINTER);
8846     else {
8847         /* we have can just get the values */
8848         int size = AOP_SIZE(right);
8849         int offset = 0 ;        
8850         
8851         while (size--) {
8852             l = aopGet(AOP(right),offset,FALSE,TRUE);
8853             
8854             MOVA(l);
8855             pic14_emitcode("movx","@%s,a",rname);
8856
8857             if (size)
8858                 pic14_emitcode("inc","%s",rname);
8859
8860             offset++;
8861         }
8862     }
8863     
8864     /* now some housekeeping stuff */
8865     if (aop) {
8866         /* we had to allocate for this iCode */
8867         freeAsmop(NULL,aop,ic,TRUE);
8868     } else { 
8869         /* we did not allocate which means left
8870            already in a pointer register, then
8871            if size > 0 && this could be used again
8872            we have to point it back to where it 
8873            belongs */
8874         if (AOP_SIZE(right) > 1 &&
8875             !OP_SYMBOL(result)->remat &&
8876             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8877               ic->depth )) {
8878             int size = AOP_SIZE(right) - 1;
8879             while (size--)
8880                 pic14_emitcode("dec","%s",rname);
8881         }
8882     }
8883
8884     /* done */
8885     freeAsmop(right,NULL,ic,TRUE);
8886     
8887         
8888 }
8889
8890 /*-----------------------------------------------------------------*/
8891 /* genFarPointerSet - set value from far space                     */
8892 /*-----------------------------------------------------------------*/
8893 static void genFarPointerSet (operand *right,
8894                               operand *result, iCode *ic)
8895 {
8896     int size, offset ;
8897     sym_link *retype = getSpec(operandType(right));
8898
8899     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8900     aopOp(result,ic,FALSE);
8901
8902     /* if the operand is already in dptr 
8903     then we do nothing else we move the value to dptr */
8904     if (AOP_TYPE(result) != AOP_STR) {
8905         /* if this is remateriazable */
8906         if (AOP_TYPE(result) == AOP_IMMD)
8907             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8908         else { /* we need to get it byte by byte */
8909             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8910             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8911             if (options.model == MODEL_FLAT24)
8912             {
8913                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8914             }
8915         }
8916     }
8917     /* so dptr know contains the address */
8918     freeAsmop(result,NULL,ic,TRUE);
8919     aopOp(right,ic,FALSE);
8920
8921     /* if bit then unpack */
8922     if (IS_BITVAR(retype)) 
8923         genPackBits(retype,right,"dptr",FPOINTER);
8924     else {
8925         size = AOP_SIZE(right);
8926         offset = 0 ;
8927
8928         while (size--) {
8929             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8930             MOVA(l);
8931             pic14_emitcode("movx","@dptr,a");
8932             if (size)
8933                 pic14_emitcode("inc","dptr");
8934         }
8935     }
8936
8937     freeAsmop(right,NULL,ic,TRUE);
8938 }
8939
8940 /*-----------------------------------------------------------------*/
8941 /* genGenPointerSet - set value from generic pointer space         */
8942 /*-----------------------------------------------------------------*/
8943 static void genGenPointerSet (operand *right,
8944                               operand *result, iCode *ic)
8945 {
8946   int size, offset ;
8947   sym_link *retype = getSpec(operandType(right));
8948
8949   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8950
8951   aopOp(result,ic,FALSE);
8952   aopOp(right,ic,FALSE);
8953   size = AOP_SIZE(right);
8954
8955   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8956
8957   /* if the operand is already in dptr 
8958      then we do nothing else we move the value to dptr */
8959   if (AOP_TYPE(result) != AOP_STR) {
8960     /* if this is remateriazable */
8961     if (AOP_TYPE(result) == AOP_IMMD) {
8962       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8963       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8964     }
8965     else { /* we need to get it byte by byte */
8966       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8967       size = AOP_SIZE(right);
8968       offset = 0 ;
8969
8970       /* hack hack! see if this the FSR. If so don't load W */
8971       if(AOP_TYPE(right) != AOP_ACC) {
8972
8973
8974         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8975         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8976
8977         if(AOP_SIZE(result) > 1) {
8978           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8979           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8980           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8981
8982         }
8983
8984         //if(size==2)
8985         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8986         //if(size==4) {
8987         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8988         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8989         //}
8990
8991         while(size--) {
8992           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8993           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8994           
8995           if(size)
8996             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8997         }
8998
8999
9000         goto release;
9001       } 
9002
9003       if(aopIdx(AOP(result),0) != 4) {
9004
9005         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9006         goto release;
9007       }
9008
9009       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9010       goto release;
9011
9012     }
9013   }
9014   /* so dptr know contains the address */
9015
9016
9017   /* if bit then unpack */
9018   if (IS_BITVAR(retype)) 
9019     genPackBits(retype,right,"dptr",GPOINTER);
9020   else {
9021     size = AOP_SIZE(right);
9022     offset = 0 ;
9023
9024   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9025
9026     while (size--) {
9027
9028       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9029       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9030
9031       if (AOP_TYPE(right) == AOP_LIT) 
9032         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9033       else
9034         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9035
9036       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9037
9038       offset++;
9039     }
9040   }
9041
9042  release:
9043   freeAsmop(right,NULL,ic,TRUE);
9044   freeAsmop(result,NULL,ic,TRUE);
9045 }
9046
9047 /*-----------------------------------------------------------------*/
9048 /* genPointerSet - stores the value into a pointer location        */
9049 /*-----------------------------------------------------------------*/
9050 static void genPointerSet (iCode *ic)
9051 {    
9052     operand *right, *result ;
9053     sym_link *type, *etype;
9054     int p_type;
9055
9056     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9057
9058     right = IC_RIGHT(ic);
9059     result = IC_RESULT(ic) ;
9060
9061     /* depending on the type of pointer we need to
9062     move it to the correct pointer register */
9063     type = operandType(result);
9064     etype = getSpec(type);
9065     /* if left is of type of pointer then it is simple */
9066     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9067         p_type = DCL_TYPE(type);
9068     }
9069     else {
9070         /* we have to go by the storage class */
9071         p_type = PTR_TYPE(SPEC_OCLS(etype));
9072
9073 /*      if (SPEC_OCLS(etype)->codesp ) { */
9074 /*          p_type = CPOINTER ;  */
9075 /*      } */
9076 /*      else */
9077 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9078 /*              p_type = FPOINTER ; */
9079 /*          else */
9080 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9081 /*                  p_type = PPOINTER ; */
9082 /*              else */
9083 /*                  if (SPEC_OCLS(etype) == idata ) */
9084 /*                      p_type = IPOINTER ; */
9085 /*                  else */
9086 /*                      p_type = POINTER ; */
9087     }
9088
9089     /* now that we have the pointer type we assign
9090     the pointer values */
9091     switch (p_type) {
9092
9093     case POINTER:
9094     case IPOINTER:
9095         genNearPointerSet (right,result,ic);
9096         break;
9097
9098     case PPOINTER:
9099         genPagedPointerSet (right,result,ic);
9100         break;
9101
9102     case FPOINTER:
9103         genFarPointerSet (right,result,ic);
9104         break;
9105
9106     case GPOINTER:
9107         genGenPointerSet (right,result,ic);
9108         break;
9109
9110     default:
9111       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9112               "genPointerSet: illegal pointer type");
9113     }
9114 }
9115
9116 /*-----------------------------------------------------------------*/
9117 /* genIfx - generate code for Ifx statement                        */
9118 /*-----------------------------------------------------------------*/
9119 static void genIfx (iCode *ic, iCode *popIc)
9120 {
9121   operand *cond = IC_COND(ic);
9122   int isbit =0;
9123
9124   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9125
9126   aopOp(cond,ic,FALSE);
9127
9128   /* get the value into acc */
9129   if (AOP_TYPE(cond) != AOP_CRY)
9130     pic14_toBoolean(cond);
9131   else
9132     isbit = 1;
9133   /* the result is now in the accumulator */
9134   freeAsmop(cond,NULL,ic,TRUE);
9135
9136   /* if there was something to be popped then do it */
9137   if (popIc)
9138     genIpop(popIc);
9139
9140   /* if the condition is  a bit variable */
9141   if (isbit && IS_ITEMP(cond) && 
9142       SPIL_LOC(cond)) {
9143     genIfxJump(ic,SPIL_LOC(cond)->rname);
9144     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9145   }
9146   else {
9147     if (isbit && !IS_ITEMP(cond))
9148       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9149     else
9150       genIfxJump(ic,"a");
9151   }
9152   ic->generated = 1;
9153
9154 }
9155
9156 /*-----------------------------------------------------------------*/
9157 /* genAddrOf - generates code for address of                       */
9158 /*-----------------------------------------------------------------*/
9159 static void genAddrOf (iCode *ic)
9160 {
9161   operand *right, *result, *left;
9162   int size, offset ;
9163
9164   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9165
9166
9167   //aopOp(IC_RESULT(ic),ic,FALSE);
9168
9169   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9170   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9171   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9172
9173   DEBUGpic14_AopType(__LINE__,left,right,result);
9174
9175   size = AOP_SIZE(IC_RESULT(ic));
9176   offset = 0;
9177
9178   while (size--) {
9179     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9180     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9181     offset++;
9182   }
9183
9184   freeAsmop(left,NULL,ic,FALSE);
9185   freeAsmop(result,NULL,ic,TRUE);
9186
9187 }
9188
9189 #if 0
9190 /*-----------------------------------------------------------------*/
9191 /* genFarFarAssign - assignment when both are in far space         */
9192 /*-----------------------------------------------------------------*/
9193 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9194 {
9195     int size = AOP_SIZE(right);
9196     int offset = 0;
9197     char *l ;
9198     /* first push the right side on to the stack */
9199     while (size--) {
9200         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9201         MOVA(l);
9202         pic14_emitcode ("push","acc");
9203     }
9204     
9205     freeAsmop(right,NULL,ic,FALSE);
9206     /* now assign DPTR to result */
9207     aopOp(result,ic,FALSE);
9208     size = AOP_SIZE(result);
9209     while (size--) {
9210         pic14_emitcode ("pop","acc");
9211         aopPut(AOP(result),"a",--offset);
9212     }
9213     freeAsmop(result,NULL,ic,FALSE);
9214         
9215 }
9216 #endif
9217
9218 /*-----------------------------------------------------------------*/
9219 /* genAssign - generate code for assignment                        */
9220 /*-----------------------------------------------------------------*/
9221 static void genAssign (iCode *ic)
9222 {
9223   operand *result, *right;
9224   int size, offset,know_W;
9225   unsigned long lit = 0L;
9226
9227   result = IC_RESULT(ic);
9228   right  = IC_RIGHT(ic) ;
9229
9230   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9231
9232   /* if they are the same */
9233   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9234     return ;
9235
9236   aopOp(right,ic,FALSE);
9237   aopOp(result,ic,TRUE);
9238
9239   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9240
9241   /* if they are the same registers */
9242   if (pic14_sameRegs(AOP(right),AOP(result)))
9243     goto release;
9244
9245   /* if the result is a bit */
9246   if (AOP_TYPE(result) == AOP_CRY) {
9247
9248     /* if the right size is a literal then
9249        we know what the value is */
9250     if (AOP_TYPE(right) == AOP_LIT) {
9251           
9252       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9253                   popGet(AOP(result),0));
9254
9255       if (((int) operandLitValue(right))) 
9256         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9257                        AOP(result)->aopu.aop_dir,
9258                        AOP(result)->aopu.aop_dir);
9259       else
9260         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9261                        AOP(result)->aopu.aop_dir,
9262                        AOP(result)->aopu.aop_dir);
9263       goto release;
9264     }
9265
9266     /* the right is also a bit variable */
9267     if (AOP_TYPE(right) == AOP_CRY) {
9268       emitpcode(POC_BCF,    popGet(AOP(result),0));
9269       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9270       emitpcode(POC_BSF,    popGet(AOP(result),0));
9271
9272       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9273                      AOP(result)->aopu.aop_dir,
9274                      AOP(result)->aopu.aop_dir);
9275       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9276                      AOP(right)->aopu.aop_dir,
9277                      AOP(right)->aopu.aop_dir);
9278       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9279                      AOP(result)->aopu.aop_dir,
9280                      AOP(result)->aopu.aop_dir);
9281       goto release ;
9282     }
9283
9284     /* we need to or */
9285     emitpcode(POC_BCF,    popGet(AOP(result),0));
9286     pic14_toBoolean(right);
9287     emitSKPZ;
9288     emitpcode(POC_BSF,    popGet(AOP(result),0));
9289     //aopPut(AOP(result),"a",0);
9290     goto release ;
9291   }
9292
9293   /* bit variables done */
9294   /* general case */
9295   size = AOP_SIZE(result);
9296   offset = 0 ;
9297   if(AOP_TYPE(right) == AOP_LIT)
9298     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9299
9300   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9301   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9302     if(aopIdx(AOP(result),0) == 4) {
9303   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9304       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9305       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9306       goto release;
9307     } else
9308       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9309   }
9310
9311   know_W=-1;
9312   while (size--) {
9313   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9314     if(AOP_TYPE(right) == AOP_LIT) {
9315       if(lit&0xff) {
9316         if(know_W != (int)(lit&0xff))
9317           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9318         know_W = lit&0xff;
9319         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9320       } else
9321         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9322
9323       lit >>= 8;
9324
9325     } else if (AOP_TYPE(right) == AOP_CRY) {
9326       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9327       if(offset == 0) {
9328         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9329         emitpcode(POC_INCF, popGet(AOP(result),0));
9330       }
9331     } else {
9332       mov2w (AOP(right), offset);
9333       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9334     }
9335             
9336     offset++;
9337   }
9338
9339     
9340  release:
9341   freeAsmop (right,NULL,ic,FALSE);
9342   freeAsmop (result,NULL,ic,TRUE);
9343 }   
9344
9345 /*-----------------------------------------------------------------*/
9346 /* genJumpTab - genrates code for jump table                       */
9347 /*-----------------------------------------------------------------*/
9348 static void genJumpTab (iCode *ic)
9349 {
9350     symbol *jtab;
9351     char *l;
9352
9353     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9354
9355     aopOp(IC_JTCOND(ic),ic,FALSE);
9356     /* get the condition into accumulator */
9357     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9358     MOVA(l);
9359     /* multiply by three */
9360     pic14_emitcode("add","a,acc");
9361     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9362
9363     jtab = newiTempLabel(NULL);
9364     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9365     pic14_emitcode("jmp","@a+dptr");
9366     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9367
9368     emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9369     emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9370     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9371     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9372     emitSKPNC;
9373     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9374     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9375     emitpLabel(jtab->key);
9376
9377     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9378
9379     /* now generate the jump labels */
9380     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9381          jtab = setNextItem(IC_JTLABELS(ic))) {
9382         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9383         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9384         
9385     }
9386
9387 }
9388
9389 /*-----------------------------------------------------------------*/
9390 /* genMixedOperation - gen code for operators between mixed types  */
9391 /*-----------------------------------------------------------------*/
9392 /*
9393   TSD - Written for the PIC port - but this unfortunately is buggy.
9394   This routine is good in that it is able to efficiently promote 
9395   types to different (larger) sizes. Unfortunately, the temporary
9396   variables that are optimized out by this routine are sometimes
9397   used in other places. So until I know how to really parse the 
9398   iCode tree, I'm going to not be using this routine :(.
9399 */
9400 static int genMixedOperation (iCode *ic)
9401 {
9402 #if 0
9403   operand *result = IC_RESULT(ic);
9404   sym_link *ctype = operandType(IC_LEFT(ic));
9405   operand *right = IC_RIGHT(ic);
9406   int ret = 0;
9407   int big,small;
9408   int offset;
9409
9410   iCode *nextic;
9411   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9412
9413   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9414
9415   nextic = ic->next;
9416   if(!nextic)
9417     return 0;
9418
9419   nextright = IC_RIGHT(nextic);
9420   nextleft  = IC_LEFT(nextic);
9421   nextresult = IC_RESULT(nextic);
9422
9423   aopOp(right,ic,FALSE);
9424   aopOp(result,ic,FALSE);
9425   aopOp(nextright,  nextic, FALSE);
9426   aopOp(nextleft,   nextic, FALSE);
9427   aopOp(nextresult, nextic, FALSE);
9428
9429   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9430
9431     operand *t = right;
9432     right = nextright;
9433     nextright = t; 
9434
9435     pic14_emitcode(";remove right +","");
9436
9437   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9438 /*
9439     operand *t = right;
9440     right = nextleft;
9441     nextleft = t; 
9442 */
9443     pic14_emitcode(";remove left +","");
9444   } else
9445     return 0;
9446
9447   big = AOP_SIZE(nextleft);
9448   small = AOP_SIZE(nextright);
9449
9450   switch(nextic->op) {
9451
9452   case '+':
9453     pic14_emitcode(";optimize a +","");
9454     /* if unsigned or not an integral type */
9455     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9456       pic14_emitcode(";add a bit to something","");
9457     } else {
9458
9459       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9460
9461       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9462         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9463         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9464       } else
9465         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9466
9467       offset = 0;
9468       while(--big) {
9469
9470         offset++;
9471
9472         if(--small) {
9473           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9474             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9475             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9476           }
9477
9478           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9479           emitSKPNC;
9480           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9481                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9482                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9483           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9484           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9485
9486         } else {
9487           pic14_emitcode("rlf","known_zero,w");
9488
9489           /*
9490             if right is signed
9491               btfsc  right,7
9492                addlw ff
9493           */
9494           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9495             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9496             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9497           } else {
9498             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9499           }
9500         }
9501       }
9502       ret = 1;
9503     }
9504   }
9505   ret = 1;
9506
9507 release:
9508   freeAsmop(right,NULL,ic,TRUE);
9509   freeAsmop(result,NULL,ic,TRUE);
9510   freeAsmop(nextright,NULL,ic,TRUE);
9511   freeAsmop(nextleft,NULL,ic,TRUE);
9512   if(ret)
9513     nextic->generated = 1;
9514
9515   return ret;
9516 #else
9517   return 0;
9518 #endif
9519 }
9520 /*-----------------------------------------------------------------*/
9521 /* genCast - gen code for casting                                  */
9522 /*-----------------------------------------------------------------*/
9523 static void genCast (iCode *ic)
9524 {
9525     operand *result = IC_RESULT(ic);
9526     sym_link *ctype = operandType(IC_LEFT(ic));
9527     sym_link *rtype = operandType(IC_RIGHT(ic));
9528     operand *right = IC_RIGHT(ic);
9529     int size, offset ;
9530
9531     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9532     /* if they are equivalent then do nothing */
9533     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9534         return ;
9535
9536     aopOp(right,ic,FALSE) ;
9537     aopOp(result,ic,FALSE);
9538
9539     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9540
9541     /* if the result is a bit */
9542     if (AOP_TYPE(result) == AOP_CRY) {
9543         /* if the right size is a literal then
9544         we know what the value is */
9545       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9546         if (AOP_TYPE(right) == AOP_LIT) {
9547
9548           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9549                       popGet(AOP(result),0));
9550
9551             if (((int) operandLitValue(right))) 
9552               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9553                        AOP(result)->aopu.aop_dir,
9554                        AOP(result)->aopu.aop_dir);
9555             else
9556               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9557                        AOP(result)->aopu.aop_dir,
9558                        AOP(result)->aopu.aop_dir);
9559
9560             goto release;
9561         }
9562
9563         /* the right is also a bit variable */
9564         if (AOP_TYPE(right) == AOP_CRY) {
9565
9566           emitCLRC;
9567           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9568
9569           pic14_emitcode("clrc","");
9570           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9571                    AOP(right)->aopu.aop_dir,
9572                    AOP(right)->aopu.aop_dir);
9573             aopPut(AOP(result),"c",0);
9574             goto release ;
9575         }
9576
9577         /* we need to or */
9578         if (AOP_TYPE(right) == AOP_REG) {
9579           emitpcode(POC_BCF,    popGet(AOP(result),0));
9580           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9581           emitpcode(POC_BSF,    popGet(AOP(result),0));
9582         }
9583         pic14_toBoolean(right);
9584         aopPut(AOP(result),"a",0);
9585         goto release ;
9586     }
9587
9588     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9589       int offset = 1;
9590       size = AOP_SIZE(result);
9591
9592       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9593
9594       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9595       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9596       emitpcode(POC_INCF,   popGet(AOP(result),0));
9597
9598       while (size--)
9599         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9600
9601       goto release;
9602     }
9603
9604     /* if they are the same size : or less */
9605     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9606
9607         /* if they are in the same place */
9608       if (pic14_sameRegs(AOP(right),AOP(result)))
9609         goto release;
9610
9611       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9612       if (IS_PTR_CONST(rtype))
9613         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9614       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9615         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9616
9617       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9618         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9619         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9620         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9621         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9622         if(AOP_SIZE(result) <2)
9623           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9624
9625       } else {
9626
9627         /* if they in different places then copy */
9628         size = AOP_SIZE(result);
9629         offset = 0 ;
9630         while (size--) {
9631           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9632           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9633
9634           //aopPut(AOP(result),
9635           // aopGet(AOP(right),offset,FALSE,FALSE),
9636           // offset);
9637
9638           offset++;
9639         }
9640       }
9641       goto release;
9642     }
9643
9644
9645     /* if the result is of type pointer */
9646     if (IS_PTR(ctype)) {
9647
9648         int p_type;
9649         sym_link *type = operandType(right);
9650         sym_link *etype = getSpec(type);
9651       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9652
9653         /* pointer to generic pointer */
9654         if (IS_GENPTR(ctype)) {
9655             char *l = zero;
9656             
9657             if (IS_PTR(type)) 
9658                 p_type = DCL_TYPE(type);
9659             else {
9660                 /* we have to go by the storage class */
9661                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9662
9663 /*              if (SPEC_OCLS(etype)->codesp )  */
9664 /*                  p_type = CPOINTER ;  */
9665 /*              else */
9666 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9667 /*                      p_type = FPOINTER ; */
9668 /*                  else */
9669 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9670 /*                          p_type = PPOINTER; */
9671 /*                      else */
9672 /*                          if (SPEC_OCLS(etype) == idata ) */
9673 /*                              p_type = IPOINTER ; */
9674 /*                          else */
9675 /*                              p_type = POINTER ; */
9676             }
9677                 
9678             /* the first two bytes are known */
9679       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9680             size = GPTRSIZE - 1; 
9681             offset = 0 ;
9682             while (size--) {
9683               if(offset < AOP_SIZE(right)) {
9684       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9685                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9686                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9687                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9688                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9689                 } else { 
9690                   aopPut(AOP(result),
9691                          aopGet(AOP(right),offset,FALSE,FALSE),
9692                          offset);
9693                 }
9694               } else 
9695                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9696               offset++;
9697             }
9698             /* the last byte depending on type */
9699             switch (p_type) {
9700             case IPOINTER:
9701             case POINTER:
9702                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9703                 break;
9704             case FPOINTER:
9705               pic14_emitcode(";BUG!? ","%d",__LINE__);
9706                 l = one;
9707                 break;
9708             case CPOINTER:
9709               pic14_emitcode(";BUG!? ","%d",__LINE__);
9710                 l = "#0x02";
9711                 break;                          
9712             case PPOINTER:
9713               pic14_emitcode(";BUG!? ","%d",__LINE__);
9714                 l = "#0x03";
9715                 break;
9716                 
9717             default:
9718                 /* this should never happen */
9719                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9720                        "got unknown pointer type");
9721                 exit(1);
9722             }
9723             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9724             goto release ;
9725         }
9726         
9727         /* just copy the pointers */
9728         size = AOP_SIZE(result);
9729         offset = 0 ;
9730         while (size--) {
9731             aopPut(AOP(result),
9732                    aopGet(AOP(right),offset,FALSE,FALSE),
9733                    offset);
9734             offset++;
9735         }
9736         goto release ;
9737     }
9738     
9739
9740
9741     /* so we now know that the size of destination is greater
9742     than the size of the source.
9743     Now, if the next iCode is an operator then we might be
9744     able to optimize the operation without performing a cast.
9745     */
9746     if(genMixedOperation(ic))
9747       goto release;
9748
9749     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9750     
9751     /* we move to result for the size of source */
9752     size = AOP_SIZE(right);
9753     offset = 0 ;
9754     while (size--) {
9755       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9756       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9757       offset++;
9758     }
9759
9760     /* now depending on the sign of the destination */
9761     size = AOP_SIZE(result) - AOP_SIZE(right);
9762     /* if unsigned or not an integral type */
9763     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9764       while (size--)
9765         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9766     } else {
9767       /* we need to extend the sign :{ */
9768
9769       if(size == 1) {
9770         /* Save one instruction of casting char to int */
9771         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9772         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9773         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9774       } else {
9775         emitpcodeNULLop(POC_CLRW);
9776
9777         if(offset)
9778           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9779         else
9780           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9781         
9782         emitpcode(POC_MOVLW,   popGetLit(0xff));
9783
9784         while (size--)
9785           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9786       }
9787     }
9788
9789 release:
9790     freeAsmop(right,NULL,ic,TRUE);
9791     freeAsmop(result,NULL,ic,TRUE);
9792
9793 }
9794
9795 /*-----------------------------------------------------------------*/
9796 /* genDjnz - generate decrement & jump if not zero instrucion      */
9797 /*-----------------------------------------------------------------*/
9798 static int genDjnz (iCode *ic, iCode *ifx)
9799 {
9800     symbol *lbl, *lbl1;
9801     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9802
9803     if (!ifx)
9804         return 0;
9805     
9806     /* if the if condition has a false label
9807        then we cannot save */
9808     if (IC_FALSE(ifx))
9809         return 0;
9810
9811     /* if the minus is not of the form 
9812        a = a - 1 */
9813     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9814         !IS_OP_LITERAL(IC_RIGHT(ic)))
9815         return 0;
9816
9817     if (operandLitValue(IC_RIGHT(ic)) != 1)
9818         return 0;
9819
9820     /* if the size of this greater than one then no
9821        saving */
9822     if (getSize(operandType(IC_RESULT(ic))) > 1)
9823         return 0;
9824
9825     /* otherwise we can save BIG */
9826     lbl = newiTempLabel(NULL);
9827     lbl1= newiTempLabel(NULL);
9828
9829     aopOp(IC_RESULT(ic),ic,FALSE);
9830     
9831     if (IS_AOP_PREG(IC_RESULT(ic))) {
9832         pic14_emitcode("dec","%s",
9833                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9834         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9835         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9836     } else {    
9837
9838
9839       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9840       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9841
9842       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9844
9845     }
9846 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9847 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9848 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9849 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9850
9851     
9852     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9853     ifx->generated = 1;
9854     return 1;
9855 }
9856
9857 /*-----------------------------------------------------------------*/
9858 /* genReceive - generate code for a receive iCode                  */
9859 /*-----------------------------------------------------------------*/
9860 static void genReceive (iCode *ic)
9861 {
9862   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9863
9864   if (isOperandInFarSpace(IC_RESULT(ic)) &&
9865       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9866         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9867
9868     int size = getSize(operandType(IC_RESULT(ic)));
9869     int offset =  fReturnSizePic - size;
9870     while (size--) {
9871       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9872                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9873       offset++;
9874     }
9875     aopOp(IC_RESULT(ic),ic,FALSE);
9876     size = AOP_SIZE(IC_RESULT(ic));
9877     offset = 0;
9878     while (size--) {
9879       pic14_emitcode ("pop","acc");
9880       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9881     }
9882
9883   } else {
9884     _G.accInUse++;
9885     aopOp(IC_RESULT(ic),ic,FALSE);
9886     _G.accInUse--;
9887     assignResultValue(IC_RESULT(ic));
9888   }
9889
9890   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9891 }
9892
9893 /*-----------------------------------------------------------------*/
9894 /* genDummyRead - generate code for dummy read of volatiles        */
9895 /*-----------------------------------------------------------------*/
9896 static void
9897 genDummyRead (iCode * ic)
9898 {
9899   pic14_emitcode ("; genDummyRead","");
9900   pic14_emitcode ("; not implemented","");
9901
9902   ic = ic;
9903 }
9904
9905 /*-----------------------------------------------------------------*/
9906 /* genpic14Code - generate code for pic14 based controllers        */
9907 /*-----------------------------------------------------------------*/
9908 /*
9909  * At this point, ralloc.c has gone through the iCode and attempted
9910  * to optimize in a way suitable for a PIC. Now we've got to generate
9911  * PIC instructions that correspond to the iCode.
9912  *
9913  * Once the instructions are generated, we'll pass through both the
9914  * peep hole optimizer and the pCode optimizer.
9915  *-----------------------------------------------------------------*/
9916
9917 void genpic14Code (iCode *lic)
9918 {
9919     iCode *ic;
9920     int cln = 0;
9921
9922     lineHead = lineCurr = NULL;
9923
9924     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9925     addpBlock(pb);
9926
9927     /* if debug information required */
9928     if (options.debug && currFunc) { 
9929       if (currFunc) {
9930         debugFile->writeFunction(currFunc);
9931         _G.debugLine = 1;
9932         if (IS_STATIC(currFunc->etype)) {
9933           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9934           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9935         } else {
9936           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9937           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9938         }
9939         _G.debugLine = 0;
9940       }
9941     }
9942
9943
9944     for (ic = lic ; ic ; ic = ic->next ) {
9945
9946       DEBUGpic14_emitcode(";ic","");
9947         if ( cln != ic->lineno ) {
9948             if ( options.debug ) {
9949                 _G.debugLine = 1;
9950                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9951                          FileBaseName(ic->filename),ic->lineno,
9952                          ic->level,ic->block);
9953                 _G.debugLine = 0;
9954             }
9955             /*
9956               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9957               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9958               printCLine(ic->filename, ic->lineno));
9959             */
9960             if (!options.noCcodeInAsm) {
9961               addpCode2pBlock(pb,
9962                               newpCodeCSource(ic->lineno, 
9963                                               ic->filename, 
9964                                               printCLine(ic->filename, ic->lineno)));
9965             }
9966
9967             cln = ic->lineno ;
9968         }
9969
9970         // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9971
9972         /* if the result is marked as
9973            spilt and rematerializable or code for
9974            this has already been generated then
9975            do nothing */
9976         if (resultRemat(ic) || ic->generated ) 
9977             continue ;
9978         
9979         /* depending on the operation */
9980         switch (ic->op) {
9981         case '!' :
9982             genNot(ic);
9983             break;
9984             
9985         case '~' :
9986             genCpl(ic);
9987             break;
9988             
9989         case UNARYMINUS:
9990             genUminus (ic);
9991             break;
9992             
9993         case IPUSH:
9994             genIpush (ic);
9995             break;
9996             
9997         case IPOP:
9998             /* IPOP happens only when trying to restore a 
9999                spilt live range, if there is an ifx statement
10000                following this pop then the if statement might
10001                be using some of the registers being popped which
10002                would destory the contents of the register so
10003                we need to check for this condition and handle it */
10004             if (ic->next            && 
10005                 ic->next->op == IFX &&
10006                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10007                 genIfx (ic->next,ic);
10008             else
10009                 genIpop (ic);
10010             break; 
10011             
10012         case CALL:
10013             genCall (ic);
10014             break;
10015             
10016         case PCALL:
10017             genPcall (ic);
10018             break;
10019             
10020         case FUNCTION:
10021             genFunction (ic);
10022             break;
10023             
10024         case ENDFUNCTION:
10025             genEndFunction (ic);
10026             break;
10027             
10028         case RETURN:
10029             genRet (ic);
10030             break;
10031             
10032         case LABEL:
10033             genLabel (ic);
10034             break;
10035             
10036         case GOTO:
10037             genGoto (ic);
10038             break;
10039             
10040         case '+' :
10041             genPlus (ic) ;
10042             break;
10043             
10044         case '-' :
10045             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10046                 genMinus (ic);
10047             break;
10048             
10049         case '*' :
10050             genMult (ic);
10051             break;
10052             
10053         case '/' :
10054             genDiv (ic) ;
10055             break;
10056             
10057         case '%' :
10058             genMod (ic);
10059             break;
10060             
10061         case '>' :
10062             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10063             break;
10064             
10065         case '<' :
10066             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10067             break;
10068             
10069         case LE_OP:
10070         case GE_OP:
10071         case NE_OP:
10072             
10073             /* note these two are xlated by algebraic equivalence
10074                during parsing SDCC.y */
10075             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10076                    "got '>=' or '<=' shouldn't have come here");
10077             break;      
10078             
10079         case EQ_OP:
10080             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10081             break;          
10082             
10083         case AND_OP:
10084             genAndOp (ic);
10085             break;
10086             
10087         case OR_OP:
10088             genOrOp (ic);
10089             break;
10090             
10091         case '^' :
10092             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10093             break;
10094             
10095         case '|' :
10096                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10097             break;
10098             
10099         case BITWISEAND:
10100             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10101             break;
10102             
10103         case INLINEASM:
10104             genInline (ic);
10105             break;
10106             
10107         case RRC:
10108             genRRC (ic);
10109             break;
10110             
10111         case RLC:
10112             genRLC (ic);
10113             break;
10114             
10115         case GETHBIT:
10116             genGetHbit (ic);
10117             break;
10118             
10119         case LEFT_OP:
10120             genLeftShift (ic);
10121             break;
10122             
10123         case RIGHT_OP:
10124             genRightShift (ic);
10125             break;
10126             
10127         case GET_VALUE_AT_ADDRESS:
10128             genPointerGet(ic);
10129             break;
10130             
10131         case '=' :
10132             if (POINTER_SET(ic))
10133                 genPointerSet(ic);
10134             else
10135                 genAssign(ic);
10136             break;
10137             
10138         case IFX:
10139             genIfx (ic,NULL);
10140             break;
10141             
10142         case ADDRESS_OF:
10143             genAddrOf (ic);
10144             break;
10145             
10146         case JUMPTABLE:
10147             genJumpTab (ic);
10148             break;
10149             
10150         case CAST:
10151             genCast (ic);
10152             break;
10153             
10154         case RECEIVE:
10155             genReceive(ic);
10156             break;
10157             
10158         case SEND:
10159             addSet(&_G.sendSet,ic);
10160             break;
10161
10162         case DUMMY_READ_VOLATILE:
10163           genDummyRead (ic);
10164           break;
10165
10166         default :
10167             ic = ic;
10168         }
10169     }
10170
10171
10172     /* now we are ready to call the
10173        peep hole optimizer */
10174     if (!options.nopeep) {
10175       peepHole (&lineHead);
10176     }
10177     /* now do the actual printing */
10178     printLine (lineHead,codeOutFile);
10179
10180 #ifdef PCODE_DEBUG
10181     DFPRINTF((stderr,"printing pBlock\n\n"));
10182     printpBlock(stdout,pb);
10183 #endif
10184
10185     return;
10186 }