Fixed compound expressions of the type y = (x+K) OP B, where x and y are variables...
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #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);
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
220   if(pcop)
221     addpCode2pBlock(pb,newpCode(poc,pcop));
222   else
223     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
224 }
225
226 void emitpcodeNULLop(PIC_OPCODE poc)
227 {
228
229   addpCode2pBlock(pb,newpCode(poc,NULL));
230
231 }
232
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple    */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
237 {
238     va_list ap;
239     char lb[INITIAL_INLINEASM];  
240     char *lbp = lb;
241
242     va_start(ap,fmt);   
243
244     if (inst && *inst) {
245         if (fmt && *fmt)
246             sprintf(lb,"%s\t",inst);
247         else
248             sprintf(lb,"%s",inst);
249         vsprintf(lb+(strlen(lb)),fmt,ap);
250     }  else
251         vsprintf(lb,fmt,ap);
252
253     while (isspace(*lbp)) lbp++;
254
255     if (lbp && *lbp) 
256         lineCurr = (lineCurr ?
257                     connectLine(lineCurr,newLineNode(lb)) :
258                     (lineHead = newLineNode(lb)));
259     lineCurr->isInline = _G.inLine;
260     lineCurr->isDebug  = _G.debugLine;
261
262     if(debug_verbose)
263       addpCode2pBlock(pb,newpCodeCharP(lb));
264
265     va_end(ap);
266 }
267
268
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
273 {
274     bool r0iu = FALSE , r1iu = FALSE;
275     bool r0ou = FALSE , r1ou = FALSE;
276
277     /* the logic: if r0 & r1 used in the instruction
278     then we are in trouble otherwise */
279
280     /* first check if r0 & r1 are used by this
281     instruction, in which case we are in trouble */
282     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
284     {
285         goto endOfWorld;      
286     }
287
288     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
290
291     /* if no usage of r0 then return it */
292     if (!r0iu && !r0ou) {
293         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294         (*aopp)->type = AOP_R0;
295         
296         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
297     }
298
299     /* if no usage of r1 then return it */
300     if (!r1iu && !r1ou) {
301         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302         (*aopp)->type = AOP_R1;
303
304         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
305     }    
306
307     /* now we know they both have usage */
308     /* if r0 not used in this instruction */
309     if (!r0iu) {
310         /* push it if not already pushed */
311         if (!_G.r0Pushed) {
312           //pic14_emitcode ("push","%s",
313           //          pic14_regWithIdx(R0_IDX)->dname);
314             _G.r0Pushed++ ;
315         }
316         
317         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318         (*aopp)->type = AOP_R0;
319
320         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
321     }
322
323     /* if r1 not used then */
324
325     if (!r1iu) {
326         /* push it if not already pushed */
327         if (!_G.r1Pushed) {
328           //pic14_emitcode ("push","%s",
329           //          pic14_regWithIdx(R1_IDX)->dname);
330             _G.r1Pushed++ ;
331         }
332         
333         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334         (*aopp)->type = AOP_R1;
335         return pic14_regWithIdx(R1_IDX);
336     }
337
338 endOfWorld :
339     /* I said end of world but not quite end of world yet */
340     /* if this is a result then we can push it on the stack*/
341     if (result) {
342         (*aopp)->type = AOP_STK;    
343         return NULL;
344     }
345
346     /* other wise this is true end of the world */
347     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348            "getFreePtr should never reach here");
349     exit(0);
350 }
351
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp                                  */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
356 {
357     asmop *aop;
358
359     aop = Safe_calloc(1,sizeof(asmop));
360     aop->type = type;
361     return aop;
362 }
363
364 static void genSetDPTR(int n)
365 {
366     if (!n)
367     {
368         pic14_emitcode(";", "Select standard DPTR");
369         pic14_emitcode("mov", "dps, #0x00");
370     }
371     else
372     {
373         pic14_emitcode(";", "Select alternate DPTR");
374         pic14_emitcode("mov", "dps, #0x01");
375     }
376 }
377
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for  */
380 /*              generating code                                    */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 {
384   if(!resIfx) 
385     return;
386
387   //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
388
389   resIfx->condition = 1;    /* assume that the ifx is true */
390   resIfx->generated = 0;    /* indicate that the ifx has not been used */
391
392   if(!ifx) {
393     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
394 /*
395     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396                         __FUNCTION__,__LINE__,resIfx->lbl->key);
397 */
398   } else {
399     if(IC_TRUE(ifx)) {
400       resIfx->lbl = IC_TRUE(ifx);
401     } else {
402       resIfx->lbl = IC_FALSE(ifx);
403       resIfx->condition = 0;
404     }
405 /*
406     if(IC_TRUE(ifx)) 
407       DEBUGpic14_emitcode("; ***","ifx true is non-null");
408     if(IC_FALSE(ifx)) 
409       DEBUGpic14_emitcode("; ***","ifx false is non-null");
410 */
411   }
412
413   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
414
415 }
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type               */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
420 {
421
422     return PTR_TYPE(SPEC_OCLS(etype));
423
424 }
425
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol                                   */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
430 {
431     asmop *aop;
432     memmap *space= SPEC_OCLS(sym->etype);
433
434     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435     /* if already has one */
436     if (sym->aop)
437         return sym->aop;
438
439     /* assign depending on the storage class */
440     /* if it is on the stack or indirectly addressable */
441     /* space we need to assign either r0 or r1 to it   */    
442     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443         sym->aop = aop = newAsmop(0);
444         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445         aop->size = getSize(sym->type);
446
447         /* now assign the address of the variable to 
448         the pointer register */
449         if (aop->type != AOP_STK) {
450
451             if (sym->onStack) {
452                     if ( _G.accInUse )
453                         pic14_emitcode("push","acc");
454
455                     pic14_emitcode("mov","a,_bp");
456                     pic14_emitcode("add","a,#0x%02x",
457                              ((sym->stack < 0) ?
458                               ((char)(sym->stack - _G.nRegsSaved )) :
459                               ((char)sym->stack)) & 0xff);
460                     pic14_emitcode("mov","%s,a",
461                              aop->aopu.aop_ptr->name);
462
463                     if ( _G.accInUse )
464                         pic14_emitcode("pop","acc");
465             } else
466                 pic14_emitcode("mov","%s,#%s",
467                          aop->aopu.aop_ptr->name,
468                          sym->rname);
469             aop->paged = space->paged;
470         } else
471             aop->aopu.aop_stk = sym->stack;
472         return aop;
473     }
474     
475     if (sym->onStack && options.stack10bit)
476     {
477         /* It's on the 10 bit stack, which is located in
478          * far data space.
479          */
480          
481       //DEBUGpic14_emitcode(";","%d",__LINE__);
482
483         if ( _G.accInUse )
484                 pic14_emitcode("push","acc");
485
486         pic14_emitcode("mov","a,_bp");
487         pic14_emitcode("add","a,#0x%02x",
488                  ((sym->stack < 0) ?
489                    ((char)(sym->stack - _G.nRegsSaved )) :
490                    ((char)sym->stack)) & 0xff);
491         
492         genSetDPTR(1);
493         pic14_emitcode ("mov","dpx1,#0x40");
494         pic14_emitcode ("mov","dph1,#0x00");
495         pic14_emitcode ("mov","dpl1, a");
496         genSetDPTR(0);
497         
498         if ( _G.accInUse )
499             pic14_emitcode("pop","acc");
500             
501         sym->aop = aop = newAsmop(AOP_DPTR2);
502         aop->size = getSize(sym->type); 
503         return aop;
504     }
505
506     //DEBUGpic14_emitcode(";","%d",__LINE__);
507     /* if in bit space */
508     if (IN_BITSPACE(space)) {
509         sym->aop = aop = newAsmop (AOP_CRY);
510         aop->aopu.aop_dir = sym->rname ;
511         aop->size = getSize(sym->type);
512         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
513         return aop;
514     }
515     /* if it is in direct space */
516     if (IN_DIRSPACE(space)) {
517         sym->aop = aop = newAsmop (AOP_DIR);
518         aop->aopu.aop_dir = sym->rname ;
519         aop->size = getSize(sym->type);
520         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
521         return aop;
522     }
523
524     /* special case for a function */
525     if (IS_FUNC(sym->type)) {   
526         sym->aop = aop = newAsmop(AOP_IMMD);    
527         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
528         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
529         strcpy(aop->aopu.aop_immd,sym->rname);
530         aop->size = FPTRSIZE; 
531         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
532         return aop;
533     }
534
535
536     /* only remaining is far space */
537     /* in which case DPTR gets the address */
538     sym->aop = aop = newAsmop(AOP_PCODE);
539
540     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
541     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542     PCOI(aop->aopu.pcop)->index = 0;
543
544     DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
545                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
546
547     allocDirReg (IC_LEFT(ic));
548
549     aop->size = FPTRSIZE; 
550 /*
551     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552     sym->aop = aop = newAsmop(AOP_DPTR);
553     pic14_emitcode ("mov","dptr,#%s", sym->rname);
554     aop->size = getSize(sym->type);
555
556     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
557 */
558
559     /* if it is in code space */
560     if (IN_CODESPACE(space))
561         aop->code = 1;
562
563     return aop;     
564 }
565
566 /*-----------------------------------------------------------------*/
567 /* aopForRemat - rematerialzes an object                           */
568 /*-----------------------------------------------------------------*/
569 static asmop *aopForRemat (operand *op) // x symbol *sym)
570 {
571   symbol *sym = OP_SYMBOL(op);
572   iCode *ic = NULL;
573   asmop *aop = newAsmop(AOP_PCODE);
574   int val = 0;
575   int offset = 0;
576
577   ic = sym->rematiCode;
578
579   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
580   if(IS_OP_POINTER(op)) {
581     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
582   }
583   for (;;) {
584     if (ic->op == '+') {
585       val += (int) operandLitValue(IC_RIGHT(ic));
586     } else if (ic->op == '-') {
587       val -= (int) operandLitValue(IC_RIGHT(ic));
588     } else
589       break;
590         
591     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
592   }
593
594   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
595   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
596   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
597   PCOI(aop->aopu.pcop)->index = val;
598
599   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
600                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
601                       val, IS_PTR_CONST(operandType(op)));
602
603   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
604
605   allocDirReg (IC_LEFT(ic));
606
607   return aop;        
608 }
609
610 int aopIdx (asmop *aop, int offset)
611 {
612   if(!aop)
613     return -1;
614
615   if(aop->type !=  AOP_REG)
616     return -2;
617         
618   return aop->aopu.aop_reg[offset]->rIdx;
619
620 }
621 /*-----------------------------------------------------------------*/
622 /* regsInCommon - two operands have some registers in common       */
623 /*-----------------------------------------------------------------*/
624 static bool regsInCommon (operand *op1, operand *op2)
625 {
626     symbol *sym1, *sym2;
627     int i;
628
629     /* if they have registers in common */
630     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
631         return FALSE ;
632
633     sym1 = OP_SYMBOL(op1);
634     sym2 = OP_SYMBOL(op2);
635
636     if (sym1->nRegs == 0 || sym2->nRegs == 0)
637         return FALSE ;
638
639     for (i = 0 ; i < sym1->nRegs ; i++) {
640         int j;
641         if (!sym1->regs[i])
642             continue ;
643
644         for (j = 0 ; j < sym2->nRegs ;j++ ) {
645             if (!sym2->regs[j])
646                 continue ;
647
648             if (sym2->regs[j] == sym1->regs[i])
649                 return TRUE ;
650         }
651     }
652
653     return FALSE ;
654 }
655
656 /*-----------------------------------------------------------------*/
657 /* operandsEqu - equivalent                                        */
658 /*-----------------------------------------------------------------*/
659 static bool operandsEqu ( operand *op1, operand *op2)
660 {
661     symbol *sym1, *sym2;
662
663     /* if they not symbols */
664     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
665         return FALSE;
666
667     sym1 = OP_SYMBOL(op1);
668     sym2 = OP_SYMBOL(op2);
669
670     /* if both are itemps & one is spilt
671        and the other is not then false */
672     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
673         sym1->isspilt != sym2->isspilt )
674         return FALSE ;
675
676     /* if they are the same */
677     if (sym1 == sym2)
678         return TRUE ;
679
680     if (strcmp(sym1->rname,sym2->rname) == 0)
681         return TRUE;
682
683
684     /* if left is a tmp & right is not */
685     if (IS_ITEMP(op1)  && 
686         !IS_ITEMP(op2) &&
687         sym1->isspilt  &&
688         (sym1->usl.spillLoc == sym2))
689         return TRUE;
690
691     if (IS_ITEMP(op2)  && 
692         !IS_ITEMP(op1) &&
693         sym2->isspilt  &&
694         sym1->level > 0 &&
695         (sym2->usl.spillLoc == sym1))
696         return TRUE ;
697
698     return FALSE ;
699 }
700
701 /*-----------------------------------------------------------------*/
702 /* pic14_sameRegs - two asmops have the same registers                   */
703 /*-----------------------------------------------------------------*/
704 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
705 {
706     int i;
707
708     if (aop1 == aop2)
709         return TRUE ;
710
711     if (aop1->type != AOP_REG ||
712         aop2->type != AOP_REG )
713         return FALSE ;
714
715     if (aop1->size != aop2->size )
716         return FALSE ;
717
718     for (i = 0 ; i < aop1->size ; i++ )
719         if (aop1->aopu.aop_reg[i] !=
720             aop2->aopu.aop_reg[i] )
721             return FALSE ;
722
723     return TRUE ;
724 }
725
726 /*-----------------------------------------------------------------*/
727 /* aopOp - allocates an asmop for an operand  :                    */
728 /*-----------------------------------------------------------------*/
729 void aopOp (operand *op, iCode *ic, bool result)
730 {
731     asmop *aop;
732     symbol *sym;
733     int i;
734
735     if (!op)
736         return ;
737
738     //    DEBUGpic14_emitcode(";","%d",__LINE__);
739     /* if this a literal */
740     if (IS_OP_LITERAL(op)) {
741         op->aop = aop = newAsmop(AOP_LIT);
742         aop->aopu.aop_lit = op->operand.valOperand;
743         aop->size = getSize(operandType(op));
744         return;
745     }
746
747     {
748       sym_link *type = operandType(op);
749       if(IS_PTR_CONST(type))
750         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
751     }
752
753     /* if already has a asmop then continue */
754     if (op->aop)
755         return ;
756
757     /* if the underlying symbol has a aop */
758     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
759       DEBUGpic14_emitcode(";","%d",__LINE__);
760         op->aop = OP_SYMBOL(op)->aop;
761         return;
762     }
763
764     /* if this is a true symbol */
765     if (IS_TRUE_SYMOP(op)) {    
766       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
767       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
768       return ;
769     }
770
771     /* this is a temporary : this has
772     only four choices :
773     a) register
774     b) spillocation
775     c) rematerialize 
776     d) conditional   
777     e) can be a return use only */
778
779     sym = OP_SYMBOL(op);
780
781
782     /* if the type is a conditional */
783     if (sym->regType == REG_CND) {
784         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
785         aop->size = 0;
786         return;
787     }
788
789     /* if it is spilt then two situations
790     a) is rematerialize 
791     b) has a spill location */
792     if (sym->isspilt || sym->nRegs == 0) {
793
794       DEBUGpic14_emitcode(";","%d",__LINE__);
795         /* rematerialize it NOW */
796         if (sym->remat) {
797
798             sym->aop = op->aop = aop =
799                                       aopForRemat (op);
800             aop->size = getSize(sym->type);
801             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
802             return;
803         }
804
805         if (sym->accuse) {
806             int i;
807             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
808             aop->size = getSize(sym->type);
809             for ( i = 0 ; i < 2 ; i++ )
810                 aop->aopu.aop_str[i] = accUse[i];
811             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
812             return;  
813         }
814
815         if (sym->ruonly ) {
816           /*
817           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
818           aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
819           //allocDirReg (IC_LEFT(ic));
820           aop->size = getSize(sym->type);
821           */
822
823           unsigned i;
824
825           aop = op->aop = sym->aop = newAsmop(AOP_STR);
826           aop->size = getSize(sym->type);
827           for ( i = 0 ; i < fReturnSizePic ; i++ )
828             aop->aopu.aop_str[i] = fReturn[i];
829
830           DEBUGpic14_emitcode(";","%d",__LINE__);
831           return;
832         }
833
834         /* else spill location  */
835         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
836             /* force a new aop if sizes differ */
837             sym->usl.spillLoc->aop = NULL;
838         }
839         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
840                             __FUNCTION__,__LINE__,
841                             sym->usl.spillLoc->rname,
842                             sym->rname, sym->usl.spillLoc->offset);
843
844         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
847                                           getSize(sym->type), 
848                                           sym->usl.spillLoc->offset);
849         aop->size = getSize(sym->type);
850
851         return;
852     }
853
854     {
855       sym_link *type = operandType(op);
856       if(IS_PTR_CONST(type)) 
857         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
858     }
859
860     /* must be in a register */
861     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
862     sym->aop = op->aop = aop = newAsmop(AOP_REG);
863     aop->size = sym->nRegs;
864     for ( i = 0 ; i < sym->nRegs ;i++)
865         aop->aopu.aop_reg[i] = sym->regs[i];
866 }
867
868 /*-----------------------------------------------------------------*/
869 /* freeAsmop - free up the asmop given to an operand               */
870 /*----------------------------------------------------------------*/
871 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
872 {   
873     asmop *aop ;
874
875     if (!op)
876         aop = aaop;
877     else 
878         aop = op->aop;
879
880     if (!aop)
881         return ;
882
883     if (aop->freed)
884         goto dealloc; 
885
886     aop->freed = 1;
887
888     /* depending on the asmop type only three cases need work AOP_RO
889        , AOP_R1 && AOP_STK */
890 #if 0
891     switch (aop->type) {
892         case AOP_R0 :
893             if (_G.r0Pushed ) {
894                 if (pop) {
895                     pic14_emitcode ("pop","ar0");     
896                     _G.r0Pushed--;
897                 }
898             }
899             bitVectUnSetBit(ic->rUsed,R0_IDX);
900             break;
901
902         case AOP_R1 :
903             if (_G.r1Pushed ) {
904                 if (pop) {
905                     pic14_emitcode ("pop","ar1");
906                     _G.r1Pushed--;
907                 }
908             }
909             bitVectUnSetBit(ic->rUsed,R1_IDX);          
910             break;
911
912         case AOP_STK :
913         {
914             int sz = aop->size;    
915             int stk = aop->aopu.aop_stk + aop->size;
916             bitVectUnSetBit(ic->rUsed,R0_IDX);
917             bitVectUnSetBit(ic->rUsed,R1_IDX);          
918
919             getFreePtr(ic,&aop,FALSE);
920             
921             if (options.stack10bit)
922             {
923                 /* I'm not sure what to do here yet... */
924                 /* #STUB */
925                 fprintf(stderr, 
926                         "*** Warning: probably generating bad code for "
927                         "10 bit stack mode.\n");
928             }
929             
930             if (stk) {
931                 pic14_emitcode ("mov","a,_bp");
932                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
933                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
934             } else {
935                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
936             }
937
938             while (sz--) {
939                 pic14_emitcode("pop","acc");
940                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
941                 if (!sz) break;
942                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
943             }
944             op->aop = aop;
945             freeAsmop(op,NULL,ic,TRUE);
946             if (_G.r0Pushed) {
947                 pic14_emitcode("pop","ar0");
948                 _G.r0Pushed--;
949             }
950
951             if (_G.r1Pushed) {
952                 pic14_emitcode("pop","ar1");
953                 _G.r1Pushed--;
954             }       
955         }
956     }
957 #endif
958
959 dealloc:
960     /* all other cases just dealloc */
961     if (op ) {
962         op->aop = NULL;
963         if (IS_SYMOP(op)) {
964             OP_SYMBOL(op)->aop = NULL;    
965             /* if the symbol has a spill */
966             if (SPIL_LOC(op))
967                 SPIL_LOC(op)->aop = NULL;
968         }
969     }
970 }
971
972 /*-----------------------------------------------------------------*/
973 /* aopGet - for fetching value of the aop                          */
974 /*-----------------------------------------------------------------*/
975 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
976 {
977     char *s = buffer ;
978     char *rs;
979
980     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
981     /* offset is greater than
982     size then zero */
983     if (offset > (aop->size - 1) &&
984         aop->type != AOP_LIT)
985         return zero;
986
987     /* depending on type */
988     switch (aop->type) {
989         
990     case AOP_R0:
991     case AOP_R1:
992         DEBUGpic14_emitcode(";","%d",__LINE__);
993         /* if we need to increment it */       
994         while (offset > aop->coff) {        
995             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
996             aop->coff++;
997         }
998         
999         while (offset < aop->coff) {
1000             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1001             aop->coff--;
1002         }
1003         
1004         aop->coff = offset ;
1005         if (aop->paged) {
1006             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1007             return (dname ? "acc" : "a");
1008         }       
1009         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1010         rs = Safe_calloc(1,strlen(s)+1);
1011         strcpy(rs,s);   
1012         return rs;
1013         
1014     case AOP_DPTR:
1015     case AOP_DPTR2:
1016         DEBUGpic14_emitcode(";","%d",__LINE__);
1017     if (aop->type == AOP_DPTR2)
1018     {
1019         genSetDPTR(1);
1020     }
1021     
1022         while (offset > aop->coff) {
1023             pic14_emitcode ("inc","dptr");
1024             aop->coff++;
1025         }
1026         
1027         while (offset < aop->coff) {        
1028             pic14_emitcode("lcall","__decdptr");
1029             aop->coff--;
1030         }
1031         
1032         aop->coff = offset;
1033         if (aop->code) {
1034             pic14_emitcode("clr","a");
1035             pic14_emitcode("movc","a,@a+dptr");
1036         }
1037     else {
1038             pic14_emitcode("movx","a,@dptr");
1039     }
1040             
1041     if (aop->type == AOP_DPTR2)
1042     {
1043         genSetDPTR(0);
1044     }
1045             
1046     return (dname ? "acc" : "a");
1047         
1048         
1049     case AOP_IMMD:
1050         if (bit16) 
1051             sprintf (s,"%s",aop->aopu.aop_immd);
1052         else
1053             if (offset) 
1054                 sprintf(s,"(%s >> %d)",
1055                         aop->aopu.aop_immd,
1056                         offset*8);
1057             else
1058                 sprintf(s,"%s",
1059                         aop->aopu.aop_immd);
1060         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1061         rs = Safe_calloc(1,strlen(s)+1);
1062         strcpy(rs,s);   
1063         return rs;
1064         
1065     case AOP_DIR:
1066       if (offset) {
1067         sprintf(s,"(%s + %d)",
1068                 aop->aopu.aop_dir,
1069                 offset);
1070         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1071       } else
1072             sprintf(s,"%s",aop->aopu.aop_dir);
1073         rs = Safe_calloc(1,strlen(s)+1);
1074         strcpy(rs,s);   
1075         return rs;
1076         
1077     case AOP_REG:
1078       //if (dname) 
1079       //    return aop->aopu.aop_reg[offset]->dname;
1080       //else
1081             return aop->aopu.aop_reg[offset]->name;
1082         
1083     case AOP_CRY:
1084       //pic14_emitcode(";","%d",__LINE__);
1085       return aop->aopu.aop_dir;
1086         
1087     case AOP_ACC:
1088         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1089         return "AOP_accumulator_bug";
1090
1091     case AOP_LIT:
1092         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1093         rs = Safe_calloc(1,strlen(s)+1);
1094         strcpy(rs,s);   
1095         return rs;
1096         
1097     case AOP_STR:
1098         aop->coff = offset ;
1099         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1100             dname)
1101             return "acc";
1102         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1103         
1104         return aop->aopu.aop_str[offset];
1105         
1106     case AOP_PCODE:
1107       {
1108         pCodeOp *pcop = aop->aopu.pcop;
1109         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1110         if(pcop->name) {
1111           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1112           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1113           sprintf(s,"%s", pcop->name);
1114         } else
1115           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1116
1117       }
1118       rs = Safe_calloc(1,strlen(s)+1);
1119       strcpy(rs,s);   
1120       return rs;
1121
1122     }
1123
1124     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1125            "aopget got unsupported aop->type");
1126     exit(0);
1127 }
1128
1129
1130 /*-----------------------------------------------------------------*/
1131 /* popGetTempReg - create a new temporary pCodeOp                  */
1132 /*-----------------------------------------------------------------*/
1133 pCodeOp *popGetTempReg(void)
1134 {
1135
1136   pCodeOp *pcop;
1137
1138   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1139   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1140     PCOR(pcop)->r->wasUsed=1;
1141     PCOR(pcop)->r->isFree=0;
1142   }
1143
1144   return pcop;
1145 }
1146
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp                  */
1149 /*-----------------------------------------------------------------*/
1150 void popReleaseTempReg(pCodeOp *pcop)
1151 {
1152
1153   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1154     PCOR(pcop)->r->isFree = 1;
1155
1156 }
1157 /*-----------------------------------------------------------------*/
1158 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1159 /*-----------------------------------------------------------------*/
1160 pCodeOp *popGetLabel(unsigned int key)
1161 {
1162
1163   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1164
1165   if(key>max_key)
1166     max_key = key;
1167
1168   return newpCodeOpLabel(NULL,key+100+labelOffset);
1169 }
1170
1171 /*-----------------------------------------------------------------*/
1172 /* popCopyReg - copy a pcode operator                              */
1173 /*-----------------------------------------------------------------*/
1174 pCodeOp *popCopyReg(pCodeOpReg *pc)
1175 {
1176   pCodeOpReg *pcor;
1177
1178   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1179   pcor->pcop.type = pc->pcop.type;
1180   if(pc->pcop.name) {
1181     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1182       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1183   } else
1184     pcor->pcop.name = NULL;
1185
1186   pcor->r = pc->r;
1187   pcor->rIdx = pc->rIdx;
1188   pcor->r->wasUsed=1;
1189
1190   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1191
1192   return PCOP(pcor);
1193 }
1194 /*-----------------------------------------------------------------*/
1195 /* popGet - asm operator to pcode operator conversion              */
1196 /*-----------------------------------------------------------------*/
1197 pCodeOp *popGetLit(unsigned int lit)
1198 {
1199
1200   return newpCodeOpLit(lit);
1201 }
1202
1203
1204 /*-----------------------------------------------------------------*/
1205 /* popGetImmd - asm operator to pcode immediate conversion         */
1206 /*-----------------------------------------------------------------*/
1207 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1208 {
1209
1210   return newpCodeOpImmd(name, offset,index, 0);
1211 }
1212
1213
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion              */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetWithString(char *str)
1218 {
1219   pCodeOp *pcop;
1220
1221
1222   if(!str) {
1223     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1224     exit (1);
1225   }
1226
1227   pcop = newpCodeOp(str,PO_STR);
1228
1229   return pcop;
1230 }
1231
1232 /*-----------------------------------------------------------------*/
1233 /* popRegFromString -                                              */
1234 /*-----------------------------------------------------------------*/
1235 pCodeOp *popRegFromString(char *str, int size, int offset)
1236 {
1237
1238   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239   pcop->type = PO_DIR;
1240
1241   DEBUGpic14_emitcode(";","%d",__LINE__);
1242
1243   if(!str)
1244     str = "BAD_STRING";
1245
1246   pcop->name = Safe_calloc(1,strlen(str)+1);
1247   strcpy(pcop->name,str);
1248
1249   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1250
1251   PCOR(pcop)->r = dirregWithName(pcop->name);
1252   if(PCOR(pcop)->r == NULL) {
1253     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1254     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1255     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1256   } else {
1257     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1258   }
1259   PCOR(pcop)->instance = offset;
1260
1261   return pcop;
1262 }
1263
1264 pCodeOp *popRegFromIdx(int rIdx)
1265 {
1266   pCodeOp *pcop;
1267
1268   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1269                        __FUNCTION__,__LINE__,rIdx);
1270
1271   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1272
1273   PCOR(pcop)->rIdx = rIdx;
1274   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1275   PCOR(pcop)->r->isFree = 0;
1276   PCOR(pcop)->r->wasUsed = 1;
1277
1278   pcop->type = PCOR(pcop)->r->pc_type;
1279
1280
1281   return pcop;
1282 }
1283 /*-----------------------------------------------------------------*/
1284 /* popGet - asm operator to pcode operator conversion              */
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1287 {
1288   //char *s = buffer ;
1289     //char *rs;
1290
1291     pCodeOp *pcop;
1292
1293     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1294     /* offset is greater than
1295     size then zero */
1296
1297     if (offset > (aop->size - 1) &&
1298         aop->type != AOP_LIT)
1299       return NULL;  //zero;
1300
1301     /* depending on type */
1302     switch (aop->type) {
1303         
1304     case AOP_R0:
1305     case AOP_R1:
1306     case AOP_DPTR:
1307     case AOP_DPTR2:
1308     case AOP_ACC:
1309         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1310         return NULL;
1311         
1312     case AOP_IMMD:
1313       DEBUGpic14_emitcode(";","%d",__LINE__);
1314       return popGetImmd(aop->aopu.aop_immd,offset,0);
1315
1316     case AOP_DIR:
1317       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1318 #if 0
1319         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1320         pcop->type = PO_DIR;
1321
1322         /*
1323         if (offset)
1324             sprintf(s,"(%s + %d)",
1325                     aop->aopu.aop_dir,
1326                     offset);
1327         else
1328             sprintf(s,"%s",aop->aopu.aop_dir);
1329         pcop->name = Safe_calloc(1,strlen(s)+1);
1330         strcpy(pcop->name,s);   
1331         */
1332         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1333         strcpy(pcop->name,aop->aopu.aop_dir);   
1334         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1335         if(PCOR(pcop)->r == NULL) {
1336           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1337           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1338           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1339         } else {
1340           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1341         }
1342         PCOR(pcop)->instance = offset;
1343
1344         return pcop;
1345 #endif
1346         
1347     case AOP_REG:
1348       {
1349         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1350
1351         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1352         PCOR(pcop)->rIdx = rIdx;
1353         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1354         PCOR(pcop)->r->wasUsed=1;
1355         PCOR(pcop)->r->isFree=0;
1356
1357         PCOR(pcop)->instance = offset;
1358         pcop->type = PCOR(pcop)->r->pc_type;
1359         //rs = aop->aopu.aop_reg[offset]->name;
1360         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1361         return pcop;
1362       }
1363
1364     case AOP_CRY:
1365       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1366       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1367       //if(PCOR(pcop)->r == NULL)
1368       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1369       return pcop;
1370         
1371     case AOP_LIT:
1372       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1373
1374     case AOP_STR:
1375       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1376       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1377       /*
1378       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1379       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1380       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1381       pcop->type = PCOR(pcop)->r->pc_type;
1382       pcop->name = PCOR(pcop)->r->name;
1383
1384       return pcop;
1385       */
1386
1387     case AOP_PCODE:
1388       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1389                           __LINE__, 
1390                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1391       pcop = pCodeOpCopy(aop->aopu.pcop);
1392       PCOI(pcop)->offset = offset;
1393       return pcop;
1394     }
1395
1396     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1397            "popGet got unsupported aop->type");
1398     exit(0);
1399 }
1400 /*-----------------------------------------------------------------*/
1401 /* aopPut - puts a string for a aop                                */
1402 /*-----------------------------------------------------------------*/
1403 void aopPut (asmop *aop, char *s, int offset)
1404 {
1405     char *d = buffer ;
1406     symbol *lbl ;
1407
1408     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1409
1410     if (aop->size && offset > ( aop->size - 1)) {
1411         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412                "aopPut got offset > aop->size");
1413         exit(0);
1414     }
1415
1416     /* will assign value to value */
1417     /* depending on where it is ofcourse */
1418     switch (aop->type) {
1419     case AOP_DIR:
1420       if (offset) {
1421         sprintf(d,"(%s + %d)",
1422                 aop->aopu.aop_dir,offset);
1423         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1424
1425       } else
1426             sprintf(d,"%s",aop->aopu.aop_dir);
1427         
1428         if (strcmp(d,s)) {
1429           DEBUGpic14_emitcode(";","%d",__LINE__);
1430           if(strcmp(s,"W"))
1431             pic14_emitcode("movf","%s,w",s);
1432           pic14_emitcode("movwf","%s",d);
1433
1434           if(strcmp(s,"W")) {
1435             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1436             if(offset >= aop->size) {
1437               emitpcode(POC_CLRF,popGet(aop,offset));
1438               break;
1439             } else
1440               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1441           }
1442
1443           emitpcode(POC_MOVWF,popGet(aop,offset));
1444
1445
1446         }
1447         break;
1448         
1449     case AOP_REG:
1450       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1451         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1452           /*
1453             if (*s == '@'           ||
1454                 strcmp(s,"r0") == 0 ||
1455                 strcmp(s,"r1") == 0 ||
1456                 strcmp(s,"r2") == 0 ||
1457                 strcmp(s,"r3") == 0 ||
1458                 strcmp(s,"r4") == 0 ||
1459                 strcmp(s,"r5") == 0 ||
1460                 strcmp(s,"r6") == 0 || 
1461                 strcmp(s,"r7") == 0 )
1462                 pic14_emitcode("mov","%s,%s  ; %d",
1463                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1464             else
1465           */
1466
1467           if(strcmp(s,"W")==0 )
1468             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1469
1470           pic14_emitcode("movwf","%s",
1471                    aop->aopu.aop_reg[offset]->name);
1472
1473           if(strcmp(s,zero)==0) {
1474             emitpcode(POC_CLRF,popGet(aop,offset));
1475
1476           } else if(strcmp(s,"W")==0) {
1477             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1478             pcop->type = PO_GPR_REGISTER;
1479
1480             PCOR(pcop)->rIdx = -1;
1481             PCOR(pcop)->r = NULL;
1482
1483             DEBUGpic14_emitcode(";","%d",__LINE__);
1484             pcop->name = Safe_strdup(s);
1485             emitpcode(POC_MOVFW,pcop);
1486             emitpcode(POC_MOVWF,popGet(aop,offset));
1487           } else if(strcmp(s,one)==0) {
1488             emitpcode(POC_CLRF,popGet(aop,offset));
1489             emitpcode(POC_INCF,popGet(aop,offset));
1490           } else {
1491             emitpcode(POC_MOVWF,popGet(aop,offset));
1492           }
1493         }
1494         break;
1495         
1496     case AOP_DPTR:
1497     case AOP_DPTR2:
1498     
1499     if (aop->type == AOP_DPTR2)
1500     {
1501         genSetDPTR(1);
1502     }
1503     
1504         if (aop->code) {
1505             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1506                    "aopPut writting to code space");
1507             exit(0);
1508         }
1509         
1510         while (offset > aop->coff) {
1511             aop->coff++;
1512             pic14_emitcode ("inc","dptr");
1513         }
1514         
1515         while (offset < aop->coff) {
1516             aop->coff-- ;
1517             pic14_emitcode("lcall","__decdptr");
1518         }
1519         
1520         aop->coff = offset;
1521         
1522         /* if not in accumulater */
1523         MOVA(s);        
1524         
1525         pic14_emitcode ("movx","@dptr,a");
1526         
1527     if (aop->type == AOP_DPTR2)
1528     {
1529         genSetDPTR(0);
1530     }
1531         break;
1532         
1533     case AOP_R0:
1534     case AOP_R1:
1535         while (offset > aop->coff) {
1536             aop->coff++;
1537             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1538         }
1539         while (offset < aop->coff) {
1540             aop->coff-- ;
1541             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1542         }
1543         aop->coff = offset;
1544         
1545         if (aop->paged) {
1546             MOVA(s);           
1547             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1548             
1549         } else
1550             if (*s == '@') {
1551                 MOVA(s);
1552                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1553             } else
1554                 if (strcmp(s,"r0") == 0 ||
1555                     strcmp(s,"r1") == 0 ||
1556                     strcmp(s,"r2") == 0 ||
1557                     strcmp(s,"r3") == 0 ||
1558                     strcmp(s,"r4") == 0 ||
1559                     strcmp(s,"r5") == 0 ||
1560                     strcmp(s,"r6") == 0 || 
1561                     strcmp(s,"r7") == 0 ) {
1562                     char buffer[10];
1563                     sprintf(buffer,"a%s",s);
1564                     pic14_emitcode("mov","@%s,%s",
1565                              aop->aopu.aop_ptr->name,buffer);
1566                 } else
1567                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1568         
1569         break;
1570         
1571     case AOP_STK:
1572         if (strcmp(s,"a") == 0)
1573             pic14_emitcode("push","acc");
1574         else
1575             pic14_emitcode("push","%s",s);
1576         
1577         break;
1578         
1579     case AOP_CRY:
1580         /* if bit variable */
1581         if (!aop->aopu.aop_dir) {
1582             pic14_emitcode("clr","a");
1583             pic14_emitcode("rlc","a");
1584         } else {
1585             if (s == zero) 
1586                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1587             else
1588                 if (s == one)
1589                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1590                 else
1591                     if (!strcmp(s,"c"))
1592                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1593                     else {
1594                         lbl = newiTempLabel(NULL);
1595                         
1596                         if (strcmp(s,"a")) {
1597                             MOVA(s);
1598                         }
1599                         pic14_emitcode("clr","c");
1600                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1601                         pic14_emitcode("cpl","c");
1602                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1603                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1604                     }
1605         }
1606         break;
1607         
1608     case AOP_STR:
1609         aop->coff = offset;
1610         if (strcmp(aop->aopu.aop_str[offset],s))
1611             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1612         break;
1613         
1614     case AOP_ACC:
1615         aop->coff = offset;
1616         if (!offset && (strcmp(s,"acc") == 0))
1617             break;
1618         
1619         if (strcmp(aop->aopu.aop_str[offset],s))
1620             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1621         break;
1622
1623     default :
1624         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1625                "aopPut got unsupported aop->type");
1626         exit(0);    
1627     }    
1628
1629 }
1630
1631 /*-----------------------------------------------------------------*/
1632 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1633 /*-----------------------------------------------------------------*/
1634 void mov2w (asmop *aop, int offset)
1635 {
1636
1637   if(!aop)
1638     return;
1639
1640   DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1641
1642   if ( aop->type == AOP_PCODE ||
1643        aop->type == AOP_LIT )
1644     emitpcode(POC_MOVLW,popGet(aop,offset));
1645   else
1646     emitpcode(POC_MOVFW,popGet(aop,offset));
1647
1648 }
1649
1650 /*-----------------------------------------------------------------*/
1651 /* reAdjustPreg - points a register back to where it should        */
1652 /*-----------------------------------------------------------------*/
1653 static void reAdjustPreg (asmop *aop)
1654 {
1655     int size ;
1656
1657     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1658     aop->coff = 0;
1659     if ((size = aop->size) <= 1)
1660         return ;
1661     size-- ;
1662     switch (aop->type) {
1663         case AOP_R0 :
1664         case AOP_R1 :
1665             while (size--)
1666                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1667             break;          
1668         case AOP_DPTR :
1669         case AOP_DPTR2:
1670             if (aop->type == AOP_DPTR2)
1671             {
1672                 genSetDPTR(1);
1673             } 
1674             while (size--)
1675             {
1676                 pic14_emitcode("lcall","__decdptr");
1677             }
1678                 
1679             if (aop->type == AOP_DPTR2)
1680             {
1681                 genSetDPTR(0);
1682             }                
1683             break;  
1684
1685     }   
1686
1687 }
1688
1689 /*-----------------------------------------------------------------*/
1690 /* genNotFloat - generates not for float operations              */
1691 /*-----------------------------------------------------------------*/
1692 static void genNotFloat (operand *op, operand *res)
1693 {
1694     int size, offset;
1695     char *l;
1696     symbol *tlbl ;
1697
1698     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1699     /* we will put 127 in the first byte of 
1700     the result */
1701     aopPut(AOP(res),"#127",0);
1702     size = AOP_SIZE(op) - 1;
1703     offset = 1;
1704
1705     l = aopGet(op->aop,offset++,FALSE,FALSE);
1706     MOVA(l);    
1707
1708     while(size--) {
1709         pic14_emitcode("orl","a,%s",
1710                  aopGet(op->aop,
1711                         offset++,FALSE,FALSE));
1712     }
1713     tlbl = newiTempLabel(NULL);
1714
1715     tlbl = newiTempLabel(NULL);
1716     aopPut(res->aop,one,1);
1717     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1718     aopPut(res->aop,zero,1);
1719     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1720
1721     size = res->aop->size - 2;
1722     offset = 2;    
1723     /* put zeros in the rest */
1724     while (size--) 
1725         aopPut(res->aop,zero,offset++);
1726 }
1727
1728 #if 0
1729 /*-----------------------------------------------------------------*/
1730 /* opIsGptr: returns non-zero if the passed operand is             */   
1731 /* a generic pointer type.                                         */
1732 /*-----------------------------------------------------------------*/ 
1733 static int opIsGptr(operand *op)
1734 {
1735     sym_link *type = operandType(op);
1736     
1737     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1738     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1739     {
1740         return 1;
1741     }
1742     return 0;        
1743 }
1744 #endif
1745
1746 /*-----------------------------------------------------------------*/
1747 /* pic14_getDataSize - get the operand data size                         */
1748 /*-----------------------------------------------------------------*/
1749 int pic14_getDataSize(operand *op)
1750 {
1751     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1752
1753
1754     return AOP_SIZE(op);
1755
1756     // tsd- in the pic port, the genptr size is 1, so this code here
1757     // fails. ( in the 8051 port, the size was 4).
1758 #if 0
1759     int size;
1760     size = AOP_SIZE(op);
1761     if (size == GPTRSIZE)
1762     {
1763         sym_link *type = operandType(op);
1764         if (IS_GENPTR(type))
1765         {
1766             /* generic pointer; arithmetic operations
1767              * should ignore the high byte (pointer type).
1768              */
1769             size--;
1770     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1771         }
1772     }
1773     return size;
1774 #endif
1775 }
1776
1777 /*-----------------------------------------------------------------*/
1778 /* pic14_outAcc - output Acc                                             */
1779 /*-----------------------------------------------------------------*/
1780 void pic14_outAcc(operand *result)
1781 {
1782   int size,offset;
1783   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1784   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1785
1786
1787   size = pic14_getDataSize(result);
1788   if(size){
1789     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1790     size--;
1791     offset = 1;
1792     /* unsigned or positive */
1793     while(size--)
1794       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1795   }
1796
1797 }
1798
1799 /*-----------------------------------------------------------------*/
1800 /* pic14_outBitC - output a bit C                                        */
1801 /*-----------------------------------------------------------------*/
1802 void pic14_outBitC(operand *result)
1803 {
1804
1805     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1806     /* if the result is bit */
1807     if (AOP_TYPE(result) == AOP_CRY) 
1808         aopPut(AOP(result),"c",0);
1809     else {
1810         pic14_emitcode("clr","a  ; %d", __LINE__);
1811         pic14_emitcode("rlc","a");
1812         pic14_outAcc(result);
1813     }
1814 }
1815
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_toBoolean(operand *oper)
1820 {
1821     int size = AOP_SIZE(oper) - 1;
1822     int offset = 1;
1823
1824     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1825
1826     if ( AOP_TYPE(oper) != AOP_ACC) {
1827       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1828     }
1829     while (size--) {
1830       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1831     }
1832 }
1833
1834
1835 /*-----------------------------------------------------------------*/
1836 /* genNot - generate code for ! operation                          */
1837 /*-----------------------------------------------------------------*/
1838 static void genNot (iCode *ic)
1839 {
1840   symbol *tlbl;
1841   sym_link *optype = operandType(IC_LEFT(ic));
1842   int size;
1843
1844   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1845   /* assign asmOps to operand & result */
1846   aopOp (IC_LEFT(ic),ic,FALSE);
1847   aopOp (IC_RESULT(ic),ic,TRUE);
1848
1849   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1850   /* if in bit space then a special case */
1851   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1852     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1853       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1854       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1855     } else {
1856       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1857       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1858       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1859     }
1860     goto release;
1861   }
1862
1863   /* if type float then do float */
1864   if (IS_FLOAT(optype)) {
1865     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1866     goto release;
1867   }
1868
1869   size = AOP_SIZE(IC_RESULT(ic));
1870   if(size == 1) {
1871     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1872     emitpcode(POC_ANDLW,popGetLit(1));
1873     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1874     goto release;
1875   }
1876   pic14_toBoolean(IC_LEFT(ic));
1877
1878   tlbl = newiTempLabel(NULL);
1879   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1880   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1881   pic14_outBitC(IC_RESULT(ic));
1882
1883  release:    
1884   /* release the aops */
1885   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1886   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1887 }
1888
1889
1890 /*-----------------------------------------------------------------*/
1891 /* genCpl - generate code for complement                           */
1892 /*-----------------------------------------------------------------*/
1893 static void genCpl (iCode *ic)
1894 {
1895   operand *left, *result;
1896   int size, offset=0;  
1897
1898
1899   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1900   aopOp((left = IC_LEFT(ic)),ic,FALSE);
1901   aopOp((result=IC_RESULT(ic)),ic,TRUE);
1902
1903   /* if both are in bit space then 
1904      a special case */
1905   if (AOP_TYPE(result) == AOP_CRY &&
1906       AOP_TYPE(left) == AOP_CRY ) { 
1907
1908     pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1909     pic14_emitcode("cpl","c"); 
1910     pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1911     goto release; 
1912   } 
1913
1914   size = AOP_SIZE(result);
1915   while (size--) {
1916
1917     if(AOP_TYPE(left) == AOP_ACC) 
1918       emitpcode(POC_XORLW, popGetLit(0xff));
1919     else
1920       emitpcode(POC_COMFW,popGet(AOP(left),offset));
1921
1922     emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1923
1924   }
1925
1926
1927 release:
1928     /* release the aops */
1929     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1930     freeAsmop(result,NULL,ic,TRUE);
1931 }
1932
1933 /*-----------------------------------------------------------------*/
1934 /* genUminusFloat - unary minus for floating points                */
1935 /*-----------------------------------------------------------------*/
1936 static void genUminusFloat(operand *op,operand *result)
1937 {
1938     int size ,offset =0 ;
1939     char *l;
1940
1941     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1942     /* for this we just need to flip the 
1943     first it then copy the rest in place */
1944     size = AOP_SIZE(op) - 1;
1945     l = aopGet(AOP(op),3,FALSE,FALSE);
1946
1947     MOVA(l);    
1948
1949     pic14_emitcode("cpl","acc.7");
1950     aopPut(AOP(result),"a",3);    
1951
1952     while(size--) {
1953         aopPut(AOP(result),
1954                aopGet(AOP(op),offset,FALSE,FALSE),
1955                offset);
1956         offset++;
1957     }          
1958 }
1959
1960 /*-----------------------------------------------------------------*/
1961 /* genUminus - unary minus code generation                         */
1962 /*-----------------------------------------------------------------*/
1963 static void genUminus (iCode *ic)
1964 {
1965   int size, i;
1966   sym_link *optype, *rtype;
1967
1968
1969   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1970   /* assign asmops */
1971   aopOp(IC_LEFT(ic),ic,FALSE);
1972   aopOp(IC_RESULT(ic),ic,TRUE);
1973
1974   /* if both in bit space then special
1975      case */
1976   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1977       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1978
1979     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1980     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1981     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1982
1983     goto release; 
1984   } 
1985
1986   optype = operandType(IC_LEFT(ic));
1987   rtype = operandType(IC_RESULT(ic));
1988
1989   /* if float then do float stuff */
1990   if (IS_FLOAT(optype)) {
1991     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1992     goto release;
1993   }
1994
1995   /* otherwise subtract from zero by taking the 2's complement */
1996   size = AOP_SIZE(IC_LEFT(ic));
1997
1998   for(i=0; i<size; i++) {
1999     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2000       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2001     else {
2002       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2003       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2004     }
2005   }
2006
2007   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2008   for(i=1; i<size; i++) {
2009     emitSKPNZ;
2010     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2011   }
2012
2013  release:
2014   /* release the aops */
2015   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2016   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2017 }
2018
2019 /*-----------------------------------------------------------------*/
2020 /* saveRegisters - will look for a call and save the registers     */
2021 /*-----------------------------------------------------------------*/
2022 static void saveRegisters(iCode *lic) 
2023 {
2024     int i;
2025     iCode *ic;
2026     bitVect *rsave;
2027     sym_link *dtype;
2028
2029     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2030     /* look for call */
2031     for (ic = lic ; ic ; ic = ic->next) 
2032         if (ic->op == CALL || ic->op == PCALL)
2033             break;
2034
2035     if (!ic) {
2036         fprintf(stderr,"found parameter push with no function call\n");
2037         return ;
2038     }
2039
2040     /* if the registers have been saved already then
2041     do nothing */
2042     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2043         return ;
2044
2045     /* find the registers in use at this time 
2046     and push them away to safety */
2047     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2048                           ic->rUsed);
2049
2050     ic->regsSaved = 1;
2051     if (options.useXstack) {
2052         if (bitVectBitValue(rsave,R0_IDX))
2053             pic14_emitcode("mov","b,r0");
2054         pic14_emitcode("mov","r0,%s",spname);
2055         for (i = 0 ; i < pic14_nRegs ; i++) {
2056             if (bitVectBitValue(rsave,i)) {
2057                 if (i == R0_IDX)
2058                     pic14_emitcode("mov","a,b");
2059                 else
2060                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2061                 pic14_emitcode("movx","@r0,a");
2062                 pic14_emitcode("inc","r0");
2063             }
2064         }
2065         pic14_emitcode("mov","%s,r0",spname);
2066         if (bitVectBitValue(rsave,R0_IDX))
2067             pic14_emitcode("mov","r0,b");           
2068     }// else
2069     //for (i = 0 ; i < pic14_nRegs ; i++) {
2070     //    if (bitVectBitValue(rsave,i))
2071     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2072     //}
2073
2074     dtype = operandType(IC_LEFT(ic));
2075     if (currFunc && dtype && 
2076         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2077         IFFUNC_ISISR(currFunc->type) &&
2078         !ic->bankSaved) 
2079
2080         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2081
2082 }
2083 /*-----------------------------------------------------------------*/
2084 /* unsaveRegisters - pop the pushed registers                      */
2085 /*-----------------------------------------------------------------*/
2086 static void unsaveRegisters (iCode *ic)
2087 {
2088     int i;
2089     bitVect *rsave;
2090
2091     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2092     /* find the registers in use at this time 
2093     and push them away to safety */
2094     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2095                           ic->rUsed);
2096     
2097     if (options.useXstack) {
2098         pic14_emitcode("mov","r0,%s",spname);   
2099         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2100             if (bitVectBitValue(rsave,i)) {
2101                 pic14_emitcode("dec","r0");
2102                 pic14_emitcode("movx","a,@r0");
2103                 if (i == R0_IDX)
2104                     pic14_emitcode("mov","b,a");
2105                 else
2106                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2107             }       
2108
2109         }
2110         pic14_emitcode("mov","%s,r0",spname);
2111         if (bitVectBitValue(rsave,R0_IDX))
2112             pic14_emitcode("mov","r0,b");
2113     } //else
2114     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2115     //    if (bitVectBitValue(rsave,i))
2116     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2117     //}
2118
2119 }  
2120
2121
2122 /*-----------------------------------------------------------------*/
2123 /* pushSide -                                                      */
2124 /*-----------------------------------------------------------------*/
2125 static void pushSide(operand * oper, int size)
2126 {
2127 #if 0
2128         int offset = 0;
2129     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2130         while (size--) {
2131                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2132                 if (AOP_TYPE(oper) != AOP_REG &&
2133                     AOP_TYPE(oper) != AOP_DIR &&
2134                     strcmp(l,"a") ) {
2135                         pic14_emitcode("mov","a,%s",l);
2136                         pic14_emitcode("push","acc");
2137                 } else
2138                         pic14_emitcode("push","%s",l);
2139         }
2140 #endif
2141 }
2142
2143 /*-----------------------------------------------------------------*/
2144 /* assignResultValue -                                             */
2145 /*-----------------------------------------------------------------*/
2146 static void assignResultValue(operand * oper)
2147 {
2148   int size = AOP_SIZE(oper);
2149
2150   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2151
2152   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2153
2154   if(!GpsuedoStkPtr) {
2155     /* The last byte in the assignment is in W */
2156     size--;
2157     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2158     GpsuedoStkPtr++;
2159   }
2160
2161   while (size--) {
2162     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2163     GpsuedoStkPtr++;
2164     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2165   }
2166 }
2167
2168
2169 /*-----------------------------------------------------------------*/
2170 /* genIpush - genrate code for pushing this gets a little complex  */
2171 /*-----------------------------------------------------------------*/
2172 static void genIpush (iCode *ic)
2173 {
2174
2175   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2176 #if 0
2177     int size, offset = 0 ;
2178     char *l;
2179
2180
2181     /* if this is not a parm push : ie. it is spill push 
2182     and spill push is always done on the local stack */
2183     if (!ic->parmPush) {
2184
2185         /* and the item is spilt then do nothing */
2186         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2187             return ;
2188
2189         aopOp(IC_LEFT(ic),ic,FALSE);
2190         size = AOP_SIZE(IC_LEFT(ic));
2191         /* push it on the stack */
2192         while(size--) {
2193             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2194             if (*l == '#') {
2195                 MOVA(l);
2196                 l = "acc";
2197             }
2198             pic14_emitcode("push","%s",l);
2199         }
2200         return ;        
2201     }
2202
2203     /* this is a paramter push: in this case we call
2204     the routine to find the call and save those
2205     registers that need to be saved */   
2206     saveRegisters(ic);
2207
2208     /* then do the push */
2209     aopOp(IC_LEFT(ic),ic,FALSE);
2210
2211
2212         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2213     size = AOP_SIZE(IC_LEFT(ic));
2214
2215     while (size--) {
2216         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2217         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2218             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2219             strcmp(l,"a") ) {
2220             pic14_emitcode("mov","a,%s",l);
2221             pic14_emitcode("push","acc");
2222         } else
2223             pic14_emitcode("push","%s",l);
2224     }       
2225
2226     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2227 #endif
2228 }
2229
2230 /*-----------------------------------------------------------------*/
2231 /* genIpop - recover the registers: can happen only for spilling   */
2232 /*-----------------------------------------------------------------*/
2233 static void genIpop (iCode *ic)
2234 {
2235   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2236 #if 0
2237     int size,offset ;
2238
2239
2240     /* if the temp was not pushed then */
2241     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2242         return ;
2243
2244     aopOp(IC_LEFT(ic),ic,FALSE);
2245     size = AOP_SIZE(IC_LEFT(ic));
2246     offset = (size-1);
2247     while (size--) 
2248         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2249                                    FALSE,TRUE));
2250
2251     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2252 #endif
2253 }
2254
2255 /*-----------------------------------------------------------------*/
2256 /* unsaverbank - restores the resgister bank from stack            */
2257 /*-----------------------------------------------------------------*/
2258 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2259 {
2260   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2261 #if 0
2262     int i;
2263     asmop *aop ;
2264     regs *r = NULL;
2265
2266     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2267     if (popPsw) {
2268         if (options.useXstack) {
2269             aop = newAsmop(0);
2270             r = getFreePtr(ic,&aop,FALSE);
2271             
2272             
2273             pic14_emitcode("mov","%s,_spx",r->name);
2274             pic14_emitcode("movx","a,@%s",r->name);
2275             pic14_emitcode("mov","psw,a");
2276             pic14_emitcode("dec","%s",r->name);
2277             
2278         }else
2279             pic14_emitcode ("pop","psw");
2280     }
2281
2282     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2283         if (options.useXstack) {       
2284             pic14_emitcode("movx","a,@%s",r->name);
2285             //pic14_emitcode("mov","(%s+%d),a",
2286             //       regspic14[i].base,8*bank+regspic14[i].offset);
2287             pic14_emitcode("dec","%s",r->name);
2288
2289         } else 
2290           pic14_emitcode("pop",""); //"(%s+%d)",
2291         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2292     }
2293
2294     if (options.useXstack) {
2295
2296         pic14_emitcode("mov","_spx,%s",r->name);
2297         freeAsmop(NULL,aop,ic,TRUE);
2298
2299     }
2300 #endif 
2301 }
2302
2303 /*-----------------------------------------------------------------*/
2304 /* saverbank - saves an entire register bank on the stack          */
2305 /*-----------------------------------------------------------------*/
2306 static void saverbank (int bank, iCode *ic, bool pushPsw)
2307 {
2308   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2309 #if 0
2310     int i;
2311     asmop *aop ;
2312     regs *r = NULL;
2313
2314     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2315     if (options.useXstack) {
2316
2317         aop = newAsmop(0);
2318         r = getFreePtr(ic,&aop,FALSE);  
2319         pic14_emitcode("mov","%s,_spx",r->name);
2320
2321     }
2322
2323     for (i = 0 ; i < pic14_nRegs ;i++) {
2324         if (options.useXstack) {
2325             pic14_emitcode("inc","%s",r->name);
2326             //pic14_emitcode("mov","a,(%s+%d)",
2327             //         regspic14[i].base,8*bank+regspic14[i].offset);
2328             pic14_emitcode("movx","@%s,a",r->name);           
2329         } else 
2330           pic14_emitcode("push","");// "(%s+%d)",
2331                      //regspic14[i].base,8*bank+regspic14[i].offset);
2332     }
2333     
2334     if (pushPsw) {
2335         if (options.useXstack) {
2336             pic14_emitcode("mov","a,psw");
2337             pic14_emitcode("movx","@%s,a",r->name);     
2338             pic14_emitcode("inc","%s",r->name);
2339             pic14_emitcode("mov","_spx,%s",r->name);       
2340             freeAsmop (NULL,aop,ic,TRUE);
2341             
2342         } else
2343             pic14_emitcode("push","psw");
2344         
2345         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2346     }
2347     ic->bankSaved = 1;
2348 #endif
2349 }
2350
2351 /*-----------------------------------------------------------------*/
2352 /* genCall - generates a call statement                            */
2353 /*-----------------------------------------------------------------*/
2354 static void genCall (iCode *ic)
2355 {
2356   sym_link *dtype;   
2357
2358   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2359
2360   /* if caller saves & we have not saved then */
2361   if (!ic->regsSaved)
2362     saveRegisters(ic);
2363
2364   /* if we are calling a function that is not using
2365      the same register bank then we need to save the
2366      destination registers on the stack */
2367   dtype = operandType(IC_LEFT(ic));
2368   if (currFunc && dtype && 
2369       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2370       IFFUNC_ISISR(currFunc->type) &&
2371       !ic->bankSaved) 
2372
2373     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2374
2375   /* if send set is not empty the assign */
2376   if (_G.sendSet) {
2377     iCode *sic;
2378     /* For the Pic port, there is no data stack.
2379      * So parameters passed to functions are stored
2380      * in registers. (The pCode optimizer will get
2381      * rid of most of these :).
2382      */
2383     int psuedoStkPtr=-1; 
2384     int firstTimeThruLoop = 1;
2385
2386     _G.sendSet = reverseSet(_G.sendSet);
2387
2388     /* First figure how many parameters are getting passed */
2389     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2390          sic = setNextItem(_G.sendSet)) {
2391
2392       aopOp(IC_LEFT(sic),sic,FALSE);
2393       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2394       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2395     }
2396
2397     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2398          sic = setNextItem(_G.sendSet)) {
2399       int size, offset = 0;
2400
2401       aopOp(IC_LEFT(sic),sic,FALSE);
2402       size = AOP_SIZE(IC_LEFT(sic));
2403
2404       while (size--) {
2405         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2406                              AopType(AOP_TYPE(IC_LEFT(sic))));
2407
2408         if(!firstTimeThruLoop) {
2409           /* If this is not the first time we've been through the loop
2410            * then we need to save the parameter in a temporary
2411            * register. The last byte of the last parameter is
2412            * passed in W. */
2413           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2414
2415         }
2416         firstTimeThruLoop=0;
2417
2418         //if (strcmp(l,fReturn[offset])) {
2419         mov2w (AOP(IC_LEFT(sic)),  offset);
2420 /*
2421         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2422              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2423           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2424         else
2425           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2426 */
2427         //}
2428         offset++;
2429       }
2430       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2431     }
2432     _G.sendSet = NULL;
2433   }
2434   /* make the call */
2435   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2436                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2437                                       OP_SYMBOL(IC_LEFT(ic))->name));
2438
2439   GpsuedoStkPtr=0;
2440   /* if we need assign a result value */
2441   if ((IS_ITEMP(IC_RESULT(ic)) && 
2442        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2443         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2444       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2445
2446     _G.accInUse++;
2447     aopOp(IC_RESULT(ic),ic,FALSE);
2448     _G.accInUse--;
2449
2450     assignResultValue(IC_RESULT(ic));
2451
2452     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2453                          AopType(AOP_TYPE(IC_RESULT(ic))));
2454                 
2455     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2456   }
2457
2458   /* adjust the stack for parameters if 
2459      required */
2460   if (ic->parmBytes) {
2461     int i;
2462     if (ic->parmBytes > 3) {
2463       pic14_emitcode("mov","a,%s",spname);
2464       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2465       pic14_emitcode("mov","%s,a",spname);
2466     } else 
2467       for ( i = 0 ; i <  ic->parmBytes ;i++)
2468         pic14_emitcode("dec","%s",spname);
2469
2470   }
2471
2472   /* if register bank was saved then pop them */
2473   if (ic->bankSaved)
2474     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2475
2476   /* if we hade saved some registers then unsave them */
2477   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2478     unsaveRegisters (ic);
2479
2480
2481 }
2482
2483 /*-----------------------------------------------------------------*/
2484 /* genPcall - generates a call by pointer statement                */
2485 /*-----------------------------------------------------------------*/
2486 static void genPcall (iCode *ic)
2487 {
2488     sym_link *dtype;
2489     symbol *rlbl = newiTempLabel(NULL);
2490
2491
2492     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2493     /* if caller saves & we have not saved then */
2494     if (!ic->regsSaved)
2495         saveRegisters(ic);
2496
2497     /* if we are calling a function that is not using
2498     the same register bank then we need to save the
2499     destination registers on the stack */
2500     dtype = operandType(IC_LEFT(ic));
2501     if (currFunc && dtype && 
2502         IFFUNC_ISISR(currFunc->type) &&
2503         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2504         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2505
2506
2507     /* push the return address on to the stack */
2508     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2509     pic14_emitcode("push","acc");    
2510     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2511     pic14_emitcode("push","acc");
2512     
2513     if (options.model == MODEL_FLAT24)
2514     {
2515         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2516         pic14_emitcode("push","acc");    
2517     }
2518
2519     /* now push the calling address */
2520     aopOp(IC_LEFT(ic),ic,FALSE);
2521
2522     pushSide(IC_LEFT(ic), FPTRSIZE);
2523
2524     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2525
2526     /* if send set is not empty the assign */
2527     if (_G.sendSet) {
2528         iCode *sic ;
2529
2530         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2531              sic = setNextItem(_G.sendSet)) {
2532             int size, offset = 0;
2533             aopOp(IC_LEFT(sic),sic,FALSE);
2534             size = AOP_SIZE(IC_LEFT(sic));
2535             while (size--) {
2536                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2537                                 FALSE,FALSE);
2538                 if (strcmp(l,fReturn[offset]))
2539                     pic14_emitcode("mov","%s,%s",
2540                              fReturn[offset],
2541                              l);
2542                 offset++;
2543             }
2544             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2545         }
2546         _G.sendSet = NULL;
2547     }
2548
2549     pic14_emitcode("ret","");
2550     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2551
2552
2553     /* if we need assign a result value */
2554     if ((IS_ITEMP(IC_RESULT(ic)) &&
2555          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2556           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2557         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2558
2559         _G.accInUse++;
2560         aopOp(IC_RESULT(ic),ic,FALSE);
2561         _G.accInUse--;
2562         
2563         assignResultValue(IC_RESULT(ic));
2564
2565         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2566     }
2567
2568     /* adjust the stack for parameters if 
2569     required */
2570     if (ic->parmBytes) {
2571         int i;
2572         if (ic->parmBytes > 3) {
2573             pic14_emitcode("mov","a,%s",spname);
2574             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2575             pic14_emitcode("mov","%s,a",spname);
2576         } else 
2577             for ( i = 0 ; i <  ic->parmBytes ;i++)
2578                 pic14_emitcode("dec","%s",spname);
2579
2580     }
2581
2582     /* if register bank was saved then unsave them */
2583     if (currFunc && dtype && 
2584         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2585         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2586
2587     /* if we hade saved some registers then
2588     unsave them */
2589     if (ic->regsSaved)
2590         unsaveRegisters (ic);
2591
2592 }
2593
2594 /*-----------------------------------------------------------------*/
2595 /* resultRemat - result  is rematerializable                       */
2596 /*-----------------------------------------------------------------*/
2597 static int resultRemat (iCode *ic)
2598 {
2599   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2600   if (SKIP_IC(ic) || ic->op == IFX)
2601     return 0;
2602
2603   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2604     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2605     if (sym->remat && !POINTER_SET(ic)) 
2606       return 1;
2607   }
2608
2609   return 0;
2610 }
2611
2612 #if defined(__BORLANDC__) || defined(_MSC_VER)
2613 #define STRCASECMP stricmp
2614 #else
2615 #define STRCASECMP strcasecmp
2616 #endif
2617
2618 #if 0
2619 /*-----------------------------------------------------------------*/
2620 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2621 /*-----------------------------------------------------------------*/
2622 static bool inExcludeList(char *s)
2623 {
2624   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2625     int i =0;
2626     
2627     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2628     if (options.excludeRegs[i] &&
2629     STRCASECMP(options.excludeRegs[i],"none") == 0)
2630         return FALSE ;
2631
2632     for ( i = 0 ; options.excludeRegs[i]; i++) {
2633         if (options.excludeRegs[i] &&
2634         STRCASECMP(s,options.excludeRegs[i]) == 0)
2635             return TRUE;
2636     }
2637     return FALSE ;
2638 }
2639 #endif
2640
2641 /*-----------------------------------------------------------------*/
2642 /* genFunction - generated code for function entry                 */
2643 /*-----------------------------------------------------------------*/
2644 static void genFunction (iCode *ic)
2645 {
2646     symbol *sym;
2647     sym_link *ftype;
2648
2649     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2650
2651     labelOffset += (max_key+4);
2652     max_key=0;
2653     GpsuedoStkPtr=0;
2654     _G.nRegsSaved = 0;
2655     /* create the function header */
2656     pic14_emitcode(";","-----------------------------------------");
2657     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2658     pic14_emitcode(";","-----------------------------------------");
2659
2660     pic14_emitcode("","%s:",sym->rname);
2661     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2662
2663     ftype = operandType(IC_LEFT(ic));
2664
2665     /* if critical function then turn interrupts off */
2666     if (IFFUNC_ISCRITICAL(ftype))
2667         pic14_emitcode("clr","ea");
2668
2669     /* here we need to generate the equates for the
2670        register bank if required */
2671 #if 0
2672     if (FUNC_REGBANK(ftype) != rbank) {
2673         int i ;
2674
2675         rbank = FUNC_REGBANK(ftype);
2676         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2677             if (strcmp(regspic14[i].base,"0") == 0)
2678                 pic14_emitcode("","%s = 0x%02x",
2679                          regspic14[i].dname,
2680                          8*rbank+regspic14[i].offset);
2681             else
2682                 pic14_emitcode ("","%s = %s + 0x%02x",
2683                           regspic14[i].dname,
2684                           regspic14[i].base,
2685                           8*rbank+regspic14[i].offset);
2686         }
2687     }
2688 #endif
2689
2690     /* if this is an interrupt service routine then
2691     save acc, b, dpl, dph  */
2692     if (IFFUNC_ISISR(sym->type)) {
2693       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2694       emitpcodeNULLop(POC_NOP);
2695       emitpcodeNULLop(POC_NOP);
2696       emitpcodeNULLop(POC_NOP);
2697       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2698       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2699       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2700       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2701
2702       pBlockConvert2ISR(pb);
2703 #if 0  
2704         if (!inExcludeList("acc"))          
2705             pic14_emitcode ("push","acc");      
2706         if (!inExcludeList("b"))
2707             pic14_emitcode ("push","b");
2708         if (!inExcludeList("dpl"))
2709             pic14_emitcode ("push","dpl");
2710         if (!inExcludeList("dph"))
2711             pic14_emitcode ("push","dph");
2712         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2713         {
2714             pic14_emitcode ("push", "dpx");
2715             /* Make sure we're using standard DPTR */
2716             pic14_emitcode ("push", "dps");
2717             pic14_emitcode ("mov", "dps, #0x00");
2718             if (options.stack10bit)
2719             {   
2720                 /* This ISR could conceivably use DPTR2. Better save it. */
2721                 pic14_emitcode ("push", "dpl1");
2722                 pic14_emitcode ("push", "dph1");
2723                 pic14_emitcode ("push", "dpx1");
2724             }
2725         }
2726         /* if this isr has no bank i.e. is going to
2727            run with bank 0 , then we need to save more
2728            registers :-) */
2729         if (!FUNC_REGBANK(sym->type)) {
2730
2731             /* if this function does not call any other
2732                function then we can be economical and
2733                save only those registers that are used */
2734             if (! IFFUNC_HASFCALL(sym->type)) {
2735                 int i;
2736
2737                 /* if any registers used */
2738                 if (sym->regsUsed) {
2739                     /* save the registers used */
2740                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2741                         if (bitVectBitValue(sym->regsUsed,i) ||
2742                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2743                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2744                     }
2745                 }
2746                 
2747             } else {
2748                 /* this function has  a function call cannot
2749                    determines register usage so we will have the
2750                    entire bank */
2751                 saverbank(0,ic,FALSE);
2752             }       
2753         }
2754 #endif
2755     } else {
2756         /* if callee-save to be used for this function
2757            then save the registers being used in this function */
2758         if (IFFUNC_CALLEESAVES(sym->type)) {
2759             int i;
2760             
2761             /* if any registers used */
2762             if (sym->regsUsed) {
2763                 /* save the registers used */
2764                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2765                     if (bitVectBitValue(sym->regsUsed,i) ||
2766                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2767                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2768                         _G.nRegsSaved++;
2769                     }
2770                 }
2771             }
2772         }
2773     }
2774
2775     /* set the register bank to the desired value */
2776     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2777         pic14_emitcode("push","psw");
2778         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2779     }
2780
2781     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2782
2783         if (options.useXstack) {
2784             pic14_emitcode("mov","r0,%s",spname);
2785             pic14_emitcode("mov","a,_bp");
2786             pic14_emitcode("movx","@r0,a");
2787             pic14_emitcode("inc","%s",spname);
2788         }
2789         else
2790         {
2791             /* set up the stack */
2792             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2793         }
2794         pic14_emitcode ("mov","_bp,%s",spname);
2795     }
2796
2797     /* adjust the stack for the function */
2798     if (sym->stack) {
2799
2800         int i = sym->stack;
2801         if (i > 256 ) 
2802             werror(W_STACK_OVERFLOW,sym->name);
2803
2804         if (i > 3 && sym->recvSize < 4) {              
2805
2806             pic14_emitcode ("mov","a,sp");
2807             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2808             pic14_emitcode ("mov","sp,a");
2809            
2810         }
2811         else
2812             while(i--)
2813                 pic14_emitcode("inc","sp");
2814     }
2815
2816      if (sym->xstack) {
2817
2818         pic14_emitcode ("mov","a,_spx");
2819         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2820         pic14_emitcode ("mov","_spx,a");
2821     }    
2822
2823 }
2824
2825 /*-----------------------------------------------------------------*/
2826 /* genEndFunction - generates epilogue for functions               */
2827 /*-----------------------------------------------------------------*/
2828 static void genEndFunction (iCode *ic)
2829 {
2830     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2831
2832     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2833
2834     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2835     {
2836         pic14_emitcode ("mov","%s,_bp",spname);
2837     }
2838
2839     /* if use external stack but some variables were
2840     added to the local stack then decrement the
2841     local stack */
2842     if (options.useXstack && sym->stack) {      
2843         pic14_emitcode("mov","a,sp");
2844         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2845         pic14_emitcode("mov","sp,a");
2846     }
2847
2848
2849     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2850         if (options.useXstack) {
2851             pic14_emitcode("mov","r0,%s",spname);
2852             pic14_emitcode("movx","a,@r0");
2853             pic14_emitcode("mov","_bp,a");
2854             pic14_emitcode("dec","%s",spname);
2855         }
2856         else
2857         {
2858             pic14_emitcode ("pop","_bp");
2859         }
2860     }
2861
2862     /* restore the register bank  */    
2863     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2864         pic14_emitcode ("pop","psw");
2865
2866     if (IFFUNC_ISISR(sym->type)) {
2867
2868         /* now we need to restore the registers */
2869         /* if this isr has no bank i.e. is going to
2870            run with bank 0 , then we need to save more
2871            registers :-) */
2872         if (!FUNC_REGBANK(sym->type)) {
2873             
2874             /* if this function does not call any other
2875                function then we can be economical and
2876                save only those registers that are used */
2877             if (! IFFUNC_HASFCALL(sym->type)) {
2878                 int i;
2879                 
2880                 /* if any registers used */
2881                 if (sym->regsUsed) {
2882                     /* save the registers used */
2883                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2884                         if (bitVectBitValue(sym->regsUsed,i) ||
2885                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2886                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2887                     }
2888                 }
2889                 
2890             } else {
2891                 /* this function has  a function call cannot
2892                    determines register usage so we will have the
2893                    entire bank */
2894                 unsaverbank(0,ic,FALSE);
2895             }       
2896         }
2897 #if 0
2898         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2899         {
2900             if (options.stack10bit)
2901             {
2902                 pic14_emitcode ("pop", "dpx1");
2903                 pic14_emitcode ("pop", "dph1");
2904                 pic14_emitcode ("pop", "dpl1");
2905             }   
2906             pic14_emitcode ("pop", "dps");
2907             pic14_emitcode ("pop", "dpx");
2908         }
2909         if (!inExcludeList("dph"))
2910             pic14_emitcode ("pop","dph");
2911         if (!inExcludeList("dpl"))
2912             pic14_emitcode ("pop","dpl");
2913         if (!inExcludeList("b"))
2914             pic14_emitcode ("pop","b");
2915         if (!inExcludeList("acc"))
2916             pic14_emitcode ("pop","acc");
2917
2918         if (IFFUNC_ISCRITICAL(sym->type))
2919             pic14_emitcode("setb","ea");
2920 #endif
2921
2922         /* if debug then send end of function */
2923 /*      if (options.debug && currFunc) { */
2924         if (currFunc) {
2925             _G.debugLine = 1;
2926             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2927                      FileBaseName(ic->filename),currFunc->lastLine,
2928                      ic->level,ic->block); 
2929             if (IS_STATIC(currFunc->etype))         
2930                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2931             else
2932                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2933             _G.debugLine = 0;
2934         }
2935         
2936         pic14_emitcode ("reti","");
2937
2938         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2939         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2940         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2941         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2942         emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2943         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2944
2945         emitpcodeNULLop(POC_RETFIE);
2946
2947     }
2948     else {
2949         if (IFFUNC_ISCRITICAL(sym->type))
2950             pic14_emitcode("setb","ea");
2951         
2952         if (IFFUNC_CALLEESAVES(sym->type)) {
2953             int i;
2954             
2955             /* if any registers used */
2956             if (sym->regsUsed) {
2957                 /* save the registers used */
2958                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2959                     if (bitVectBitValue(sym->regsUsed,i) ||
2960                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2961                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2962                 }
2963             }
2964             
2965         }
2966
2967         /* if debug then send end of function */
2968         if (currFunc) {
2969             _G.debugLine = 1;
2970             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2971                      FileBaseName(ic->filename),currFunc->lastLine,
2972                      ic->level,ic->block); 
2973             if (IS_STATIC(currFunc->etype))         
2974                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2975             else
2976                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2977             _G.debugLine = 0;
2978         }
2979
2980         pic14_emitcode ("return","");
2981         emitpcodeNULLop(POC_RETURN);
2982
2983         /* Mark the end of a function */
2984         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2985     }
2986
2987 }
2988
2989 /*-----------------------------------------------------------------*/
2990 /* genRet - generate code for return statement                     */
2991 /*-----------------------------------------------------------------*/
2992 static void genRet (iCode *ic)
2993 {
2994   int size,offset = 0 , pushed = 0;
2995     
2996   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2997   /* if we have no return value then
2998      just generate the "ret" */
2999   if (!IC_LEFT(ic)) 
3000     goto jumpret;       
3001     
3002   /* we have something to return then
3003      move the return value into place */
3004   aopOp(IC_LEFT(ic),ic,FALSE);
3005   size = AOP_SIZE(IC_LEFT(ic));
3006     
3007   while (size--) {
3008     char *l ;
3009     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3010       /* #NOCHANGE */
3011       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3012                  FALSE,TRUE);
3013       pic14_emitcode("push","%s",l);
3014       pushed++;
3015     } else {
3016       l = aopGet(AOP(IC_LEFT(ic)),offset,
3017                  FALSE,FALSE);
3018       if (strcmp(fReturn[offset],l)) {
3019         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3020             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3021           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3022         }else {
3023           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3024         }
3025         if(size) {
3026           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3027         }
3028         offset++;
3029       }
3030     }
3031   }    
3032
3033   if (pushed) {
3034     while(pushed) {
3035       pushed--;
3036       if (strcmp(fReturn[pushed],"a"))
3037         pic14_emitcode("pop",fReturn[pushed]);
3038       else
3039         pic14_emitcode("pop","acc");
3040     }
3041   }
3042   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3043     
3044  jumpret:
3045   /* generate a jump to the return label
3046      if the next is not the return statement */
3047   if (!(ic->next && ic->next->op == LABEL &&
3048         IC_LABEL(ic->next) == returnLabel)) {
3049         
3050     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3051     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3052   }
3053     
3054 }
3055
3056 /*-----------------------------------------------------------------*/
3057 /* genLabel - generates a label                                    */
3058 /*-----------------------------------------------------------------*/
3059 static void genLabel (iCode *ic)
3060 {
3061     /* special case never generate */
3062     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3063     if (IC_LABEL(ic) == entryLabel)
3064         return ;
3065
3066     emitpLabel(IC_LABEL(ic)->key);
3067     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3068 }
3069
3070 /*-----------------------------------------------------------------*/
3071 /* genGoto - generates a goto                                      */
3072 /*-----------------------------------------------------------------*/
3073 //tsd
3074 static void genGoto (iCode *ic)
3075 {
3076   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3077   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3078 }
3079
3080
3081 /*-----------------------------------------------------------------*/
3082 /* genMultbits :- multiplication of bits                           */
3083 /*-----------------------------------------------------------------*/
3084 static void genMultbits (operand *left, 
3085                          operand *right, 
3086                          operand *result)
3087 {
3088   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3089
3090   if(!pic14_sameRegs(AOP(result),AOP(right)))
3091     emitpcode(POC_BSF,  popGet(AOP(result),0));
3092
3093   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3094   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3095   emitpcode(POC_BCF,  popGet(AOP(result),0));
3096
3097 }
3098
3099
3100 /*-----------------------------------------------------------------*/
3101 /* genMultOneByte : 8 bit multiplication & division                */
3102 /*-----------------------------------------------------------------*/
3103 static void genMultOneByte (operand *left,
3104                             operand *right,
3105                             operand *result)
3106 {
3107   sym_link *opetype = operandType(result);
3108
3109   // symbol *lbl ;
3110   int size,offset;
3111
3112   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3113   DEBUGpic14_AopType(__LINE__,left,right,result);
3114   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3115
3116   /* (if two literals, the value is computed before) */
3117   /* if one literal, literal on the right */
3118   if (AOP_TYPE(left) == AOP_LIT){
3119     operand *t = right;
3120     right = left;
3121     left = t;
3122   }
3123
3124   size = AOP_SIZE(result);
3125   if(size == 1) {
3126
3127     if (AOP_TYPE(right) == AOP_LIT){
3128       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3129                      aopGet(AOP(right),0,FALSE,FALSE), 
3130                      aopGet(AOP(left),0,FALSE,FALSE), 
3131                      aopGet(AOP(result),0,FALSE,FALSE));
3132       pic14_emitcode("call","genMultLit");
3133     } else {
3134       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3135                      aopGet(AOP(right),0,FALSE,FALSE), 
3136                      aopGet(AOP(left),0,FALSE,FALSE), 
3137                      aopGet(AOP(result),0,FALSE,FALSE));
3138       pic14_emitcode("call","genMult8X8_8");
3139
3140     }
3141     genMult8X8_8 (left, right,result);
3142
3143
3144     /* signed or unsigned */
3145     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3146     //l = aopGet(AOP(left),0,FALSE,FALSE);
3147     //MOVA(l);       
3148     //pic14_emitcode("mul","ab");
3149     /* if result size = 1, mul signed = mul unsigned */
3150     //aopPut(AOP(result),"a",0);
3151
3152   } else {  // (size > 1)
3153
3154     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3155                    aopGet(AOP(right),0,FALSE,FALSE), 
3156                    aopGet(AOP(left),0,FALSE,FALSE), 
3157                    aopGet(AOP(result),0,FALSE,FALSE));
3158
3159     if (SPEC_USIGN(opetype)){
3160       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3161       genUMult8X8_16 (left, right, result, NULL);
3162
3163       if (size > 2) {
3164         /* for filling the MSBs */
3165         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3166         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3167       }
3168     }
3169     else{
3170       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3171
3172       pic14_emitcode("mov","a,b");
3173
3174       /* adjust the MSB if left or right neg */
3175
3176       /* if one literal */
3177       if (AOP_TYPE(right) == AOP_LIT){
3178         pic14_emitcode("multiply ","right is a lit");
3179         /* AND literal negative */
3180         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3181           /* adjust MSB (c==0 after mul) */
3182           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3183         }
3184       }
3185       else{
3186         genSMult8X8_16 (left, right, result, NULL);
3187       }
3188
3189       if(size > 2){
3190         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3191         /* get the sign */
3192         pic14_emitcode("rlc","a");
3193         pic14_emitcode("subb","a,acc");
3194       }
3195     }
3196
3197     size -= 2;   
3198     offset = 2;
3199     if (size > 0)
3200       while (size--)
3201         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3202     //aopPut(AOP(result),"a",offset++);
3203   }
3204 }
3205
3206 /*-----------------------------------------------------------------*/
3207 /* genMult - generates code for multiplication                     */
3208 /*-----------------------------------------------------------------*/
3209 static void genMult (iCode *ic)
3210 {
3211     operand *left = IC_LEFT(ic);
3212     operand *right = IC_RIGHT(ic);
3213     operand *result= IC_RESULT(ic);   
3214
3215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3216     /* assign the amsops */
3217     aopOp (left,ic,FALSE);
3218     aopOp (right,ic,FALSE);
3219     aopOp (result,ic,TRUE);
3220
3221   DEBUGpic14_AopType(__LINE__,left,right,result);
3222
3223     /* special cases first */
3224     /* both are bits */
3225     if (AOP_TYPE(left) == AOP_CRY &&
3226         AOP_TYPE(right)== AOP_CRY) {
3227         genMultbits(left,right,result);
3228         goto release ;
3229     }
3230
3231     /* if both are of size == 1 */
3232     if (AOP_SIZE(left) == 1 &&
3233         AOP_SIZE(right) == 1 ) {
3234         genMultOneByte(left,right,result);
3235         goto release ;
3236     }
3237
3238     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3239
3240     /* should have been converted to function call */
3241     //assert(0) ;
3242
3243 release :
3244     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3245     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3246     freeAsmop(result,NULL,ic,TRUE); 
3247 }
3248
3249 /*-----------------------------------------------------------------*/
3250 /* genDivbits :- division of bits                                  */
3251 /*-----------------------------------------------------------------*/
3252 static void genDivbits (operand *left, 
3253                         operand *right, 
3254                         operand *result)
3255 {
3256
3257     char *l;
3258
3259     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3260     /* the result must be bit */    
3261     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3262     l = aopGet(AOP(left),0,FALSE,FALSE);
3263
3264     MOVA(l);    
3265
3266     pic14_emitcode("div","ab");
3267     pic14_emitcode("rrc","a");
3268     aopPut(AOP(result),"c",0);
3269 }
3270
3271 /*-----------------------------------------------------------------*/
3272 /* genDivOneByte : 8 bit division                                  */
3273 /*-----------------------------------------------------------------*/
3274 static void genDivOneByte (operand *left,
3275                            operand *right,
3276                            operand *result)
3277 {
3278     sym_link *opetype = operandType(result);
3279     char *l ;
3280     symbol *lbl ;
3281     int size,offset;
3282
3283     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3284     size = AOP_SIZE(result) - 1;
3285     offset = 1;
3286     /* signed or unsigned */
3287     if (SPEC_USIGN(opetype)) {
3288         /* unsigned is easy */
3289         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3290         l = aopGet(AOP(left),0,FALSE,FALSE);
3291         MOVA(l);        
3292         pic14_emitcode("div","ab");
3293         aopPut(AOP(result),"a",0);
3294         while (size--)
3295             aopPut(AOP(result),zero,offset++);
3296         return ;
3297     }
3298
3299     /* signed is a little bit more difficult */
3300
3301     /* save the signs of the operands */
3302     l = aopGet(AOP(left),0,FALSE,FALSE);    
3303     MOVA(l);    
3304     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3305     pic14_emitcode("push","acc"); /* save it on the stack */
3306
3307     /* now sign adjust for both left & right */
3308     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3309     MOVA(l);       
3310     lbl = newiTempLabel(NULL);
3311     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3312     pic14_emitcode("cpl","a");   
3313     pic14_emitcode("inc","a");
3314     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3315     pic14_emitcode("mov","b,a");
3316
3317     /* sign adjust left side */
3318     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3319     MOVA(l);
3320
3321     lbl = newiTempLabel(NULL);
3322     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3323     pic14_emitcode("cpl","a");
3324     pic14_emitcode("inc","a");
3325     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3326
3327     /* now the division */
3328     pic14_emitcode("div","ab");
3329     /* we are interested in the lower order
3330     only */
3331     pic14_emitcode("mov","b,a");
3332     lbl = newiTempLabel(NULL);
3333     pic14_emitcode("pop","acc");   
3334     /* if there was an over flow we don't 
3335     adjust the sign of the result */
3336     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3337     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3338     CLRC;
3339     pic14_emitcode("clr","a");
3340     pic14_emitcode("subb","a,b");
3341     pic14_emitcode("mov","b,a");
3342     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3343
3344     /* now we are done */
3345     aopPut(AOP(result),"b",0);
3346     if(size > 0){
3347         pic14_emitcode("mov","c,b.7");
3348         pic14_emitcode("subb","a,acc");   
3349     }
3350     while (size--)
3351         aopPut(AOP(result),"a",offset++);
3352
3353 }
3354
3355 /*-----------------------------------------------------------------*/
3356 /* genDiv - generates code for division                            */
3357 /*-----------------------------------------------------------------*/
3358 static void genDiv (iCode *ic)
3359 {
3360     operand *left = IC_LEFT(ic);
3361     operand *right = IC_RIGHT(ic);
3362     operand *result= IC_RESULT(ic);   
3363
3364     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3365     /* assign the amsops */
3366     aopOp (left,ic,FALSE);
3367     aopOp (right,ic,FALSE);
3368     aopOp (result,ic,TRUE);
3369
3370     /* special cases first */
3371     /* both are bits */
3372     if (AOP_TYPE(left) == AOP_CRY &&
3373         AOP_TYPE(right)== AOP_CRY) {
3374         genDivbits(left,right,result);
3375         goto release ;
3376     }
3377
3378     /* if both are of size == 1 */
3379     if (AOP_SIZE(left) == 1 &&
3380         AOP_SIZE(right) == 1 ) {
3381         genDivOneByte(left,right,result);
3382         goto release ;
3383     }
3384
3385     /* should have been converted to function call */
3386     assert(0);
3387 release :
3388     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3389     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3390     freeAsmop(result,NULL,ic,TRUE); 
3391 }
3392
3393 /*-----------------------------------------------------------------*/
3394 /* genModbits :- modulus of bits                                   */
3395 /*-----------------------------------------------------------------*/
3396 static void genModbits (operand *left, 
3397                         operand *right, 
3398                         operand *result)
3399 {
3400
3401     char *l;
3402
3403     /* the result must be bit */    
3404     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3405     l = aopGet(AOP(left),0,FALSE,FALSE);
3406
3407     MOVA(l);       
3408
3409     pic14_emitcode("div","ab");
3410     pic14_emitcode("mov","a,b");
3411     pic14_emitcode("rrc","a");
3412     aopPut(AOP(result),"c",0);
3413 }
3414
3415 /*-----------------------------------------------------------------*/
3416 /* genModOneByte : 8 bit modulus                                   */
3417 /*-----------------------------------------------------------------*/
3418 static void genModOneByte (operand *left,
3419                            operand *right,
3420                            operand *result)
3421 {
3422     sym_link *opetype = operandType(result);
3423     char *l ;
3424     symbol *lbl ;
3425
3426     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3427     /* signed or unsigned */
3428     if (SPEC_USIGN(opetype)) {
3429         /* unsigned is easy */
3430         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3431         l = aopGet(AOP(left),0,FALSE,FALSE);
3432         MOVA(l);    
3433         pic14_emitcode("div","ab");
3434         aopPut(AOP(result),"b",0);
3435         return ;
3436     }
3437
3438     /* signed is a little bit more difficult */
3439
3440     /* save the signs of the operands */
3441     l = aopGet(AOP(left),0,FALSE,FALSE);    
3442     MOVA(l);
3443
3444     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3445     pic14_emitcode("push","acc"); /* save it on the stack */
3446
3447     /* now sign adjust for both left & right */
3448     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3449     MOVA(l);
3450
3451     lbl = newiTempLabel(NULL);
3452     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3453     pic14_emitcode("cpl","a");   
3454     pic14_emitcode("inc","a");
3455     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3456     pic14_emitcode("mov","b,a"); 
3457
3458     /* sign adjust left side */
3459     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3460     MOVA(l);
3461
3462     lbl = newiTempLabel(NULL);
3463     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3464     pic14_emitcode("cpl","a");   
3465     pic14_emitcode("inc","a");
3466     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3467
3468     /* now the multiplication */
3469     pic14_emitcode("div","ab");
3470     /* we are interested in the lower order
3471     only */
3472     lbl = newiTempLabel(NULL);
3473     pic14_emitcode("pop","acc");   
3474     /* if there was an over flow we don't 
3475     adjust the sign of the result */
3476     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3477     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3478     CLRC ;
3479     pic14_emitcode("clr","a");
3480     pic14_emitcode("subb","a,b");
3481     pic14_emitcode("mov","b,a");
3482     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3483
3484     /* now we are done */
3485     aopPut(AOP(result),"b",0);
3486
3487 }
3488
3489 /*-----------------------------------------------------------------*/
3490 /* genMod - generates code for division                            */
3491 /*-----------------------------------------------------------------*/
3492 static void genMod (iCode *ic)
3493 {
3494     operand *left = IC_LEFT(ic);
3495     operand *right = IC_RIGHT(ic);
3496     operand *result= IC_RESULT(ic);  
3497
3498     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3499     /* assign the amsops */
3500     aopOp (left,ic,FALSE);
3501     aopOp (right,ic,FALSE);
3502     aopOp (result,ic,TRUE);
3503
3504     /* special cases first */
3505     /* both are bits */
3506     if (AOP_TYPE(left) == AOP_CRY &&
3507         AOP_TYPE(right)== AOP_CRY) {
3508         genModbits(left,right,result);
3509         goto release ;
3510     }
3511
3512     /* if both are of size == 1 */
3513     if (AOP_SIZE(left) == 1 &&
3514         AOP_SIZE(right) == 1 ) {
3515         genModOneByte(left,right,result);
3516         goto release ;
3517     }
3518
3519     /* should have been converted to function call */
3520     assert(0);
3521
3522 release :
3523     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3524     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3525     freeAsmop(result,NULL,ic,TRUE); 
3526 }
3527
3528 /*-----------------------------------------------------------------*/
3529 /* genIfxJump :- will create a jump depending on the ifx           */
3530 /*-----------------------------------------------------------------*/
3531 /*
3532   note: May need to add parameter to indicate when a variable is in bit space.
3533 */
3534 static void genIfxJump (iCode *ic, char *jval)
3535 {
3536
3537     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3538     /* if true label then we jump if condition
3539     supplied is true */
3540     if ( IC_TRUE(ic) ) {
3541
3542         if(strcmp(jval,"a") == 0)
3543           emitSKPZ;
3544         else if (strcmp(jval,"c") == 0)
3545           emitSKPC;
3546         else {
3547           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3548           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3549         }
3550
3551         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3552         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3553
3554     }
3555     else {
3556         /* false label is present */
3557         if(strcmp(jval,"a") == 0)
3558           emitSKPNZ;
3559         else if (strcmp(jval,"c") == 0)
3560           emitSKPNC;
3561         else {
3562           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3563           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3564         }
3565
3566         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3567         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3568
3569     }
3570
3571
3572     /* mark the icode as generated */
3573     ic->generated = 1;
3574 }
3575
3576 /*-----------------------------------------------------------------*/
3577 /* genSkip                                                         */
3578 /*-----------------------------------------------------------------*/
3579 static void genSkip(iCode *ifx,int status_bit)
3580 {
3581   if(!ifx)
3582     return;
3583
3584   if ( IC_TRUE(ifx) ) {
3585     switch(status_bit) {
3586     case 'z':
3587       emitSKPNZ;
3588       break;
3589
3590     case 'c':
3591       emitSKPNC;
3592       break;
3593
3594     case 'd':
3595       emitSKPDC;
3596       break;
3597
3598     }
3599
3600     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3601     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3602
3603   } else {
3604
3605     switch(status_bit) {
3606
3607     case 'z':
3608       emitSKPZ;
3609       break;
3610
3611     case 'c':
3612       emitSKPC;
3613       break;
3614
3615     case 'd':
3616       emitSKPDC;
3617       break;
3618     }
3619     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3620     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3621
3622   }
3623
3624 }
3625
3626 /*-----------------------------------------------------------------*/
3627 /* genSkipc                                                        */
3628 /*-----------------------------------------------------------------*/
3629 static void genSkipc(resolvedIfx *rifx)
3630 {
3631   if(!rifx)
3632     return;
3633
3634   if(rifx->condition)
3635     emitSKPC;
3636   else
3637     emitSKPNC;
3638
3639   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3640   rifx->generated = 1;
3641 }
3642
3643 /*-----------------------------------------------------------------*/
3644 /* genSkipz2                                                       */
3645 /*-----------------------------------------------------------------*/
3646 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3647 {
3648   if(!rifx)
3649     return;
3650
3651   if( (rifx->condition ^ invert_condition) & 1)
3652     emitSKPZ;
3653   else
3654     emitSKPNZ;
3655
3656   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3657   rifx->generated = 1;
3658 }
3659
3660 /*-----------------------------------------------------------------*/
3661 /* genSkipz                                                        */
3662 /*-----------------------------------------------------------------*/
3663 static void genSkipz(iCode *ifx, int condition)
3664 {
3665   if(!ifx)
3666     return;
3667
3668   if(condition)
3669     emitSKPNZ;
3670   else
3671     emitSKPZ;
3672
3673   if ( IC_TRUE(ifx) )
3674     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3675   else
3676     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3677
3678   if ( IC_TRUE(ifx) )
3679     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3680   else
3681     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3682
3683 }
3684 /*-----------------------------------------------------------------*/
3685 /* genSkipCond                                                     */
3686 /*-----------------------------------------------------------------*/
3687 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3688 {
3689   if(!rifx)
3690     return;
3691
3692   if(rifx->condition)
3693     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3694   else
3695     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3696
3697
3698   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3699   rifx->generated = 1;
3700 }
3701
3702 #if 0
3703 /*-----------------------------------------------------------------*/
3704 /* genChkZeroes :- greater or less than comparison                 */
3705 /*     For each byte in a literal that is zero, inclusive or the   */
3706 /*     the corresponding byte in the operand with W                */
3707 /*     returns true if any of the bytes are zero                   */
3708 /*-----------------------------------------------------------------*/
3709 static int genChkZeroes(operand *op, int lit,  int size)
3710 {
3711
3712   int i;
3713   int flag =1;
3714
3715   while(size--) {
3716     i = (lit >> (size*8)) & 0xff;
3717
3718     if(i==0) {
3719       if(flag) 
3720         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3721       else
3722         emitpcode(POC_IORFW, popGet(AOP(op),size));
3723       flag = 0;
3724     }
3725   }
3726
3727   return (flag==0);
3728 }
3729 #endif
3730
3731 /*-----------------------------------------------------------------*/
3732 /* genCmp :- greater or less than comparison                       */
3733 /*-----------------------------------------------------------------*/
3734 static void genCmp (operand *left,operand *right,
3735                     operand *result, iCode *ifx, int sign)
3736 {
3737   int size; //, offset = 0 ;
3738   unsigned long lit = 0L,i = 0;
3739   resolvedIfx rFalseIfx;
3740   //  resolvedIfx rTrueIfx;
3741   symbol *truelbl;
3742   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3743 /*
3744   if(ifx) {
3745     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3746     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3747   }
3748 */
3749
3750   resolveIfx(&rFalseIfx,ifx);
3751   truelbl  = newiTempLabel(NULL);
3752   size = max(AOP_SIZE(left),AOP_SIZE(right));
3753
3754   DEBUGpic14_AopType(__LINE__,left,right,result);
3755
3756 #define _swapp
3757
3758   /* if literal is on the right then swap with left */
3759   if ((AOP_TYPE(right) == AOP_LIT)) {
3760     operand *tmp = right ;
3761     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3762     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3763 #ifdef _swapp
3764
3765     lit = (lit - 1) & mask;
3766     right = left;
3767     left = tmp;
3768     rFalseIfx.condition ^= 1;
3769 #endif
3770
3771   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3772     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3773   }
3774
3775
3776   //if(IC_TRUE(ifx) == NULL)
3777   /* if left & right are bit variables */
3778   if (AOP_TYPE(left) == AOP_CRY &&
3779       AOP_TYPE(right) == AOP_CRY ) {
3780     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3781     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3782   } else {
3783     /* subtract right from left if at the
3784        end the carry flag is set then we know that
3785        left is greater than right */
3786
3787     //    {
3788
3789     symbol *lbl  = newiTempLabel(NULL);
3790
3791 #ifndef _swapp
3792     if(AOP_TYPE(right) == AOP_LIT) {
3793
3794       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3795
3796       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3797
3798       /* special cases */
3799
3800       if(lit == 0) {
3801
3802         if(sign != 0) 
3803           genSkipCond(&rFalseIfx,left,size-1,7);
3804         else 
3805           /* no need to compare to 0...*/
3806           /* NOTE: this is a de-generate compare that most certainly 
3807            *       creates some dead code. */
3808           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3809
3810         if(ifx) ifx->generated = 1;
3811         return;
3812
3813       }
3814       size--;
3815
3816       if(size == 0) {
3817         //i = (lit >> (size*8)) & 0xff;
3818         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3819         
3820         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3821
3822         i = ((0-lit) & 0xff);
3823         if(sign) {
3824           if( i == 0x81) { 
3825             /* lit is 0x7f, all signed chars are less than
3826              * this except for 0x7f itself */
3827             emitpcode(POC_XORLW, popGetLit(0x7f));
3828             genSkipz2(&rFalseIfx,0);
3829           } else {
3830             emitpcode(POC_ADDLW, popGetLit(0x80));
3831             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3832             genSkipc(&rFalseIfx);
3833           }
3834
3835         } else {
3836           if(lit == 1) {
3837             genSkipz2(&rFalseIfx,1);
3838           } else {
3839             emitpcode(POC_ADDLW, popGetLit(i));
3840             genSkipc(&rFalseIfx);
3841           }
3842         }
3843
3844         if(ifx) ifx->generated = 1;
3845         return;
3846       }
3847
3848       /* chars are out of the way. now do ints and longs */
3849
3850
3851       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3852         
3853       /* special cases */
3854
3855       if(sign) {
3856
3857         if(lit == 0) {
3858           genSkipCond(&rFalseIfx,left,size,7);
3859           if(ifx) ifx->generated = 1;
3860           return;
3861         }
3862
3863         if(lit <0x100) {
3864           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3865
3866           //rFalseIfx.condition ^= 1;
3867           //genSkipCond(&rFalseIfx,left,size,7);
3868           //rFalseIfx.condition ^= 1;
3869
3870           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3871           if(rFalseIfx.condition)
3872             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3873           else
3874             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3875
3876           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3877           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3878           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3879
3880           while(size > 1)
3881             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3882
3883           if(rFalseIfx.condition) {
3884             emitSKPZ;
3885             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3886
3887           } else {
3888             emitSKPNZ;
3889           }
3890
3891           genSkipc(&rFalseIfx);
3892           emitpLabel(truelbl->key);
3893           if(ifx) ifx->generated = 1;
3894           return;
3895
3896         }
3897
3898         if(size == 1) {
3899
3900           if( (lit & 0xff) == 0) {
3901             /* lower byte is zero */
3902             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3903             i = ((lit >> 8) & 0xff) ^0x80;
3904             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3905             emitpcode(POC_ADDLW, popGetLit( 0x80));
3906             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3907             genSkipc(&rFalseIfx);
3908
3909
3910             if(ifx) ifx->generated = 1;
3911             return;
3912
3913           }
3914         } else {
3915           /* Special cases for signed longs */
3916           if( (lit & 0xffffff) == 0) {
3917             /* lower byte is zero */
3918             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3919             i = ((lit >> 8*3) & 0xff) ^0x80;
3920             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3921             emitpcode(POC_ADDLW, popGetLit( 0x80));
3922             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3923             genSkipc(&rFalseIfx);
3924
3925
3926             if(ifx) ifx->generated = 1;
3927             return;
3928
3929           }
3930
3931         }
3932
3933
3934         if(lit & (0x80 << (size*8))) {
3935           /* lit is negative */
3936           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3937
3938           //genSkipCond(&rFalseIfx,left,size,7);
3939
3940           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3941
3942           if(rFalseIfx.condition)
3943             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3944           else
3945             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3946
3947
3948         } else {
3949           /* lit is positive */
3950           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3951           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3952           if(rFalseIfx.condition)
3953             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3954           else
3955             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3956
3957         }
3958
3959         /*
3960           This works, but is only good for ints.
3961           It also requires a "known zero" register.
3962           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3963           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3964           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3965           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3966           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3967           genSkipc(&rFalseIfx);
3968
3969           emitpLabel(truelbl->key);
3970           if(ifx) ifx->generated = 1;
3971           return;
3972         **/
3973           
3974         /* There are no more special cases, so perform a general compare */
3975   
3976         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3977         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3978
3979         while(size--) {
3980
3981           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3982           emitSKPNZ;
3983           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3984         }
3985         //rFalseIfx.condition ^= 1;
3986         genSkipc(&rFalseIfx);
3987
3988         emitpLabel(truelbl->key);
3989
3990         if(ifx) ifx->generated = 1;
3991         return;
3992
3993
3994       }
3995
3996
3997       /* sign is out of the way. So now do an unsigned compare */
3998       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3999
4000
4001       /* General case - compare to an unsigned literal on the right.*/
4002
4003       i = (lit >> (size*8)) & 0xff;
4004       emitpcode(POC_MOVLW, popGetLit(i));
4005       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4006       while(size--) {
4007         i = (lit >> (size*8)) & 0xff;
4008
4009         if(i) {
4010           emitpcode(POC_MOVLW, popGetLit(i));
4011           emitSKPNZ;
4012           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4013         } else {
4014           /* this byte of the lit is zero, 
4015            *if it's not the last then OR in the variable */
4016           if(size)
4017             emitpcode(POC_IORFW, popGet(AOP(left),size));
4018         }
4019       }
4020
4021
4022       emitpLabel(lbl->key);
4023       //if(emitFinalCheck)
4024       genSkipc(&rFalseIfx);
4025       if(sign)
4026         emitpLabel(truelbl->key);
4027
4028       if(ifx) ifx->generated = 1;
4029       return;
4030
4031
4032     }
4033 #endif  // _swapp
4034
4035     if(AOP_TYPE(left) == AOP_LIT) {
4036       //symbol *lbl = newiTempLabel(NULL);
4037
4038       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4039
4040
4041       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4042
4043       /* Special cases */
4044       if((lit == 0) && (sign == 0)){
4045
4046         size--;
4047         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4048         while(size) 
4049           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4050
4051         genSkipz2(&rFalseIfx,0);
4052         if(ifx) ifx->generated = 1;
4053         return;
4054       }
4055
4056       if(size==1) {
4057         /* Special cases */
4058         lit &= 0xff;
4059         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4060           /* degenerate compare can never be true */
4061           if(rFalseIfx.condition == 0)
4062             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4063
4064           if(ifx) ifx->generated = 1;
4065           return;
4066         }
4067
4068         if(sign) {
4069           /* signed comparisons to a literal byte */
4070
4071           int lp1 = (lit+1) & 0xff;
4072
4073           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4074           switch (lp1) {
4075           case 0:
4076             rFalseIfx.condition ^= 1;
4077             genSkipCond(&rFalseIfx,right,0,7);
4078             break;
4079           case 0x7f:
4080             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4081             emitpcode(POC_XORLW, popGetLit(0x7f));
4082             genSkipz2(&rFalseIfx,1);
4083             break;
4084           default:
4085             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4086             emitpcode(POC_ADDLW, popGetLit(0x80));
4087             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4088             rFalseIfx.condition ^= 1;
4089             genSkipc(&rFalseIfx);
4090             break;
4091           }
4092           if(ifx) ifx->generated = 1;
4093         } else {
4094           /* unsigned comparisons to a literal byte */
4095
4096           switch(lit & 0xff ) {
4097           case 0:
4098             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4099             genSkipz2(&rFalseIfx,0);
4100             if(ifx) ifx->generated = 1;
4101             break;
4102           case 0x7f:
4103             rFalseIfx.condition ^= 1;
4104             genSkipCond(&rFalseIfx,right,0,7);
4105             if(ifx) ifx->generated = 1;
4106             break;
4107
4108           default:
4109             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4110             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4111             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4112             rFalseIfx.condition ^= 1;
4113             if (AOP_TYPE(result) == AOP_CRY) {
4114               genSkipc(&rFalseIfx);
4115               if(ifx) ifx->generated = 1;
4116             } else {
4117               DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4118               emitpcode(POC_CLRF, popGet(AOP(result),0));
4119               emitpcode(POC_RLF, popGet(AOP(result),0));
4120               emitpcode(POC_MOVLW, popGetLit(0x01));
4121               emitpcode(POC_XORWF, popGet(AOP(result),0));
4122             }         
4123             break;
4124           }
4125         }
4126
4127         //goto check_carry;
4128         return;
4129
4130       } else {
4131
4132         /* Size is greater than 1 */
4133
4134         if(sign) {
4135           int lp1 = lit+1;
4136
4137           size--;
4138
4139           if(lp1 == 0) {
4140             /* this means lit = 0xffffffff, or -1 */
4141
4142
4143             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4144             rFalseIfx.condition ^= 1;
4145             genSkipCond(&rFalseIfx,right,size,7);
4146             if(ifx) ifx->generated = 1;
4147             return;
4148           }
4149
4150           if(lit == 0) {
4151             int s = size;
4152
4153             if(rFalseIfx.condition) {
4154               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4155               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4156             }
4157
4158             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4159             while(size--)
4160               emitpcode(POC_IORFW, popGet(AOP(right),size));
4161
4162
4163             emitSKPZ;
4164             if(rFalseIfx.condition) {
4165               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4166               emitpLabel(truelbl->key);
4167             }else {
4168               rFalseIfx.condition ^= 1;
4169               genSkipCond(&rFalseIfx,right,s,7);
4170             }
4171
4172             if(ifx) ifx->generated = 1;
4173             return;
4174           }
4175
4176           if((size == 1) &&  (0 == (lp1&0xff))) {
4177             /* lower byte of signed word is zero */
4178             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4179             i = ((lp1 >> 8) & 0xff) ^0x80;
4180             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4181             emitpcode(POC_ADDLW, popGetLit( 0x80));
4182             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4183             rFalseIfx.condition ^= 1;
4184             genSkipc(&rFalseIfx);
4185
4186
4187             if(ifx) ifx->generated = 1;
4188             return;
4189           }
4190
4191           if(lit & (0x80 << (size*8))) {
4192             /* Lit is less than zero */
4193             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4194             //rFalseIfx.condition ^= 1;
4195             //genSkipCond(&rFalseIfx,left,size,7);
4196             //rFalseIfx.condition ^= 1;
4197             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4198             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4199
4200             if(rFalseIfx.condition)
4201               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4202             else
4203               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4204
4205
4206           } else {
4207             /* Lit is greater than or equal to zero */
4208             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4209             //rFalseIfx.condition ^= 1;
4210             //genSkipCond(&rFalseIfx,right,size,7);
4211             //rFalseIfx.condition ^= 1;
4212
4213             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4215
4216             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4217             if(rFalseIfx.condition)
4218               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4219             else
4220               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4221
4222           }
4223
4224
4225           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4226           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4227
4228           while(size--) {
4229
4230             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4231             emitSKPNZ;
4232             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4233           }
4234           rFalseIfx.condition ^= 1;
4235           //rFalseIfx.condition = 1;
4236           genSkipc(&rFalseIfx);
4237
4238           emitpLabel(truelbl->key);
4239
4240           if(ifx) ifx->generated = 1;
4241           return;
4242           // end of if (sign)
4243         } else {
4244
4245           /* compare word or long to an unsigned literal on the right.*/
4246
4247
4248           size--;
4249           if(lit < 0xff) {
4250             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4251             switch (lit) {
4252             case 0:
4253               break; /* handled above */
4254 /*
4255             case 0xff:
4256               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4257               while(size--)
4258                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4259               genSkipz2(&rFalseIfx,0);
4260               break;
4261 */
4262             default:
4263               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4264               while(--size)
4265                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4266
4267               emitSKPZ;
4268               if(rFalseIfx.condition)
4269                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4270               else
4271                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4272
4273
4274               emitpcode(POC_MOVLW, popGetLit(lit+1));
4275               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4276
4277               rFalseIfx.condition ^= 1;
4278               genSkipc(&rFalseIfx);
4279             }
4280
4281             emitpLabel(truelbl->key);
4282
4283             if(ifx) ifx->generated = 1;
4284             return;
4285           }
4286
4287
4288           lit++;
4289           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4290           i = (lit >> (size*8)) & 0xff;
4291
4292           emitpcode(POC_MOVLW, popGetLit(i));
4293           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4294
4295           while(size--) {
4296             i = (lit >> (size*8)) & 0xff;
4297
4298             if(i) {
4299               emitpcode(POC_MOVLW, popGetLit(i));
4300               emitSKPNZ;
4301               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4302             } else {
4303               /* this byte of the lit is zero, 
4304                *if it's not the last then OR in the variable */
4305               if(size)
4306                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4307             }
4308           }
4309
4310
4311           emitpLabel(lbl->key);
4312
4313           rFalseIfx.condition ^= 1;
4314           genSkipc(&rFalseIfx);
4315         }
4316
4317         if(sign)
4318           emitpLabel(truelbl->key);
4319         if(ifx) ifx->generated = 1;
4320         return;
4321       }
4322     }
4323     /* Compare two variables */
4324
4325     DEBUGpic14_emitcode(";sign","%d",sign);
4326
4327     size--;
4328     if(sign) {
4329       /* Sigh. thus sucks... */
4330       if(size) {
4331         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4332         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4333         emitpcode(POC_MOVLW, popGetLit(0x80));
4334         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4335         emitpcode(POC_XORFW, popGet(AOP(right),size));
4336         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4337       } else {
4338         /* Signed char comparison */
4339         /* Special thanks to Nikolai Golovchenko for this snippet */
4340         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4341         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4342         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4343         emitpcode(POC_XORFW, popGet(AOP(left),0));
4344         emitpcode(POC_XORFW, popGet(AOP(right),0));
4345         emitpcode(POC_ADDLW, popGetLit(0x80));
4346
4347         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4348         genSkipc(&rFalseIfx);
4349           
4350         if(ifx) ifx->generated = 1;
4351         return;
4352       }
4353
4354     } else {
4355
4356       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4357       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4358     }
4359
4360
4361     /* The rest of the bytes of a multi-byte compare */
4362     while (size) {
4363
4364       emitSKPZ;
4365       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4366       size--;
4367
4368       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4369       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4370
4371
4372     }
4373
4374     emitpLabel(lbl->key);
4375
4376     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4377     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4378         (AOP_TYPE(result) == AOP_REG)) {
4379       emitpcode(POC_CLRF, popGet(AOP(result),0));
4380       emitpcode(POC_RLF, popGet(AOP(result),0));
4381     } else {
4382       genSkipc(&rFalseIfx);
4383     }         
4384     //genSkipc(&rFalseIfx);
4385     if(ifx) ifx->generated = 1;
4386
4387     return;
4388
4389   }
4390
4391   // check_carry:
4392   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4393     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4394     pic14_outBitC(result);
4395   } else {
4396     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4397     /* if the result is used in the next
4398        ifx conditional branch then generate
4399        code a little differently */
4400     if (ifx )
4401       genIfxJump (ifx,"c");
4402     else
4403       pic14_outBitC(result);
4404     /* leave the result in acc */
4405   }
4406
4407 }
4408
4409 /*-----------------------------------------------------------------*/
4410 /* genCmpGt :- greater than comparison                             */
4411 /*-----------------------------------------------------------------*/
4412 static void genCmpGt (iCode *ic, iCode *ifx)
4413 {
4414     operand *left, *right, *result;
4415     sym_link *letype , *retype;
4416     int sign ;
4417
4418     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4419     left = IC_LEFT(ic);
4420     right= IC_RIGHT(ic);
4421     result = IC_RESULT(ic);
4422
4423     letype = getSpec(operandType(left));
4424     retype =getSpec(operandType(right));
4425     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4426     /* assign the amsops */
4427     aopOp (left,ic,FALSE);
4428     aopOp (right,ic,FALSE);
4429     aopOp (result,ic,TRUE);
4430
4431     genCmp(right, left, result, ifx, sign);
4432
4433     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4434     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4435     freeAsmop(result,NULL,ic,TRUE); 
4436 }
4437
4438 /*-----------------------------------------------------------------*/
4439 /* genCmpLt - less than comparisons                                */
4440 /*-----------------------------------------------------------------*/
4441 static void genCmpLt (iCode *ic, iCode *ifx)
4442 {
4443     operand *left, *right, *result;
4444     sym_link *letype , *retype;
4445     int sign ;
4446
4447     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4448     left = IC_LEFT(ic);
4449     right= IC_RIGHT(ic);
4450     result = IC_RESULT(ic);
4451
4452     letype = getSpec(operandType(left));
4453     retype =getSpec(operandType(right));
4454     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4455
4456     /* assign the amsops */
4457     aopOp (left,ic,FALSE);
4458     aopOp (right,ic,FALSE);
4459     aopOp (result,ic,TRUE);
4460
4461     genCmp(left, right, result, ifx, sign);
4462
4463     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4464     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4465     freeAsmop(result,NULL,ic,TRUE); 
4466 }
4467
4468 /*-----------------------------------------------------------------*/
4469 /* genc16bit2lit - compare a 16 bit value to a literal             */
4470 /*-----------------------------------------------------------------*/
4471 static void genc16bit2lit(operand *op, int lit, int offset)
4472 {
4473   int i;
4474
4475   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4476   if( (lit&0xff) == 0) 
4477     i=1;
4478   else
4479     i=0;
4480
4481   switch( BYTEofLONG(lit,i)) { 
4482   case 0:
4483     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4484     break;
4485   case 1:
4486     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4487     break;
4488   case 0xff:
4489     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4490     break;
4491   default:
4492     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4493     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4494   }
4495
4496   i ^= 1;
4497
4498   switch( BYTEofLONG(lit,i)) { 
4499   case 0:
4500     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4501     break;
4502   case 1:
4503     emitSKPNZ;
4504     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4505     break;
4506   case 0xff:
4507     emitSKPNZ;
4508     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4509     break;
4510   default:
4511     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4512     emitSKPNZ;
4513     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4514
4515   }
4516
4517 }
4518
4519 /*-----------------------------------------------------------------*/
4520 /* gencjneshort - compare and jump if not equal                    */
4521 /*-----------------------------------------------------------------*/
4522 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4523 {
4524   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4525   int offset = 0;
4526   int res_offset = 0;  /* the result may be a different size then left or right */
4527   int res_size = AOP_SIZE(result);
4528   resolvedIfx rIfx;
4529   symbol *lbl;
4530
4531   unsigned long lit = 0L;
4532   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4533   DEBUGpic14_AopType(__LINE__,left,right,result);
4534   if(result)
4535     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4536   resolveIfx(&rIfx,ifx);
4537   lbl =  newiTempLabel(NULL);
4538
4539
4540   /* if the left side is a literal or 
4541      if the right is in a pointer register and left 
4542      is not */
4543   if ((AOP_TYPE(left) == AOP_LIT) || 
4544       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4545     operand *t = right;
4546     right = left;
4547     left = t;
4548   }
4549   if(AOP_TYPE(right) == AOP_LIT)
4550     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4551
4552   /* if the right side is a literal then anything goes */
4553   if (AOP_TYPE(right) == AOP_LIT &&
4554       AOP_TYPE(left) != AOP_DIR ) {
4555     switch(size) {
4556     case 2:
4557       genc16bit2lit(left, lit, 0);
4558       emitSKPNZ;
4559       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4560       break;
4561     default:
4562       while (size--) {
4563         if(lit & 0xff) {
4564           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4565           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4566         } else {
4567           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4568         }
4569
4570         emitSKPNZ;
4571         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4572         offset++;
4573         if(res_offset < res_size-1)
4574           res_offset++;
4575         lit >>= 8;
4576       }
4577       break;
4578     }
4579   }
4580
4581   /* if the right side is in a register or in direct space or
4582      if the left is a pointer register & right is not */    
4583   else if (AOP_TYPE(right) == AOP_REG ||
4584            AOP_TYPE(right) == AOP_DIR || 
4585            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4586            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4587     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4588     int lbl_key = lbl->key;
4589
4590     if(result) {
4591       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4592       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4593     }else {
4594       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4595       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4596               __FUNCTION__,__LINE__);
4597       return;
4598     }
4599
4600 /*     switch(size) { */
4601 /*     case 2: */
4602 /*       genc16bit2lit(left, lit, 0); */
4603 /*       emitSKPNZ; */
4604 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4605 /*       break; */
4606 /*     default: */
4607     while (size--) {
4608       int emit_skip=1;
4609       if((AOP_TYPE(left) == AOP_DIR) && 
4610          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4611
4612         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4613         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4614
4615       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4616             
4617         switch (lit & 0xff) {
4618         case 0:
4619           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4620           break;
4621         case 1:
4622           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4623           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4624           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4625           emit_skip=0;
4626           break;
4627         case 0xff:
4628           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4629           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4631           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4632           emit_skip=0;
4633           break;
4634         default:
4635           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4636           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4637         }
4638         lit >>= 8;
4639
4640       } else {
4641         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4642       }
4643       if(emit_skip) {
4644         if(AOP_TYPE(result) == AOP_CRY) {
4645           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4646           if(rIfx.condition)
4647             emitSKPNZ;
4648           else
4649             emitSKPZ;
4650           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4651         } else {
4652           /* fix me. probably need to check result size too */
4653           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4654           if(rIfx.condition)
4655             emitSKPZ;
4656           else
4657             emitSKPNZ;
4658           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4659           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4660         }
4661         if(ifx)
4662           ifx->generated=1;
4663       }
4664       emit_skip++;
4665       offset++;
4666       if(res_offset < res_size-1)
4667         res_offset++;
4668     }
4669 /*       break; */
4670 /*     } */
4671   } else if(AOP_TYPE(right) == AOP_REG &&
4672             AOP_TYPE(left) != AOP_DIR){
4673
4674     while(size--) {
4675       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4676       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4677       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4678       if(rIfx.condition)
4679         emitSKPNZ;
4680       else
4681         emitSKPZ;
4682       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4683       offset++;
4684       if(res_offset < res_size-1)
4685         res_offset++;
4686     }
4687       
4688   }else{
4689     /* right is a pointer reg need both a & b */
4690     while(size--) {
4691       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4692       if(strcmp(l,"b"))
4693         pic14_emitcode("mov","b,%s",l);
4694       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4695       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4696       offset++;
4697     }
4698   }
4699
4700   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4701   if(!rIfx.condition)
4702     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4703
4704   emitpLabel(lbl->key);
4705
4706   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4707
4708   if(ifx)
4709     ifx->generated = 1;
4710 }
4711
4712 #if 0
4713 /*-----------------------------------------------------------------*/
4714 /* gencjne - compare and jump if not equal                         */
4715 /*-----------------------------------------------------------------*/
4716 static void gencjne(operand *left, operand *right, iCode *ifx)
4717 {
4718     symbol *tlbl  = newiTempLabel(NULL);
4719
4720     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4721     gencjneshort(left, right, lbl);
4722
4723     pic14_emitcode("mov","a,%s",one);
4724     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4725     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4726     pic14_emitcode("clr","a");
4727     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4728
4729     emitpLabel(lbl->key);
4730     emitpLabel(tlbl->key);
4731
4732 }
4733 #endif
4734
4735 /*-----------------------------------------------------------------*/
4736 /* genCmpEq - generates code for equal to                          */
4737 /*-----------------------------------------------------------------*/
4738 static void genCmpEq (iCode *ic, iCode *ifx)
4739 {
4740     operand *left, *right, *result;
4741     unsigned long lit = 0L;
4742     int size,offset=0;
4743
4744     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4745
4746     if(ifx)
4747       DEBUGpic14_emitcode ("; ifx is non-null","");
4748     else
4749       DEBUGpic14_emitcode ("; ifx is null","");
4750
4751     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4752     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4753     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4754
4755     size = max(AOP_SIZE(left),AOP_SIZE(right));
4756
4757     DEBUGpic14_AopType(__LINE__,left,right,result);
4758
4759     /* if literal, literal on the right or 
4760     if the right is in a pointer register and left 
4761     is not */
4762     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4763         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4764       operand *tmp = right ;
4765       right = left;
4766       left = tmp;
4767     }
4768
4769
4770     if(ifx && !AOP_SIZE(result)){
4771         symbol *tlbl;
4772         /* if they are both bit variables */
4773         if (AOP_TYPE(left) == AOP_CRY &&
4774             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4775             if(AOP_TYPE(right) == AOP_LIT){
4776                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4777                 if(lit == 0L){
4778                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779                     pic14_emitcode("cpl","c");
4780                 } else if(lit == 1L) {
4781                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4782                 } else {
4783                     pic14_emitcode("clr","c");
4784                 }
4785                 /* AOP_TYPE(right) == AOP_CRY */
4786             } else {
4787                 symbol *lbl = newiTempLabel(NULL);
4788                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4790                 pic14_emitcode("cpl","c");
4791                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4792             }
4793             /* if true label then we jump if condition
4794             supplied is true */
4795             tlbl = newiTempLabel(NULL);
4796             if ( IC_TRUE(ifx) ) {
4797                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4798                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4799             } else {
4800                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4801                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4802             }
4803             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4804
4805             {
4806               /* left and right are both bit variables, result is carry */
4807               resolvedIfx rIfx;
4808               
4809               resolveIfx(&rIfx,ifx);
4810
4811               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4812               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4813               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4814               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4815               genSkipz2(&rIfx,0);
4816             }
4817         } else {
4818
4819           /* They're not both bit variables. Is the right a literal? */
4820           if(AOP_TYPE(right) == AOP_LIT) {
4821             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4822             
4823             switch(size) {
4824
4825             case 1:
4826               switch(lit & 0xff) {
4827               case 1:
4828                 if ( IC_TRUE(ifx) ) {
4829                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4830                   emitSKPNZ;
4831                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4832                 } else {
4833                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4834                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4835                 }
4836                 break;
4837               case 0xff:
4838                 if ( IC_TRUE(ifx) ) {
4839                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4840                   emitSKPNZ;
4841                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4842                 } else {
4843                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4844                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4845                 }
4846                 break;
4847               default:
4848                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4849                 if(lit)
4850                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4851                 genSkip(ifx,'z');
4852               }
4853
4854
4855               /* end of size == 1 */
4856               break;
4857               
4858             case 2:
4859               genc16bit2lit(left,lit,offset);
4860               genSkip(ifx,'z');
4861               break;
4862               /* end of size == 2 */
4863
4864             default:
4865               /* size is 4 */
4866               if(lit==0) {
4867                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4868                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4869                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4870                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4871
4872               } else {
4873
4874                 /* search for patterns that can be optimized */
4875
4876                 genc16bit2lit(left,lit,0);
4877                 lit >>= 16;
4878                 if(lit) {
4879                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4880                   //genSkip(ifx,'z');
4881                   genc16bit2lit(left,lit,2);
4882                 } else {
4883                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4884                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4885
4886                 }
4887                 
4888               }
4889
4890               genSkip(ifx,'z');
4891             }
4892           
4893             ifx->generated = 1;
4894             goto release ;
4895             
4896
4897           } else if(AOP_TYPE(right) == AOP_CRY ) {
4898             /* we know the left is not a bit, but that the right is */
4899             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4900             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4901                       popGet(AOP(right),offset));
4902             emitpcode(POC_XORLW,popGetLit(1));
4903
4904             /* if the two are equal, then W will be 0 and the Z bit is set
4905              * we could test Z now, or go ahead and check the high order bytes if
4906              * the variable we're comparing is larger than a byte. */
4907
4908             while(--size)
4909               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4910
4911             if ( IC_TRUE(ifx) ) {
4912               emitSKPNZ;
4913               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4914               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4915             } else {
4916               emitSKPZ;
4917               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4918               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4919             }
4920
4921           } else {
4922             /* They're both variables that are larger than bits */
4923             int s = size;
4924
4925             tlbl = newiTempLabel(NULL);
4926
4927             while(size--) {
4928               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4929               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4930
4931               if ( IC_TRUE(ifx) ) {
4932                 if(size) {
4933                   emitSKPZ;
4934                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4935                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4936                 } else {
4937                   emitSKPNZ;
4938                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4939                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4940                 }
4941               } else {
4942                 emitSKPZ;
4943                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4944                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4945               }
4946               offset++;
4947             }
4948             if(s>1 && IC_TRUE(ifx)) {
4949               emitpLabel(tlbl->key);
4950               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4951             }
4952           }
4953         }
4954         /* mark the icode as generated */
4955         ifx->generated = 1;
4956         goto release ;
4957     }
4958
4959     /* if they are both bit variables */
4960     if (AOP_TYPE(left) == AOP_CRY &&
4961         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4962         if(AOP_TYPE(right) == AOP_LIT){
4963             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4964             if(lit == 0L){
4965                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966                 pic14_emitcode("cpl","c");
4967             } else if(lit == 1L) {
4968                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4969             } else {
4970                 pic14_emitcode("clr","c");
4971             }
4972             /* AOP_TYPE(right) == AOP_CRY */
4973         } else {
4974             symbol *lbl = newiTempLabel(NULL);
4975             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4977             pic14_emitcode("cpl","c");
4978             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4979         }
4980         /* c = 1 if egal */
4981         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4982             pic14_outBitC(result);
4983             goto release ;
4984         }
4985         if (ifx) {
4986             genIfxJump (ifx,"c");
4987             goto release ;
4988         }
4989         /* if the result is used in an arithmetic operation
4990         then put the result in place */
4991         pic14_outBitC(result);
4992     } else {
4993       
4994       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4995       gencjne(left,right,result,ifx);
4996 /*
4997       if(ifx) 
4998         gencjne(left,right,newiTempLabel(NULL));
4999       else {
5000         if(IC_TRUE(ifx)->key)
5001           gencjne(left,right,IC_TRUE(ifx)->key);
5002         else
5003           gencjne(left,right,IC_FALSE(ifx)->key);
5004         ifx->generated = 1;
5005         goto release ;
5006       }
5007       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5008         aopPut(AOP(result),"a",0);
5009         goto release ;
5010       }
5011
5012       if (ifx) {
5013         genIfxJump (ifx,"a");
5014         goto release ;
5015       }
5016 */
5017       /* if the result is used in an arithmetic operation
5018          then put the result in place */
5019 /*
5020       if (AOP_TYPE(result) != AOP_CRY) 
5021         pic14_outAcc(result);
5022 */
5023       /* leave the result in acc */
5024     }
5025
5026 release:
5027     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5028     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029     freeAsmop(result,NULL,ic,TRUE);
5030 }
5031
5032 /*-----------------------------------------------------------------*/
5033 /* ifxForOp - returns the icode containing the ifx for operand     */
5034 /*-----------------------------------------------------------------*/
5035 static iCode *ifxForOp ( operand *op, iCode *ic )
5036 {
5037     /* if true symbol then needs to be assigned */
5038     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5039     if (IS_TRUE_SYMOP(op))
5040         return NULL ;
5041
5042     /* if this has register type condition and
5043     the next instruction is ifx with the same operand
5044     and live to of the operand is upto the ifx only then */
5045     if (ic->next &&
5046         ic->next->op == IFX &&
5047         IC_COND(ic->next)->key == op->key &&
5048         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5049         return ic->next;
5050
5051     if (ic->next &&
5052         ic->next->op == IFX &&
5053         IC_COND(ic->next)->key == op->key) {
5054       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5055       return ic->next;
5056     }
5057
5058     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5059     if (ic->next &&
5060         ic->next->op == IFX)
5061       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5062
5063     if (ic->next &&
5064         ic->next->op == IFX &&
5065         IC_COND(ic->next)->key == op->key) {
5066       DEBUGpic14_emitcode ("; "," key is okay");
5067       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5068                            OP_SYMBOL(op)->liveTo,
5069                            ic->next->seq);
5070     }
5071
5072
5073     return NULL;
5074 }
5075 /*-----------------------------------------------------------------*/
5076 /* genAndOp - for && operation                                     */
5077 /*-----------------------------------------------------------------*/
5078 static void genAndOp (iCode *ic)
5079 {
5080     operand *left,*right, *result;
5081 /*     symbol *tlbl; */
5082
5083     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5084     /* note here that && operations that are in an
5085     if statement are taken away by backPatchLabels
5086     only those used in arthmetic operations remain */
5087     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5088     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5089     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5090
5091     DEBUGpic14_AopType(__LINE__,left,right,result);
5092
5093     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5094     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5095     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5096
5097     /* if both are bit variables */
5098 /*     if (AOP_TYPE(left) == AOP_CRY && */
5099 /*         AOP_TYPE(right) == AOP_CRY ) { */
5100 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5101 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5102 /*         pic14_outBitC(result); */
5103 /*     } else { */
5104 /*         tlbl = newiTempLabel(NULL); */
5105 /*         pic14_toBoolean(left);     */
5106 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5107 /*         pic14_toBoolean(right); */
5108 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5109 /*         pic14_outBitAcc(result); */
5110 /*     } */
5111
5112     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5113     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5114     freeAsmop(result,NULL,ic,TRUE);
5115 }
5116
5117
5118 /*-----------------------------------------------------------------*/
5119 /* genOrOp - for || operation                                      */
5120 /*-----------------------------------------------------------------*/
5121 /*
5122   tsd pic port -
5123   modified this code, but it doesn't appear to ever get called
5124 */
5125
5126 static void genOrOp (iCode *ic)
5127 {
5128     operand *left,*right, *result;
5129     symbol *tlbl;
5130
5131     /* note here that || operations that are in an
5132     if statement are taken away by backPatchLabels
5133     only those used in arthmetic operations remain */
5134     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5135     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5136     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5137     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5138
5139     DEBUGpic14_AopType(__LINE__,left,right,result);
5140
5141     /* if both are bit variables */
5142     if (AOP_TYPE(left) == AOP_CRY &&
5143         AOP_TYPE(right) == AOP_CRY ) {
5144       pic14_emitcode("clrc","");
5145       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5146                AOP(left)->aopu.aop_dir,
5147                AOP(left)->aopu.aop_dir);
5148       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5149                AOP(right)->aopu.aop_dir,
5150                AOP(right)->aopu.aop_dir);
5151       pic14_emitcode("setc","");
5152
5153     } else {
5154         tlbl = newiTempLabel(NULL);
5155         pic14_toBoolean(left);
5156         emitSKPZ;
5157         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5158         pic14_toBoolean(right);
5159         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5160
5161         pic14_outBitAcc(result);
5162     }
5163
5164     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5165     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5166     freeAsmop(result,NULL,ic,TRUE);            
5167 }
5168
5169 /*-----------------------------------------------------------------*/
5170 /* isLiteralBit - test if lit == 2^n                               */
5171 /*-----------------------------------------------------------------*/
5172 static int isLiteralBit(unsigned long lit)
5173 {
5174     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5175     0x100L,0x200L,0x400L,0x800L,
5176     0x1000L,0x2000L,0x4000L,0x8000L,
5177     0x10000L,0x20000L,0x40000L,0x80000L,
5178     0x100000L,0x200000L,0x400000L,0x800000L,
5179     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5180     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5181     int idx;
5182     
5183     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5184     for(idx = 0; idx < 32; idx++)
5185         if(lit == pw[idx])
5186             return idx+1;
5187     return 0;
5188 }
5189
5190 /*-----------------------------------------------------------------*/
5191 /* continueIfTrue -                                                */
5192 /*-----------------------------------------------------------------*/
5193 static void continueIfTrue (iCode *ic)
5194 {
5195     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5196     if(IC_TRUE(ic))
5197         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5198     ic->generated = 1;
5199 }
5200
5201 /*-----------------------------------------------------------------*/
5202 /* jmpIfTrue -                                                     */
5203 /*-----------------------------------------------------------------*/
5204 static void jumpIfTrue (iCode *ic)
5205 {
5206     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5207     if(!IC_TRUE(ic))
5208         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5209     ic->generated = 1;
5210 }
5211
5212 /*-----------------------------------------------------------------*/
5213 /* jmpTrueOrFalse -                                                */
5214 /*-----------------------------------------------------------------*/
5215 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5216 {
5217     // ugly but optimized by peephole
5218     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5219     if(IC_TRUE(ic)){
5220         symbol *nlbl = newiTempLabel(NULL);
5221         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5222         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5223         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5224         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5225     }
5226     else{
5227         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5228         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5229     }
5230     ic->generated = 1;
5231 }
5232
5233 /*-----------------------------------------------------------------*/
5234 /* genAnd  - code for and                                          */
5235 /*-----------------------------------------------------------------*/
5236 static void genAnd (iCode *ic, iCode *ifx)
5237 {
5238   operand *left, *right, *result;
5239   int size, offset=0;  
5240   unsigned long lit = 0L;
5241   int bytelit = 0;
5242   resolvedIfx rIfx;
5243
5244
5245   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5246   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5247   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5248   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5249
5250   resolveIfx(&rIfx,ifx);
5251
5252   /* if left is a literal & right is not then exchange them */
5253   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5254       AOP_NEEDSACC(left)) {
5255     operand *tmp = right ;
5256     right = left;
5257     left = tmp;
5258   }
5259
5260   /* if result = right then exchange them */
5261   if(pic14_sameRegs(AOP(result),AOP(right))){
5262     operand *tmp = right ;
5263     right = left;
5264     left = tmp;
5265   }
5266
5267   /* if right is bit then exchange them */
5268   if (AOP_TYPE(right) == AOP_CRY &&
5269       AOP_TYPE(left) != AOP_CRY){
5270     operand *tmp = right ;
5271     right = left;
5272     left = tmp;
5273   }
5274   if(AOP_TYPE(right) == AOP_LIT)
5275     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5276
5277   size = AOP_SIZE(result);
5278
5279   DEBUGpic14_AopType(__LINE__,left,right,result);
5280
5281   // if(bit & yy)
5282   // result = bit & yy;
5283   if (AOP_TYPE(left) == AOP_CRY){
5284     // c = bit & literal;
5285     if(AOP_TYPE(right) == AOP_LIT){
5286       if(lit & 1) {
5287         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5288           // no change
5289           goto release;
5290         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5291       } else {
5292         // bit(result) = 0;
5293         if(size && (AOP_TYPE(result) == AOP_CRY)){
5294           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5295           goto release;
5296         }
5297         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5298           jumpIfTrue(ifx);
5299           goto release;
5300         }
5301         pic14_emitcode("clr","c");
5302       }
5303     } else {
5304       if (AOP_TYPE(right) == AOP_CRY){
5305         // c = bit & bit;
5306         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5307         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5308       } else {
5309         // c = bit & val;
5310         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5311         // c = lsb
5312         pic14_emitcode("rrc","a");
5313         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5314       }
5315     }
5316     // bit = c
5317     // val = c
5318     if(size)
5319       pic14_outBitC(result);
5320     // if(bit & ...)
5321     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5322       genIfxJump(ifx, "c");           
5323     goto release ;
5324   }
5325
5326   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5327   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5328   if((AOP_TYPE(right) == AOP_LIT) &&
5329      (AOP_TYPE(result) == AOP_CRY) &&
5330      (AOP_TYPE(left) != AOP_CRY)){
5331     int posbit = isLiteralBit(lit);
5332     /* left &  2^n */
5333     if(posbit){
5334       posbit--;
5335       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5336       // bit = left & 2^n
5337       if(size)
5338         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5339       // if(left &  2^n)
5340       else{
5341         if(ifx){
5342 /*
5343           if(IC_TRUE(ifx)) {
5344             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5345             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5346           } else {
5347             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5348             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5349           }
5350 */
5351           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5352                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5353           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5354           
5355           ifx->generated = 1;
5356         }
5357         goto release;
5358       }
5359     } else {
5360       symbol *tlbl = newiTempLabel(NULL);
5361       int sizel = AOP_SIZE(left);
5362       if(size)
5363         pic14_emitcode("setb","c");
5364       while(sizel--){
5365         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5366           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5367           // byte ==  2^n ?
5368           if((posbit = isLiteralBit(bytelit)) != 0)
5369             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5370           else{
5371             if(bytelit != 0x0FFL)
5372               pic14_emitcode("anl","a,%s",
5373                              aopGet(AOP(right),offset,FALSE,TRUE));
5374             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5375           }
5376         }
5377         offset++;
5378       }
5379       // bit = left & literal
5380       if(size){
5381         pic14_emitcode("clr","c");
5382         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5383       }
5384       // if(left & literal)
5385       else{
5386         if(ifx)
5387           jmpTrueOrFalse(ifx, tlbl);
5388         goto release ;
5389       }
5390     }
5391     pic14_outBitC(result);
5392     goto release ;
5393   }
5394
5395   /* if left is same as result */
5396   if(pic14_sameRegs(AOP(result),AOP(left))){
5397     int know_W = -1;
5398     for(;size--; offset++,lit>>=8) {
5399       if(AOP_TYPE(right) == AOP_LIT){
5400         switch(lit & 0xff) {
5401         case 0x00:
5402           /*  and'ing with 0 has clears the result */
5403           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5404           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5405           break;
5406         case 0xff:
5407           /* and'ing with 0xff is a nop when the result and left are the same */
5408           break;
5409
5410         default:
5411           {
5412             int p = my_powof2( (~lit) & 0xff );
5413             if(p>=0) {
5414               /* only one bit is set in the literal, so use a bcf instruction */
5415               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5416               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5417
5418             } else {
5419               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5420               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5421               if(know_W != (lit&0xff))
5422                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5423               know_W = lit &0xff;
5424               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5425             }
5426           }    
5427         }
5428       } else {
5429         if (AOP_TYPE(left) == AOP_ACC) {
5430           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5431         } else {                    
5432           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5433           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5434
5435         }
5436       }
5437     }
5438
5439   } else {
5440     // left & result in different registers
5441     if(AOP_TYPE(result) == AOP_CRY){
5442       // result = bit
5443       // if(size), result in bit
5444       // if(!size && ifx), conditional oper: if(left & right)
5445       symbol *tlbl = newiTempLabel(NULL);
5446       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5447       if(size)
5448         pic14_emitcode("setb","c");
5449       while(sizer--){
5450         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5451         pic14_emitcode("anl","a,%s",
5452                        aopGet(AOP(left),offset,FALSE,FALSE));
5453         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5454         offset++;
5455       }
5456       if(size){
5457         CLRC;
5458         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5459         pic14_outBitC(result);
5460       } else if(ifx)
5461         jmpTrueOrFalse(ifx, tlbl);
5462     } else {
5463       for(;(size--);offset++) {
5464         // normal case
5465         // result = left & right
5466         if(AOP_TYPE(right) == AOP_LIT){
5467           int t = (lit >> (offset*8)) & 0x0FFL;
5468           switch(t) { 
5469           case 0x00:
5470             pic14_emitcode("clrf","%s",
5471                            aopGet(AOP(result),offset,FALSE,FALSE));
5472             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5473             break;
5474           case 0xff:
5475             if(AOP_TYPE(left) != AOP_ACC) {
5476               pic14_emitcode("movf","%s,w",
5477                              aopGet(AOP(left),offset,FALSE,FALSE));
5478               pic14_emitcode("movwf","%s",
5479                              aopGet(AOP(result),offset,FALSE,FALSE));
5480               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5481             }
5482             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5483             break;
5484           default:
5485             if(AOP_TYPE(left) == AOP_ACC) {
5486               emitpcode(POC_ANDLW, popGetLit(t));
5487             } else {
5488               pic14_emitcode("movlw","0x%x",t);
5489               pic14_emitcode("andwf","%s,w",
5490                              aopGet(AOP(left),offset,FALSE,FALSE));
5491               pic14_emitcode("movwf","%s",
5492                              aopGet(AOP(result),offset,FALSE,FALSE));
5493               
5494               emitpcode(POC_MOVLW, popGetLit(t));
5495               emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5496             }
5497             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5498           }
5499           continue;
5500         }
5501
5502         if (AOP_TYPE(left) == AOP_ACC) {
5503           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5504           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5505         } else {
5506           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5507           pic14_emitcode("andwf","%s,w",
5508                          aopGet(AOP(left),offset,FALSE,FALSE));
5509           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5510           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5511         }
5512         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5513         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5514       }
5515     }
5516   }
5517
5518   release :
5519     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5520   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521   freeAsmop(result,NULL,ic,TRUE);     
5522 }
5523
5524 /*-----------------------------------------------------------------*/
5525 /* genOr  - code for or                                            */
5526 /*-----------------------------------------------------------------*/
5527 static void genOr (iCode *ic, iCode *ifx)
5528 {
5529     operand *left, *right, *result;
5530     int size, offset=0;
5531     unsigned long lit = 0L;
5532
5533     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5534
5535     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5536     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5537     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5538
5539     DEBUGpic14_AopType(__LINE__,left,right,result);
5540
5541     /* if left is a literal & right is not then exchange them */
5542     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5543         AOP_NEEDSACC(left)) {
5544         operand *tmp = right ;
5545         right = left;
5546         left = tmp;
5547     }
5548
5549     /* if result = right then exchange them */
5550     if(pic14_sameRegs(AOP(result),AOP(right))){
5551         operand *tmp = right ;
5552         right = left;
5553         left = tmp;
5554     }
5555
5556     /* if right is bit then exchange them */
5557     if (AOP_TYPE(right) == AOP_CRY &&
5558         AOP_TYPE(left) != AOP_CRY){
5559         operand *tmp = right ;
5560         right = left;
5561         left = tmp;
5562     }
5563
5564     DEBUGpic14_AopType(__LINE__,left,right,result);
5565
5566     if(AOP_TYPE(right) == AOP_LIT)
5567         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5568
5569     size = AOP_SIZE(result);
5570
5571     // if(bit | yy)
5572     // xx = bit | yy;
5573     if (AOP_TYPE(left) == AOP_CRY){
5574         if(AOP_TYPE(right) == AOP_LIT){
5575             // c = bit & literal;
5576             if(lit){
5577                 // lit != 0 => result = 1
5578                 if(AOP_TYPE(result) == AOP_CRY){
5579                   if(size)
5580                     emitpcode(POC_BSF, popGet(AOP(result),0));
5581                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5582                   //     AOP(result)->aopu.aop_dir,
5583                   //     AOP(result)->aopu.aop_dir);
5584                     else if(ifx)
5585                         continueIfTrue(ifx);
5586                     goto release;
5587                 }
5588             } else {
5589                 // lit == 0 => result = left
5590                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5591                     goto release;
5592                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5593             }
5594         } else {
5595             if (AOP_TYPE(right) == AOP_CRY){
5596               if(pic14_sameRegs(AOP(result),AOP(left))){
5597                 // c = bit | bit;
5598                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5599                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5600                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5601
5602                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5603                          AOP(result)->aopu.aop_dir,
5604                          AOP(result)->aopu.aop_dir);
5605                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5606                          AOP(right)->aopu.aop_dir,
5607                          AOP(right)->aopu.aop_dir);
5608                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5609                          AOP(result)->aopu.aop_dir,
5610                          AOP(result)->aopu.aop_dir);
5611               } else {
5612                 if( AOP_TYPE(result) == AOP_ACC) {
5613                   emitpcode(POC_MOVLW, popGetLit(0));
5614                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5615                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5616                   emitpcode(POC_MOVLW, popGetLit(1));
5617
5618                 } else {
5619
5620                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5621                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5622                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5623                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5624
5625                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5626                                  AOP(result)->aopu.aop_dir,
5627                                  AOP(result)->aopu.aop_dir);
5628                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5629                                  AOP(right)->aopu.aop_dir,
5630                                  AOP(right)->aopu.aop_dir);
5631                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5632                                  AOP(left)->aopu.aop_dir,
5633                                  AOP(left)->aopu.aop_dir);
5634                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5635                                  AOP(result)->aopu.aop_dir,
5636                                  AOP(result)->aopu.aop_dir);
5637                 }
5638               }
5639             } else {
5640                 // c = bit | val;
5641                 symbol *tlbl = newiTempLabel(NULL);
5642                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5643
5644
5645                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5646                 if( AOP_TYPE(right) == AOP_ACC) {
5647                   emitpcode(POC_IORLW, popGetLit(0));
5648                   emitSKPNZ;
5649                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5650                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5651                 }
5652
5653
5654
5655                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5656                     pic14_emitcode(";XXX setb","c");
5657                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5658                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5659                 pic14_toBoolean(right);
5660                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5661                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5662                     jmpTrueOrFalse(ifx, tlbl);
5663                     goto release;
5664                 } else {
5665                     CLRC;
5666                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5667                 }
5668             }
5669         }
5670         // bit = c
5671         // val = c
5672         if(size)
5673             pic14_outBitC(result);
5674         // if(bit | ...)
5675         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5676             genIfxJump(ifx, "c");           
5677         goto release ;
5678     }
5679
5680     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5681     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5682     if((AOP_TYPE(right) == AOP_LIT) &&
5683        (AOP_TYPE(result) == AOP_CRY) &&
5684        (AOP_TYPE(left) != AOP_CRY)){
5685         if(lit){
5686           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5687             // result = 1
5688             if(size)
5689                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5690             else 
5691                 continueIfTrue(ifx);
5692             goto release;
5693         } else {
5694           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695             // lit = 0, result = boolean(left)
5696             if(size)
5697                 pic14_emitcode(";XXX setb","c");
5698             pic14_toBoolean(right);
5699             if(size){
5700                 symbol *tlbl = newiTempLabel(NULL);
5701                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5702                 CLRC;
5703                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5704             } else {
5705                 genIfxJump (ifx,"a");
5706                 goto release;
5707             }
5708         }
5709         pic14_outBitC(result);
5710         goto release ;
5711     }
5712
5713     /* if left is same as result */
5714     if(pic14_sameRegs(AOP(result),AOP(left))){
5715       int know_W = -1;
5716       for(;size--; offset++,lit>>=8) {
5717         if(AOP_TYPE(right) == AOP_LIT){
5718           if((lit & 0xff) == 0)
5719             /*  or'ing with 0 has no effect */
5720             continue;
5721           else {
5722             int p = my_powof2(lit & 0xff);
5723             if(p>=0) {
5724               /* only one bit is set in the literal, so use a bsf instruction */
5725               emitpcode(POC_BSF,
5726                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5727             } else {
5728               if(know_W != (lit & 0xff))
5729                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5730               know_W = lit & 0xff;
5731               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5732             }
5733                     
5734           }
5735         } else {
5736           if (AOP_TYPE(left) == AOP_ACC) {
5737             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5738             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5739           } else {                  
5740             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5741             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5742
5743             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5744             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5745
5746           }
5747         }
5748       }
5749     } else {
5750         // left & result in different registers
5751         if(AOP_TYPE(result) == AOP_CRY){
5752             // result = bit
5753             // if(size), result in bit
5754             // if(!size && ifx), conditional oper: if(left | right)
5755             symbol *tlbl = newiTempLabel(NULL);
5756             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5757             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5758
5759
5760             if(size)
5761                 pic14_emitcode(";XXX setb","c");
5762             while(sizer--){
5763                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5764                 pic14_emitcode(";XXX orl","a,%s",
5765                          aopGet(AOP(left),offset,FALSE,FALSE));
5766                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5767                 offset++;
5768             }
5769             if(size){
5770                 CLRC;
5771                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772                 pic14_outBitC(result);
5773             } else if(ifx)
5774                 jmpTrueOrFalse(ifx, tlbl);
5775         } else for(;(size--);offset++){
5776           // normal case
5777           // result = left & right
5778           if(AOP_TYPE(right) == AOP_LIT){
5779             int t = (lit >> (offset*8)) & 0x0FFL;
5780             switch(t) { 
5781             case 0x00:
5782               if (AOP_TYPE(left) != AOP_ACC) {
5783                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5784               }
5785               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5786
5787               break;
5788             default:
5789               if (AOP_TYPE(left) == AOP_ACC) {
5790                 emitpcode(POC_IORLW,  popGetLit(t));
5791               } else {
5792                 emitpcode(POC_MOVLW,  popGetLit(t));
5793                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5794               }
5795               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));              
5796             }
5797             continue;
5798           }
5799
5800           // faster than result <- left, anl result,right
5801           // and better if result is SFR
5802           if (AOP_TYPE(left) == AOP_ACC) {
5803             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5804             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5805           } else {
5806             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5807             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5808
5809             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5810             pic14_emitcode("iorwf","%s,w",
5811                      aopGet(AOP(left),offset,FALSE,FALSE));
5812           }
5813           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5814           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5815         }
5816     }
5817
5818 release :
5819     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5820     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5821     freeAsmop(result,NULL,ic,TRUE);     
5822 }
5823
5824 /*-----------------------------------------------------------------*/
5825 /* genXor - code for xclusive or                                   */
5826 /*-----------------------------------------------------------------*/
5827 static void genXor (iCode *ic, iCode *ifx)
5828 {
5829   operand *left, *right, *result;
5830   int size, offset=0;
5831   unsigned long lit = 0L;
5832
5833   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5834
5835   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5836   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5837   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5838
5839   /* if left is a literal & right is not ||
5840      if left needs acc & right does not */
5841   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5842       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5843     operand *tmp = right ;
5844     right = left;
5845     left = tmp;
5846   }
5847
5848   /* if result = right then exchange them */
5849   if(pic14_sameRegs(AOP(result),AOP(right))){
5850     operand *tmp = right ;
5851     right = left;
5852     left = tmp;
5853   }
5854
5855   /* if right is bit then exchange them */
5856   if (AOP_TYPE(right) == AOP_CRY &&
5857       AOP_TYPE(left) != AOP_CRY){
5858     operand *tmp = right ;
5859     right = left;
5860     left = tmp;
5861   }
5862   if(AOP_TYPE(right) == AOP_LIT)
5863     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5864
5865   size = AOP_SIZE(result);
5866
5867   // if(bit ^ yy)
5868   // xx = bit ^ yy;
5869   if (AOP_TYPE(left) == AOP_CRY){
5870     if(AOP_TYPE(right) == AOP_LIT){
5871       // c = bit & literal;
5872       if(lit>>1){
5873         // lit>>1  != 0 => result = 1
5874         if(AOP_TYPE(result) == AOP_CRY){
5875           if(size)
5876             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5877             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5878           else if(ifx)
5879             continueIfTrue(ifx);
5880           goto release;
5881         }
5882         pic14_emitcode("setb","c");
5883       } else{
5884         // lit == (0 or 1)
5885         if(lit == 0){
5886           // lit == 0, result = left
5887           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5888             goto release;
5889           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5890         } else{
5891           // lit == 1, result = not(left)
5892           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5893             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5894             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5895             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5896             goto release;
5897           } else {
5898             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5899             pic14_emitcode("cpl","c");
5900           }
5901         }
5902       }
5903
5904     } else {
5905       // right != literal
5906       symbol *tlbl = newiTempLabel(NULL);
5907       if (AOP_TYPE(right) == AOP_CRY){
5908         // c = bit ^ bit;
5909         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5910       }
5911       else{
5912         int sizer = AOP_SIZE(right);
5913         // c = bit ^ val
5914         // if val>>1 != 0, result = 1
5915         pic14_emitcode("setb","c");
5916         while(sizer){
5917           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5918           if(sizer == 1)
5919             // test the msb of the lsb
5920             pic14_emitcode("anl","a,#0xfe");
5921           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5922           sizer--;
5923         }
5924         // val = (0,1)
5925         pic14_emitcode("rrc","a");
5926       }
5927       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5928       pic14_emitcode("cpl","c");
5929       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5930     }
5931     // bit = c
5932     // val = c
5933     if(size)
5934       pic14_outBitC(result);
5935     // if(bit | ...)
5936     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5937       genIfxJump(ifx, "c");           
5938     goto release ;
5939   }
5940
5941   if(pic14_sameRegs(AOP(result),AOP(left))){
5942     /* if left is same as result */
5943     for(;size--; offset++) {
5944       if(AOP_TYPE(right) == AOP_LIT){
5945         int t  = (lit >> (offset*8)) & 0x0FFL;
5946         if(t == 0x00L)
5947           continue;
5948         else
5949           if (IS_AOP_PREG(left)) {
5950             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5951             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5952             aopPut(AOP(result),"a",offset);
5953           } else {
5954             emitpcode(POC_MOVLW, popGetLit(t));
5955             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5956             pic14_emitcode("xrl","%s,%s",
5957                            aopGet(AOP(left),offset,FALSE,TRUE),
5958                            aopGet(AOP(right),offset,FALSE,FALSE));
5959           }
5960       } else {
5961         if (AOP_TYPE(left) == AOP_ACC)
5962           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5963         else {
5964           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5965           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5966 /*
5967           if (IS_AOP_PREG(left)) {
5968             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5969             aopPut(AOP(result),"a",offset);
5970           } else
5971             pic14_emitcode("xrl","%s,a",
5972                            aopGet(AOP(left),offset,FALSE,TRUE));
5973 */
5974         }
5975       }
5976     }
5977   } else {
5978     // left & result in different registers
5979     if(AOP_TYPE(result) == AOP_CRY){
5980       // result = bit
5981       // if(size), result in bit
5982       // if(!size && ifx), conditional oper: if(left ^ right)
5983       symbol *tlbl = newiTempLabel(NULL);
5984       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5985       if(size)
5986         pic14_emitcode("setb","c");
5987       while(sizer--){
5988         if((AOP_TYPE(right) == AOP_LIT) &&
5989            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5990           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5991         } else {
5992           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5993           pic14_emitcode("xrl","a,%s",
5994                          aopGet(AOP(left),offset,FALSE,FALSE));
5995         }
5996         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5997         offset++;
5998       }
5999       if(size){
6000         CLRC;
6001         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6002         pic14_outBitC(result);
6003       } else if(ifx)
6004         jmpTrueOrFalse(ifx, tlbl);
6005     } else for(;(size--);offset++){
6006       // normal case
6007       // result = left & right
6008       if(AOP_TYPE(right) == AOP_LIT){
6009         int t = (lit >> (offset*8)) & 0x0FFL;
6010         switch(t) { 
6011         case 0x00:
6012           if (AOP_TYPE(left) != AOP_ACC) {
6013             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6014           }
6015           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6016           pic14_emitcode("movf","%s,w",
6017                          aopGet(AOP(left),offset,FALSE,FALSE));
6018           pic14_emitcode("movwf","%s",
6019                          aopGet(AOP(result),offset,FALSE,FALSE));
6020           break;
6021         case 0xff:
6022           if (AOP_TYPE(left) == AOP_ACC) {
6023             emitpcode(POC_XORLW, popGetLit(t));
6024           } else {
6025             emitpcode(POC_COMFW,popGet(AOP(left),offset));
6026           }
6027           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6028           break;
6029         default:
6030           if (AOP_TYPE(left) == AOP_ACC) {
6031             emitpcode(POC_XORLW, popGetLit(t));
6032           } else {
6033             emitpcode(POC_MOVLW, popGetLit(t));
6034             emitpcode(POC_XORFW,popGet(AOP(left),offset));
6035           }
6036           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6037           pic14_emitcode("movlw","0x%x",t);
6038           pic14_emitcode("xorwf","%s,w",
6039                          aopGet(AOP(left),offset,FALSE,FALSE));
6040           pic14_emitcode("movwf","%s",
6041                          aopGet(AOP(result),offset,FALSE,FALSE));
6042
6043         }
6044         continue;
6045       }
6046
6047       // faster than result <- left, anl result,right
6048       // and better if result is SFR
6049       if (AOP_TYPE(left) == AOP_ACC) {
6050         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6051         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6052       } else {
6053         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6054         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6055         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6056         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6057       }
6058       if ( AOP_TYPE(result) != AOP_ACC){
6059         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6060         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6061       }
6062     }
6063   }
6064
6065   release :
6066     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068   freeAsmop(result,NULL,ic,TRUE);     
6069 }
6070
6071 /*-----------------------------------------------------------------*/
6072 /* genInline - write the inline code out                           */
6073 /*-----------------------------------------------------------------*/
6074 static void genInline (iCode *ic)
6075 {
6076     char *buffer, *bp, *bp1;
6077     
6078     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6079
6080     _G.inLine += (!options.asmpeep);
6081
6082     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6083     strcpy(buffer,IC_INLINE(ic));
6084
6085     /* emit each line as a code */
6086     while (*bp) {
6087         if (*bp == '\n') {
6088             *bp++ = '\0';
6089
6090             if(*bp1)
6091               addpCode2pBlock(pb,AssembleLine(bp1));
6092             bp1 = bp;
6093         } else {
6094             if (*bp == ':') {
6095                 bp++;
6096                 *bp = '\0';
6097                 bp++;
6098                 pic14_emitcode(bp1,"");
6099                 bp1 = bp;
6100             } else
6101                 bp++;
6102         }
6103     }
6104     if ((bp1 != bp) && *bp1)
6105       addpCode2pBlock(pb,AssembleLine(bp1));
6106
6107     Safe_free(buffer);
6108
6109     _G.inLine -= (!options.asmpeep);
6110 }
6111
6112 /*-----------------------------------------------------------------*/
6113 /* genRRC - rotate right with carry                                */
6114 /*-----------------------------------------------------------------*/
6115 static void genRRC (iCode *ic)
6116 {
6117   operand *left , *result ;
6118   int size, offset = 0, same;
6119
6120   /* rotate right with carry */
6121   left = IC_LEFT(ic);
6122   result=IC_RESULT(ic);
6123   aopOp (left,ic,FALSE);
6124   aopOp (result,ic,FALSE);
6125
6126   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6127
6128   same = pic14_sameRegs(AOP(result),AOP(left));
6129
6130   size = AOP_SIZE(result);    
6131
6132   /* get the lsb and put it into the carry */
6133   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6134
6135   offset = 0 ;
6136
6137   while(size--) {
6138
6139     if(same) {
6140       emitpcode(POC_RRF, popGet(AOP(left),offset));
6141     } else {
6142       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6143       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6144     }
6145
6146     offset++;
6147   }
6148
6149   freeAsmop(left,NULL,ic,TRUE);
6150   freeAsmop(result,NULL,ic,TRUE);
6151 }
6152
6153 /*-----------------------------------------------------------------*/
6154 /* genRLC - generate code for rotate left with carry               */
6155 /*-----------------------------------------------------------------*/
6156 static void genRLC (iCode *ic)
6157 {    
6158   operand *left , *result ;
6159   int size, offset = 0;
6160   int same;
6161
6162   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6163   /* rotate right with carry */
6164   left = IC_LEFT(ic);
6165   result=IC_RESULT(ic);
6166   aopOp (left,ic,FALSE);
6167   aopOp (result,ic,FALSE);
6168
6169   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6170
6171   same = pic14_sameRegs(AOP(result),AOP(left));
6172
6173   /* move it to the result */
6174   size = AOP_SIZE(result);    
6175
6176   /* get the msb and put it into the carry */
6177   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6178
6179   offset = 0 ;
6180
6181   while(size--) {
6182
6183     if(same) {
6184       emitpcode(POC_RLF, popGet(AOP(left),offset));
6185     } else {
6186       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6187       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6188     }
6189
6190     offset++;
6191   }
6192
6193
6194   freeAsmop(left,NULL,ic,TRUE);
6195   freeAsmop(result,NULL,ic,TRUE);
6196 }
6197
6198 /*-----------------------------------------------------------------*/
6199 /* genGetHbit - generates code get highest order bit               */
6200 /*-----------------------------------------------------------------*/
6201 static void genGetHbit (iCode *ic)
6202 {
6203     operand *left, *result;
6204     left = IC_LEFT(ic);
6205     result=IC_RESULT(ic);
6206     aopOp (left,ic,FALSE);
6207     aopOp (result,ic,FALSE);
6208
6209     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6210     /* get the highest order byte into a */
6211     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6212     if(AOP_TYPE(result) == AOP_CRY){
6213         pic14_emitcode("rlc","a");
6214         pic14_outBitC(result);
6215     }
6216     else{
6217         pic14_emitcode("rl","a");
6218         pic14_emitcode("anl","a,#0x01");
6219         pic14_outAcc(result);
6220     }
6221
6222
6223     freeAsmop(left,NULL,ic,TRUE);
6224     freeAsmop(result,NULL,ic,TRUE);
6225 }
6226
6227 /*-----------------------------------------------------------------*/
6228 /* AccRol - rotate left accumulator by known count                 */
6229 /*-----------------------------------------------------------------*/
6230 static void AccRol (int shCount)
6231 {
6232     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6233     shCount &= 0x0007;              // shCount : 0..7
6234     switch(shCount){
6235         case 0 :
6236             break;
6237         case 1 :
6238             pic14_emitcode("rl","a");
6239             break;
6240         case 2 :
6241             pic14_emitcode("rl","a");
6242             pic14_emitcode("rl","a");
6243             break;
6244         case 3 :
6245             pic14_emitcode("swap","a");
6246             pic14_emitcode("rr","a");
6247             break;
6248         case 4 :
6249             pic14_emitcode("swap","a");
6250             break;
6251         case 5 :
6252             pic14_emitcode("swap","a");
6253             pic14_emitcode("rl","a");
6254             break;
6255         case 6 :
6256             pic14_emitcode("rr","a");
6257             pic14_emitcode("rr","a");
6258             break;
6259         case 7 :
6260             pic14_emitcode("rr","a");
6261             break;
6262     }
6263 }
6264
6265 /*-----------------------------------------------------------------*/
6266 /* AccLsh - left shift accumulator by known count                  */
6267 /*-----------------------------------------------------------------*/
6268 static void AccLsh (int shCount)
6269 {
6270     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6271     if(shCount != 0){
6272         if(shCount == 1)
6273             pic14_emitcode("add","a,acc");
6274         else 
6275             if(shCount == 2) {
6276             pic14_emitcode("add","a,acc");
6277             pic14_emitcode("add","a,acc");
6278         } else {
6279             /* rotate left accumulator */
6280             AccRol(shCount);
6281             /* and kill the lower order bits */
6282             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6283         }
6284     }
6285 }
6286
6287 /*-----------------------------------------------------------------*/
6288 /* AccRsh - right shift accumulator by known count                 */
6289 /*-----------------------------------------------------------------*/
6290 static void AccRsh (int shCount)
6291 {
6292     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6293     if(shCount != 0){
6294         if(shCount == 1){
6295             CLRC;
6296             pic14_emitcode("rrc","a");
6297         } else {
6298             /* rotate right accumulator */
6299             AccRol(8 - shCount);
6300             /* and kill the higher order bits */
6301             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6302         }
6303     }
6304 }
6305
6306 #if 0
6307 /*-----------------------------------------------------------------*/
6308 /* AccSRsh - signed right shift accumulator by known count                 */
6309 /*-----------------------------------------------------------------*/
6310 static void AccSRsh (int shCount)
6311 {
6312     symbol *tlbl ;
6313     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6314     if(shCount != 0){
6315         if(shCount == 1){
6316             pic14_emitcode("mov","c,acc.7");
6317             pic14_emitcode("rrc","a");
6318         } else if(shCount == 2){
6319             pic14_emitcode("mov","c,acc.7");
6320             pic14_emitcode("rrc","a");
6321             pic14_emitcode("mov","c,acc.7");
6322             pic14_emitcode("rrc","a");
6323         } else {
6324             tlbl = newiTempLabel(NULL);
6325             /* rotate right accumulator */
6326             AccRol(8 - shCount);
6327             /* and kill the higher order bits */
6328             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6329             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6330             pic14_emitcode("orl","a,#0x%02x",
6331                      (unsigned char)~SRMask[shCount]);
6332             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6333         }
6334     }
6335 }
6336 #endif
6337 /*-----------------------------------------------------------------*/
6338 /* shiftR1Left2Result - shift right one byte from left to result   */
6339 /*-----------------------------------------------------------------*/
6340 static void shiftR1Left2ResultSigned (operand *left, int offl,
6341                                 operand *result, int offr,
6342                                 int shCount)
6343 {
6344   int same;
6345
6346   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6347
6348   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6349
6350   switch(shCount) {
6351   case 1:
6352     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6353     if(same) 
6354       emitpcode(POC_RRF, popGet(AOP(result),offr));
6355     else {
6356       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6357       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6358     }
6359
6360     break;
6361   case 2:
6362
6363     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6364     if(same) 
6365       emitpcode(POC_RRF, popGet(AOP(result),offr));
6366     else {
6367       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6368       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6369     }
6370     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6371     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6372
6373     break;
6374
6375   case 3:
6376     if(same)
6377       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6378     else {
6379       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6380       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381     }
6382
6383     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6384     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6385     emitpcode(POC_ANDLW, popGetLit(0x1f));
6386
6387     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6388     emitpcode(POC_IORLW, popGetLit(0xe0));
6389
6390     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6391     break;
6392
6393   case 4:
6394     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6395     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6396     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6397     emitpcode(POC_IORLW,  popGetLit(0xf0));
6398     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6399     break;
6400   case 5:
6401     if(same) {
6402       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6403     } else {
6404       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6405       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6406     }
6407     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6408     emitpcode(POC_ANDLW,  popGetLit(0x07));
6409     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6410     emitpcode(POC_IORLW,  popGetLit(0xf8));
6411     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6412     break;
6413
6414   case 6:
6415     if(same) {
6416       emitpcode(POC_MOVLW, popGetLit(0x00));
6417       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6418       emitpcode(POC_MOVLW, popGetLit(0xfe));
6419       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6420       emitpcode(POC_IORLW, popGetLit(0x01));
6421       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422     } else {
6423       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6424       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6425       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6426       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6427       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6428     }
6429     break;
6430
6431   case 7:
6432     if(same) {
6433       emitpcode(POC_MOVLW, popGetLit(0x00));
6434       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6435       emitpcode(POC_MOVLW, popGetLit(0xff));
6436       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437     } else {
6438       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6439       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6440       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6441     }
6442
6443   default:
6444     break;
6445   }
6446 }
6447
6448 /*-----------------------------------------------------------------*/
6449 /* shiftR1Left2Result - shift right one byte from left to result   */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftR1Left2Result (operand *left, int offl,
6452                                 operand *result, int offr,
6453                                 int shCount, int sign)
6454 {
6455   int same;
6456
6457   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6458
6459   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6460
6461   /* Copy the msb into the carry if signed. */
6462   if(sign) {
6463     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6464     return;
6465   }
6466
6467
6468
6469   switch(shCount) {
6470   case 1:
6471     emitCLRC;
6472     if(same) 
6473       emitpcode(POC_RRF, popGet(AOP(result),offr));
6474     else {
6475       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6476       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6477     }
6478     break;
6479   case 2:
6480     emitCLRC;
6481     if(same) {
6482       emitpcode(POC_RRF, popGet(AOP(result),offr));
6483     } else {
6484       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6485       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6486     }
6487     emitCLRC;
6488     emitpcode(POC_RRF, popGet(AOP(result),offr));
6489
6490     break;
6491   case 3:
6492     if(same)
6493       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6494     else {
6495       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6496       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6497     }
6498
6499     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6500     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6501     emitpcode(POC_ANDLW, popGetLit(0x1f));
6502     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6503     break;
6504       
6505   case 4:
6506     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6507     emitpcode(POC_ANDLW, popGetLit(0x0f));
6508     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6509     break;
6510
6511   case 5:
6512     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6513     emitpcode(POC_ANDLW, popGetLit(0x0f));
6514     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6515     emitCLRC;
6516     emitpcode(POC_RRF, popGet(AOP(result),offr));
6517
6518     break;
6519   case 6:
6520
6521     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6522     emitpcode(POC_ANDLW, popGetLit(0x80));
6523     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6524     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6525     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6526     break;
6527
6528   case 7:
6529
6530     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6531     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6532     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6533
6534     break;
6535
6536   default:
6537     break;
6538   }
6539 }
6540
6541 /*-----------------------------------------------------------------*/
6542 /* shiftL1Left2Result - shift left one byte from left to result    */
6543 /*-----------------------------------------------------------------*/
6544 static void shiftL1Left2Result (operand *left, int offl,
6545                                 operand *result, int offr, int shCount)
6546 {
6547   int same;
6548
6549   //    char *l;
6550   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6551
6552   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6553   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6554     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6555     //    MOVA(l);
6556     /* shift left accumulator */
6557     //AccLsh(shCount); // don't comment out just yet...
6558   //    aopPut(AOP(result),"a",offr);
6559
6560   switch(shCount) {
6561   case 1:
6562     /* Shift left 1 bit position */
6563     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6564     if(same) {
6565       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6566     } else {
6567       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6568       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6569     }
6570     break;
6571   case 2:
6572     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6573     emitpcode(POC_ANDLW,popGetLit(0x7e));
6574     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6575     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6576     break;
6577   case 3:
6578     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579     emitpcode(POC_ANDLW,popGetLit(0x3e));
6580     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6581     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6582     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6583     break;
6584   case 4:
6585     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6586     emitpcode(POC_ANDLW, popGetLit(0xf0));
6587     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6588     break;
6589   case 5:
6590     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6591     emitpcode(POC_ANDLW, popGetLit(0xf0));
6592     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6593     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6594     break;
6595   case 6:
6596     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6597     emitpcode(POC_ANDLW, popGetLit(0x30));
6598     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6599     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6600     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6601     break;
6602   case 7:
6603     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6604     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6605     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6606     break;
6607
6608   default:
6609     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6610   }
6611
6612 }
6613
6614 /*-----------------------------------------------------------------*/
6615 /* movLeft2Result - move byte from left to result                  */
6616 /*-----------------------------------------------------------------*/
6617 static void movLeft2Result (operand *left, int offl,
6618                             operand *result, int offr)
6619 {
6620   char *l;
6621   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6622   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6623     l = aopGet(AOP(left),offl,FALSE,FALSE);
6624
6625     if (*l == '@' && (IS_AOP_PREG(result))) {
6626       pic14_emitcode("mov","a,%s",l);
6627       aopPut(AOP(result),"a",offr);
6628     } else {
6629       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6630       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6631     }
6632   }
6633 }
6634
6635 /*-----------------------------------------------------------------*/
6636 /* shiftL2Left2Result - shift left two bytes from left to result   */
6637 /*-----------------------------------------------------------------*/
6638 static void shiftL2Left2Result (operand *left, int offl,
6639                                 operand *result, int offr, int shCount)
6640 {
6641
6642
6643   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6644
6645   if(pic14_sameRegs(AOP(result), AOP(left))) {
6646     switch(shCount) {
6647     case 0:
6648       break;
6649     case 1:
6650     case 2:
6651     case 3:
6652
6653       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6654       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6655       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6656
6657       while(--shCount) {
6658         emitCLRC;
6659         emitpcode(POC_RLF, popGet(AOP(result),offr));
6660         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6661       }
6662
6663       break;
6664     case 4:
6665     case 5:
6666       emitpcode(POC_MOVLW, popGetLit(0x0f));
6667       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6668       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6669       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6670       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6671       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6672       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6673       if(shCount >=5) {
6674         emitpcode(POC_RLF, popGet(AOP(result),offr));
6675         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6676       }
6677       break;
6678     case 6:
6679       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6680       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6681       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6682       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6683       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6684       emitpcode(POC_ANDLW,popGetLit(0xc0));
6685       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6686       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6687       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6688       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6689       break;
6690     case 7:
6691       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6692       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6693       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6694       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6695       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6696     }
6697
6698   } else {
6699     switch(shCount) {
6700     case 0:
6701       break;
6702     case 1:
6703     case 2:
6704     case 3:
6705       /* note, use a mov/add for the shift since the mov has a
6706          chance of getting optimized out */
6707       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6708       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6709       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6710       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6711       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6712
6713       while(--shCount) {
6714         emitCLRC;
6715         emitpcode(POC_RLF, popGet(AOP(result),offr));
6716         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6717       }
6718       break;
6719
6720     case 4:
6721     case 5:
6722       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6723       emitpcode(POC_ANDLW, popGetLit(0xF0));
6724       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6725       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6726       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6727       emitpcode(POC_ANDLW, popGetLit(0xF0));
6728       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6729       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6730
6731
6732       if(shCount == 5) {
6733         emitpcode(POC_RLF, popGet(AOP(result),offr));
6734         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6735       }
6736       break;
6737     case 6:
6738       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6739       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6741       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6742
6743       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6744       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6745       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6746       emitpcode(POC_ANDLW,popGetLit(0xc0));
6747       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6748       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6749       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6750       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6751       break;
6752     case 7:
6753       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6754       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6755       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6756       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6757       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6758     }
6759   }
6760
6761 }
6762 /*-----------------------------------------------------------------*/
6763 /* shiftR2Left2Result - shift right two bytes from left to result  */
6764 /*-----------------------------------------------------------------*/
6765 static void shiftR2Left2Result (operand *left, int offl,
6766                                 operand *result, int offr,
6767                                 int shCount, int sign)
6768 {
6769   int same=0;
6770
6771   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6772   same = pic14_sameRegs(AOP(result), AOP(left));
6773
6774   if(same && ((offl + MSB16) == offr)){
6775     same=1;
6776     /* don't crash result[offr] */
6777     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6778     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6779   }
6780 /* else {
6781     movLeft2Result(left,offl, result, offr);
6782     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6783   }
6784 */
6785   /* a:x >> shCount (x = lsb(result))*/
6786 /*
6787   if(sign)
6788     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789   else {
6790     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6791 */
6792   switch(shCount) {
6793   case 0:
6794     break;
6795   case 1:
6796   case 2:
6797   case 3:
6798     if(sign)
6799       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6800     else
6801       emitCLRC;
6802
6803     if(same) {
6804       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6805       emitpcode(POC_RRF,popGet(AOP(result),offr));
6806     } else {
6807       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6808       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6809       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6810       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811     }
6812
6813     while(--shCount) {
6814       if(sign)
6815         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6816       else
6817         emitCLRC;
6818       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6819       emitpcode(POC_RRF,popGet(AOP(result),offr));
6820     }
6821     break;
6822   case 4:
6823   case 5:
6824     if(same) {
6825
6826       emitpcode(POC_MOVLW, popGetLit(0xf0));
6827       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6828       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6829
6830       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6831       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6832       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6834     } else {
6835       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6836       emitpcode(POC_ANDLW, popGetLit(0x0f));
6837       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6838
6839       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6840       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6841       emitpcode(POC_ANDLW, popGetLit(0xf0));
6842       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6843       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6844     }
6845
6846     if(shCount >=5) {
6847       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6848       emitpcode(POC_RRF, popGet(AOP(result),offr));
6849     }
6850
6851     if(sign) {
6852       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6853       emitpcode(POC_BTFSC, 
6854                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6855       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6856     }
6857
6858     break;
6859
6860   case 6:
6861     if(same) {
6862
6863       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6864       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6865
6866       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6867       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6868       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6869       emitpcode(POC_ANDLW,popGetLit(0x03));
6870       if(sign) {
6871         emitpcode(POC_BTFSC, 
6872                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6873         emitpcode(POC_IORLW,popGetLit(0xfc));
6874       }
6875       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6876       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6877       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6878       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6879     } else {
6880       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6881       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6882       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6883       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6884       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6885       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6886       emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6887       emitpcode(POC_ANDLW,popGetLit(0x03));
6888       if(sign) {
6889         emitpcode(POC_BTFSC, 
6890                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6891         emitpcode(POC_IORLW,popGetLit(0xfc));
6892       }
6893       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6894       //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6895
6896         
6897     }
6898
6899     break;
6900   case 7:
6901     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6902     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6903     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6904     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6905     if(sign) {
6906       emitSKPNC;
6907       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6908     } else 
6909       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6910   }
6911 }
6912
6913
6914 /*-----------------------------------------------------------------*/
6915 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6916 /*-----------------------------------------------------------------*/
6917 static void shiftLLeftOrResult (operand *left, int offl,
6918                                 operand *result, int offr, int shCount)
6919 {
6920     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6921     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6922     /* shift left accumulator */
6923     AccLsh(shCount);
6924     /* or with result */
6925     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6926     /* back to result */
6927     aopPut(AOP(result),"a",offr);
6928 }
6929
6930 /*-----------------------------------------------------------------*/
6931 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6932 /*-----------------------------------------------------------------*/
6933 static void shiftRLeftOrResult (operand *left, int offl,
6934                                 operand *result, int offr, int shCount)
6935 {
6936     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6937     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6938     /* shift right accumulator */
6939     AccRsh(shCount);
6940     /* or with result */
6941     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6942     /* back to result */
6943     aopPut(AOP(result),"a",offr);
6944 }
6945
6946 /*-----------------------------------------------------------------*/
6947 /* genlshOne - left shift a one byte quantity by known count       */
6948 /*-----------------------------------------------------------------*/
6949 static void genlshOne (operand *result, operand *left, int shCount)
6950 {       
6951     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6952     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6953 }
6954
6955 /*-----------------------------------------------------------------*/
6956 /* genlshTwo - left shift two bytes by known amount != 0           */
6957 /*-----------------------------------------------------------------*/
6958 static void genlshTwo (operand *result,operand *left, int shCount)
6959 {
6960     int size;
6961     
6962     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6963     size = pic14_getDataSize(result);
6964
6965     /* if shCount >= 8 */
6966     if (shCount >= 8) {
6967         shCount -= 8 ;
6968
6969         if (size > 1){
6970             if (shCount)
6971                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6972             else 
6973                 movLeft2Result(left, LSB, result, MSB16);
6974         }
6975         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6976     }
6977
6978     /*  1 <= shCount <= 7 */
6979     else {  
6980         if(size == 1)
6981             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6982         else 
6983             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6984     }
6985 }
6986
6987 /*-----------------------------------------------------------------*/
6988 /* shiftLLong - shift left one long from left to result            */
6989 /* offl = LSB or MSB16                                             */
6990 /*-----------------------------------------------------------------*/
6991 static void shiftLLong (operand *left, operand *result, int offr )
6992 {
6993     char *l;
6994     int size = AOP_SIZE(result);
6995
6996     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6997     if(size >= LSB+offr){
6998         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6999         MOVA(l);
7000         pic14_emitcode("add","a,acc");
7001         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7002             size >= MSB16+offr && offr != LSB )
7003             pic14_emitcode("xch","a,%s",
7004                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7005         else        
7006             aopPut(AOP(result),"a",LSB+offr);
7007     }
7008
7009     if(size >= MSB16+offr){
7010         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7011             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7012             MOVA(l);
7013         }
7014         pic14_emitcode("rlc","a");
7015         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7016             size >= MSB24+offr && offr != LSB)
7017             pic14_emitcode("xch","a,%s",
7018                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7019         else        
7020             aopPut(AOP(result),"a",MSB16+offr);
7021     }
7022
7023     if(size >= MSB24+offr){
7024         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7025             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7026             MOVA(l);
7027         }
7028         pic14_emitcode("rlc","a");
7029         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7030             size >= MSB32+offr && offr != LSB )
7031             pic14_emitcode("xch","a,%s",
7032                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7033         else        
7034             aopPut(AOP(result),"a",MSB24+offr);
7035     }
7036
7037     if(size > MSB32+offr){
7038         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7039             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7040             MOVA(l);    
7041         }
7042         pic14_emitcode("rlc","a");
7043         aopPut(AOP(result),"a",MSB32+offr);
7044     }
7045     if(offr != LSB)
7046         aopPut(AOP(result),zero,LSB);       
7047 }
7048
7049 /*-----------------------------------------------------------------*/
7050 /* genlshFour - shift four byte by a known amount != 0             */
7051 /*-----------------------------------------------------------------*/
7052 static void genlshFour (operand *result, operand *left, int shCount)
7053 {
7054     int size;
7055
7056     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7057     size = AOP_SIZE(result);
7058
7059     /* if shifting more that 3 bytes */
7060     if (shCount >= 24 ) {
7061         shCount -= 24;
7062         if (shCount)
7063             /* lowest order of left goes to the highest
7064             order of the destination */
7065             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7066         else
7067             movLeft2Result(left, LSB, result, MSB32);
7068         aopPut(AOP(result),zero,LSB);
7069         aopPut(AOP(result),zero,MSB16);
7070         aopPut(AOP(result),zero,MSB32);
7071         return;
7072     }
7073
7074     /* more than two bytes */
7075     else if ( shCount >= 16 ) {
7076         /* lower order two bytes goes to higher order two bytes */
7077         shCount -= 16;
7078         /* if some more remaining */
7079         if (shCount)
7080             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7081         else {
7082             movLeft2Result(left, MSB16, result, MSB32);
7083             movLeft2Result(left, LSB, result, MSB24);
7084         }
7085         aopPut(AOP(result),zero,MSB16);
7086         aopPut(AOP(result),zero,LSB);
7087         return;
7088     }    
7089
7090     /* if more than 1 byte */
7091     else if ( shCount >= 8 ) {
7092         /* lower order three bytes goes to higher order  three bytes */
7093         shCount -= 8;
7094         if(size == 2){
7095             if(shCount)
7096                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7097             else
7098                 movLeft2Result(left, LSB, result, MSB16);
7099         }
7100         else{   /* size = 4 */
7101             if(shCount == 0){
7102                 movLeft2Result(left, MSB24, result, MSB32);
7103                 movLeft2Result(left, MSB16, result, MSB24);
7104                 movLeft2Result(left, LSB, result, MSB16);
7105                 aopPut(AOP(result),zero,LSB);
7106             }
7107             else if(shCount == 1)
7108                 shiftLLong(left, result, MSB16);
7109             else{
7110                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7111                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7112                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7113                 aopPut(AOP(result),zero,LSB);
7114             }
7115         }
7116     }
7117
7118     /* 1 <= shCount <= 7 */
7119     else if(shCount <= 2){
7120         shiftLLong(left, result, LSB);
7121         if(shCount == 2)
7122             shiftLLong(result, result, LSB);
7123     }
7124     /* 3 <= shCount <= 7, optimize */
7125     else{
7126         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7127         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7128         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7129     }
7130 }
7131
7132 /*-----------------------------------------------------------------*/
7133 /* genLeftShiftLiteral - left shifting by known count              */
7134 /*-----------------------------------------------------------------*/
7135 static void genLeftShiftLiteral (operand *left,
7136                                  operand *right,
7137                                  operand *result,
7138                                  iCode *ic)
7139 {    
7140     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7141     int size;
7142
7143     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7144     freeAsmop(right,NULL,ic,TRUE);
7145
7146     aopOp(left,ic,FALSE);
7147     aopOp(result,ic,FALSE);
7148
7149     size = getSize(operandType(result));
7150
7151 #if VIEW_SIZE
7152     pic14_emitcode("; shift left ","result %d, left %d",size,
7153              AOP_SIZE(left));
7154 #endif
7155
7156     /* I suppose that the left size >= result size */
7157     if(shCount == 0){
7158         while(size--){
7159             movLeft2Result(left, size, result, size);
7160         }
7161     }
7162
7163     else if(shCount >= (size * 8))
7164         while(size--)
7165             aopPut(AOP(result),zero,size);
7166     else{
7167         switch (size) {
7168             case 1:
7169                 genlshOne (result,left,shCount);
7170                 break;
7171
7172             case 2:
7173             case 3:
7174                 genlshTwo (result,left,shCount);
7175                 break;
7176
7177             case 4:
7178                 genlshFour (result,left,shCount);
7179                 break;
7180         }
7181     }
7182     freeAsmop(left,NULL,ic,TRUE);
7183     freeAsmop(result,NULL,ic,TRUE);
7184 }
7185
7186 /*-----------------------------------------------------------------*
7187  * genMultiAsm - repeat assembly instruction for size of register.
7188  * if endian == 1, then the high byte (i.e base address + size of 
7189  * register) is used first else the low byte is used first;
7190  *-----------------------------------------------------------------*/
7191 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7192 {
7193
7194   int offset = 0;
7195
7196   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7197
7198   if(!reg)
7199     return;
7200
7201   if(!endian) {
7202     endian = 1;
7203   } else {
7204     endian = -1;
7205     offset = size-1;
7206   }
7207
7208   while(size--) {
7209     emitpcode(poc,    popGet(AOP(reg),offset));
7210     offset += endian;
7211   }
7212
7213 }
7214 /*-----------------------------------------------------------------*/
7215 /* genLeftShift - generates code for left shifting                 */
7216 /*-----------------------------------------------------------------*/
7217 static void genLeftShift (iCode *ic)
7218 {
7219   operand *left,*right, *result;
7220   int size, offset;
7221   char *l;
7222   symbol *tlbl , *tlbl1;
7223   pCodeOp *pctemp;
7224
7225   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7226
7227   right = IC_RIGHT(ic);
7228   left  = IC_LEFT(ic);
7229   result = IC_RESULT(ic);
7230
7231   aopOp(right,ic,FALSE);
7232
7233   /* if the shift count is known then do it 
7234      as efficiently as possible */
7235   if (AOP_TYPE(right) == AOP_LIT) {
7236     genLeftShiftLiteral (left,right,result,ic);
7237     return ;
7238   }
7239
7240   /* shift count is unknown then we have to form 
7241      a loop get the loop count in B : Note: we take
7242      only the lower order byte since shifting
7243      more that 32 bits make no sense anyway, ( the
7244      largest size of an object can be only 32 bits ) */  
7245
7246     
7247   aopOp(left,ic,FALSE);
7248   aopOp(result,ic,FALSE);
7249
7250   /* now move the left to the result if they are not the
7251      same */
7252   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7253       AOP_SIZE(result) > 1) {
7254
7255     size = AOP_SIZE(result);
7256     offset=0;
7257     while (size--) {
7258       l = aopGet(AOP(left),offset,FALSE,TRUE);
7259       if (*l == '@' && (IS_AOP_PREG(result))) {
7260
7261         pic14_emitcode("mov","a,%s",l);
7262         aopPut(AOP(result),"a",offset);
7263       } else {
7264         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7265         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7266         //aopPut(AOP(result),l,offset);
7267       }
7268       offset++;
7269     }
7270   }
7271
7272   size = AOP_SIZE(result);
7273
7274   /* if it is only one byte then */
7275   if (size == 1) {
7276     if(optimized_for_speed) {
7277       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7278       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7279       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7280       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7281       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7282       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7283       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7284       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7285       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7286       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7287       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7288       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7289     } else {
7290
7291       tlbl = newiTempLabel(NULL);
7292       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7293         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7294         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7295       }
7296
7297       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7298       emitpcode(POC_RRF,    popGet(AOP(result),0));
7299       emitpLabel(tlbl->key);
7300       emitpcode(POC_RLF,    popGet(AOP(result),0));
7301       emitpcode(POC_ADDLW,  popGetLit(1));
7302       emitSKPC;
7303       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7304     }
7305     goto release ;
7306   }
7307     
7308   if (pic14_sameRegs(AOP(left),AOP(result))) {
7309
7310     tlbl = newiTempLabel(NULL);
7311     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7312     genMultiAsm(POC_RRF, result, size,1);
7313     emitpLabel(tlbl->key);
7314     genMultiAsm(POC_RLF, result, size,0);
7315     emitpcode(POC_ADDLW,  popGetLit(1));
7316     emitSKPC;
7317     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7318     goto release;
7319   }
7320
7321   //tlbl = newiTempLabel(NULL);
7322   //offset = 0 ;   
7323   //tlbl1 = newiTempLabel(NULL);
7324
7325   //reAdjustPreg(AOP(result));    
7326     
7327   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7328   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7329   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7330   //MOVA(l);
7331   //pic14_emitcode("add","a,acc");         
7332   //aopPut(AOP(result),"a",offset++);
7333   //while (--size) {
7334   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7335   //  MOVA(l);
7336   //  pic14_emitcode("rlc","a");         
7337   //  aopPut(AOP(result),"a",offset++);
7338   //}
7339   //reAdjustPreg(AOP(result));
7340
7341   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7342   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7343
7344
7345   tlbl = newiTempLabel(NULL);
7346   tlbl1= newiTempLabel(NULL);
7347
7348   size = AOP_SIZE(result);
7349   offset = 1;
7350
7351   pctemp = popGetTempReg();  /* grab a temporary working register. */
7352
7353   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7354
7355   /* offset should be 0, 1 or 3 */
7356   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7357   emitSKPNZ;
7358   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7359
7360   emitpcode(POC_MOVWF, pctemp);
7361
7362
7363   emitpLabel(tlbl->key);
7364
7365   emitCLRC;
7366   emitpcode(POC_RLF,  popGet(AOP(result),0));
7367   while(--size)
7368     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7369
7370   emitpcode(POC_DECFSZ,  pctemp);
7371   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7372   emitpLabel(tlbl1->key);
7373
7374   popReleaseTempReg(pctemp);
7375
7376
7377  release:
7378   freeAsmop (right,NULL,ic,TRUE);
7379   freeAsmop(left,NULL,ic,TRUE);
7380   freeAsmop(result,NULL,ic,TRUE);
7381 }
7382
7383 /*-----------------------------------------------------------------*/
7384 /* genrshOne - right shift a one byte quantity by known count      */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshOne (operand *result, operand *left,
7387                        int shCount, int sign)
7388 {
7389     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7390     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7391 }
7392
7393 /*-----------------------------------------------------------------*/
7394 /* genrshTwo - right shift two bytes by known amount != 0          */
7395 /*-----------------------------------------------------------------*/
7396 static void genrshTwo (operand *result,operand *left,
7397                        int shCount, int sign)
7398 {
7399   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7400   /* if shCount >= 8 */
7401   if (shCount >= 8) {
7402     shCount -= 8 ;
7403     if (shCount)
7404       shiftR1Left2Result(left, MSB16, result, LSB,
7405                          shCount, sign);
7406     else
7407       movLeft2Result(left, MSB16, result, LSB);
7408
7409     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7410
7411     if(sign) {
7412       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7413       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7414     }
7415   }
7416
7417   /*  1 <= shCount <= 7 */
7418   else
7419     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7420 }
7421
7422 /*-----------------------------------------------------------------*/
7423 /* shiftRLong - shift right one long from left to result           */
7424 /* offl = LSB or MSB16                                             */
7425 /*-----------------------------------------------------------------*/
7426 static void shiftRLong (operand *left, int offl,
7427                         operand *result, int sign)
7428 {
7429     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7430     if(!sign)
7431         pic14_emitcode("clr","c");
7432     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7433     if(sign)
7434         pic14_emitcode("mov","c,acc.7");
7435     pic14_emitcode("rrc","a");
7436     aopPut(AOP(result),"a",MSB32-offl);
7437     if(offl == MSB16)
7438         /* add sign of "a" */
7439         addSign(result, MSB32, sign);
7440
7441     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7442     pic14_emitcode("rrc","a");
7443     aopPut(AOP(result),"a",MSB24-offl);
7444
7445     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7446     pic14_emitcode("rrc","a");
7447     aopPut(AOP(result),"a",MSB16-offl);
7448
7449     if(offl == LSB){
7450         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7451         pic14_emitcode("rrc","a");
7452         aopPut(AOP(result),"a",LSB);
7453     }
7454 }
7455
7456 /*-----------------------------------------------------------------*/
7457 /* genrshFour - shift four byte by a known amount != 0             */
7458 /*-----------------------------------------------------------------*/
7459 static void genrshFour (operand *result, operand *left,
7460                         int shCount, int sign)
7461 {
7462   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7463   /* if shifting more that 3 bytes */
7464   if(shCount >= 24 ) {
7465     shCount -= 24;
7466     if(shCount)
7467       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7468     else
7469       movLeft2Result(left, MSB32, result, LSB);
7470
7471     addSign(result, MSB16, sign);
7472   }
7473   else if(shCount >= 16){
7474     shCount -= 16;
7475     if(shCount)
7476       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7477     else{
7478       movLeft2Result(left, MSB24, result, LSB);
7479       movLeft2Result(left, MSB32, result, MSB16);
7480     }
7481     addSign(result, MSB24, sign);
7482   }
7483   else if(shCount >= 8){
7484     shCount -= 8;
7485     if(shCount == 1)
7486       shiftRLong(left, MSB16, result, sign);
7487     else if(shCount == 0){
7488       movLeft2Result(left, MSB16, result, LSB);
7489       movLeft2Result(left, MSB24, result, MSB16);
7490       movLeft2Result(left, MSB32, result, MSB24);
7491       addSign(result, MSB32, sign);
7492     }
7493     else{
7494       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7495       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7496       /* the last shift is signed */
7497       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7498       addSign(result, MSB32, sign);
7499     }
7500   }
7501   else{   /* 1 <= shCount <= 7 */
7502     if(shCount <= 2){
7503       shiftRLong(left, LSB, result, sign);
7504       if(shCount == 2)
7505         shiftRLong(result, LSB, result, sign);
7506     }
7507     else{
7508       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7509       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7510       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7511     }
7512   }
7513 }
7514
7515 /*-----------------------------------------------------------------*/
7516 /* genRightShiftLiteral - right shifting by known count            */
7517 /*-----------------------------------------------------------------*/
7518 static void genRightShiftLiteral (operand *left,
7519                                   operand *right,
7520                                   operand *result,
7521                                   iCode *ic,
7522                                   int sign)
7523 {    
7524   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7525   int lsize,res_size;
7526
7527   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7528   freeAsmop(right,NULL,ic,TRUE);
7529
7530   aopOp(left,ic,FALSE);
7531   aopOp(result,ic,FALSE);
7532
7533 #if VIEW_SIZE
7534   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7535                  AOP_SIZE(left));
7536 #endif
7537
7538   lsize = pic14_getDataSize(left);
7539   res_size = pic14_getDataSize(result);
7540   /* test the LEFT size !!! */
7541
7542   /* I suppose that the left size >= result size */
7543   if(shCount == 0){
7544     while(res_size--)
7545       movLeft2Result(left, lsize, result, res_size);
7546   }
7547
7548   else if(shCount >= (lsize * 8)){
7549
7550     if(res_size == 1) {
7551       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7552       if(sign) {
7553         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7554         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7555       }
7556     } else {
7557
7558       if(sign) {
7559         emitpcode(POC_MOVLW, popGetLit(0));
7560         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7561         emitpcode(POC_MOVLW, popGetLit(0xff));
7562         while(res_size--)
7563           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7564
7565       } else {
7566
7567         while(res_size--)
7568           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7569       }
7570     }
7571   } else {
7572
7573     switch (res_size) {
7574     case 1:
7575       genrshOne (result,left,shCount,sign);
7576       break;
7577
7578     case 2:
7579       genrshTwo (result,left,shCount,sign);
7580       break;
7581
7582     case 4:
7583       genrshFour (result,left,shCount,sign);
7584       break;
7585     default :
7586       break;
7587     }
7588
7589   }
7590
7591   freeAsmop(left,NULL,ic,TRUE);
7592   freeAsmop(result,NULL,ic,TRUE);
7593 }
7594
7595 /*-----------------------------------------------------------------*/
7596 /* genSignedRightShift - right shift of signed number              */
7597 /*-----------------------------------------------------------------*/
7598 static void genSignedRightShift (iCode *ic)
7599 {
7600   operand *right, *left, *result;
7601   int size, offset;
7602   //  char *l;
7603   symbol *tlbl, *tlbl1 ;
7604   pCodeOp *pctemp;
7605
7606   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7607
7608   /* we do it the hard way put the shift count in b
7609      and loop thru preserving the sign */
7610   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7611
7612   right = IC_RIGHT(ic);
7613   left  = IC_LEFT(ic);
7614   result = IC_RESULT(ic);
7615
7616   aopOp(right,ic,FALSE);  
7617   aopOp(left,ic,FALSE);
7618   aopOp(result,ic,FALSE);
7619
7620
7621   if ( AOP_TYPE(right) == AOP_LIT) {
7622     genRightShiftLiteral (left,right,result,ic,1);
7623     return ;
7624   }
7625   /* shift count is unknown then we have to form 
7626      a loop get the loop count in B : Note: we take
7627      only the lower order byte since shifting
7628      more that 32 bits make no sense anyway, ( the
7629      largest size of an object can be only 32 bits ) */  
7630
7631   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7632   //pic14_emitcode("inc","b");
7633   //freeAsmop (right,NULL,ic,TRUE);
7634   //aopOp(left,ic,FALSE);
7635   //aopOp(result,ic,FALSE);
7636
7637   /* now move the left to the result if they are not the
7638      same */
7639   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7640       AOP_SIZE(result) > 1) {
7641
7642     size = AOP_SIZE(result);
7643     offset=0;
7644     while (size--) { 
7645       /*
7646         l = aopGet(AOP(left),offset,FALSE,TRUE);
7647         if (*l == '@' && IS_AOP_PREG(result)) {
7648
7649         pic14_emitcode("mov","a,%s",l);
7650         aopPut(AOP(result),"a",offset);
7651         } else
7652         aopPut(AOP(result),l,offset);
7653       */
7654       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7655       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7656
7657       offset++;
7658     }
7659   }
7660
7661   /* mov the highest order bit to OVR */    
7662   tlbl = newiTempLabel(NULL);
7663   tlbl1= newiTempLabel(NULL);
7664
7665   size = AOP_SIZE(result);
7666   offset = size - 1;
7667
7668   pctemp = popGetTempReg();  /* grab a temporary working register. */
7669
7670   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7671
7672   /* offset should be 0, 1 or 3 */
7673   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7674   emitSKPNZ;
7675   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7676
7677   emitpcode(POC_MOVWF, pctemp);
7678
7679
7680   emitpLabel(tlbl->key);
7681
7682   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7683   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7684
7685   while(--size) {
7686     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7687   }
7688
7689   emitpcode(POC_DECFSZ,  pctemp);
7690   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7691   emitpLabel(tlbl1->key);
7692
7693   popReleaseTempReg(pctemp);
7694 #if 0
7695   size = AOP_SIZE(result);
7696   offset = size - 1;
7697   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7698   pic14_emitcode("rlc","a");
7699   pic14_emitcode("mov","ov,c");
7700   /* if it is only one byte then */
7701   if (size == 1) {
7702     l = aopGet(AOP(left),0,FALSE,FALSE);
7703     MOVA(l);
7704     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7706     pic14_emitcode("mov","c,ov");
7707     pic14_emitcode("rrc","a");
7708     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7709     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7710     aopPut(AOP(result),"a",0);
7711     goto release ;
7712   }
7713
7714   reAdjustPreg(AOP(result));
7715   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7716   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7717   pic14_emitcode("mov","c,ov");
7718   while (size--) {
7719     l = aopGet(AOP(result),offset,FALSE,FALSE);
7720     MOVA(l);
7721     pic14_emitcode("rrc","a");         
7722     aopPut(AOP(result),"a",offset--);
7723   }
7724   reAdjustPreg(AOP(result));
7725   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7726   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7727
7728  release:
7729 #endif
7730
7731   freeAsmop(left,NULL,ic,TRUE);
7732   freeAsmop(result,NULL,ic,TRUE);
7733   freeAsmop(right,NULL,ic,TRUE);
7734 }
7735
7736 /*-----------------------------------------------------------------*/
7737 /* genRightShift - generate code for right shifting                */
7738 /*-----------------------------------------------------------------*/
7739 static void genRightShift (iCode *ic)
7740 {
7741     operand *right, *left, *result;
7742     sym_link *retype ;
7743     int size, offset;
7744     char *l;
7745     symbol *tlbl, *tlbl1 ;
7746
7747     /* if signed then we do it the hard way preserve the
7748     sign bit moving it inwards */
7749     retype = getSpec(operandType(IC_RESULT(ic)));
7750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7751
7752     if (!SPEC_USIGN(retype)) {
7753         genSignedRightShift (ic);
7754         return ;
7755     }
7756
7757     /* signed & unsigned types are treated the same : i.e. the
7758     signed is NOT propagated inwards : quoting from the
7759     ANSI - standard : "for E1 >> E2, is equivalent to division
7760     by 2**E2 if unsigned or if it has a non-negative value,
7761     otherwise the result is implementation defined ", MY definition
7762     is that the sign does not get propagated */
7763
7764     right = IC_RIGHT(ic);
7765     left  = IC_LEFT(ic);
7766     result = IC_RESULT(ic);
7767
7768     aopOp(right,ic,FALSE);
7769
7770     /* if the shift count is known then do it 
7771     as efficiently as possible */
7772     if (AOP_TYPE(right) == AOP_LIT) {
7773         genRightShiftLiteral (left,right,result,ic, 0);
7774         return ;
7775     }
7776
7777     /* shift count is unknown then we have to form 
7778     a loop get the loop count in B : Note: we take
7779     only the lower order byte since shifting
7780     more that 32 bits make no sense anyway, ( the
7781     largest size of an object can be only 32 bits ) */  
7782
7783     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7784     pic14_emitcode("inc","b");
7785     aopOp(left,ic,FALSE);
7786     aopOp(result,ic,FALSE);
7787
7788     /* now move the left to the result if they are not the
7789     same */
7790     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7791         AOP_SIZE(result) > 1) {
7792
7793         size = AOP_SIZE(result);
7794         offset=0;
7795         while (size--) {
7796             l = aopGet(AOP(left),offset,FALSE,TRUE);
7797             if (*l == '@' && IS_AOP_PREG(result)) {
7798
7799                 pic14_emitcode("mov","a,%s",l);
7800                 aopPut(AOP(result),"a",offset);
7801             } else
7802                 aopPut(AOP(result),l,offset);
7803             offset++;
7804         }
7805     }
7806
7807     tlbl = newiTempLabel(NULL);
7808     tlbl1= newiTempLabel(NULL);
7809     size = AOP_SIZE(result);
7810     offset = size - 1;
7811
7812     /* if it is only one byte then */
7813     if (size == 1) {
7814
7815       tlbl = newiTempLabel(NULL);
7816       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7817         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7818         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7819       }
7820
7821       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7822       emitpcode(POC_RLF,    popGet(AOP(result),0));
7823       emitpLabel(tlbl->key);
7824       emitpcode(POC_RRF,    popGet(AOP(result),0));
7825       emitpcode(POC_ADDLW,  popGetLit(1));
7826       emitSKPC;
7827       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7828
7829       goto release ;
7830     }
7831
7832     reAdjustPreg(AOP(result));
7833     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7834     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7835     CLRC;
7836     while (size--) {
7837         l = aopGet(AOP(result),offset,FALSE,FALSE);
7838         MOVA(l);
7839         pic14_emitcode("rrc","a");         
7840         aopPut(AOP(result),"a",offset--);
7841     }
7842     reAdjustPreg(AOP(result));
7843
7844     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7845     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7846
7847 release:
7848     freeAsmop(left,NULL,ic,TRUE);
7849     freeAsmop (right,NULL,ic,TRUE);
7850     freeAsmop(result,NULL,ic,TRUE);
7851 }
7852
7853 /*-----------------------------------------------------------------*/
7854 /* genUnpackBits - generates code for unpacking bits               */
7855 /*-----------------------------------------------------------------*/
7856 static void genUnpackBits (operand *result, char *rname, int ptype)
7857 {    
7858     int shCnt ;
7859     int rlen = 0 ;
7860     sym_link *etype;
7861     int offset = 0 ;
7862
7863     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7864     etype = getSpec(operandType(result));
7865
7866     /* read the first byte  */
7867     switch (ptype) {
7868
7869     case POINTER:
7870     case IPOINTER:
7871         pic14_emitcode("mov","a,@%s",rname);
7872         break;
7873         
7874     case PPOINTER:
7875         pic14_emitcode("movx","a,@%s",rname);
7876         break;
7877         
7878     case FPOINTER:
7879         pic14_emitcode("movx","a,@dptr");
7880         break;
7881
7882     case CPOINTER:
7883         pic14_emitcode("clr","a");
7884         pic14_emitcode("movc","a","@a+dptr");
7885         break;
7886
7887     case GPOINTER:
7888         pic14_emitcode("lcall","__gptrget");
7889         break;
7890     }
7891
7892     /* if we have bitdisplacement then it fits   */
7893     /* into this byte completely or if length is */
7894     /* less than a byte                          */
7895     if ((shCnt = SPEC_BSTR(etype)) || 
7896         (SPEC_BLEN(etype) <= 8))  {
7897
7898         /* shift right acc */
7899         AccRsh(shCnt);
7900
7901         pic14_emitcode("anl","a,#0x%02x",
7902                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7903         aopPut(AOP(result),"a",offset);
7904         return ;
7905     }
7906
7907     /* bit field did not fit in a byte  */
7908     rlen = SPEC_BLEN(etype) - 8;
7909     aopPut(AOP(result),"a",offset++);
7910
7911     while (1)  {
7912
7913         switch (ptype) {
7914         case POINTER:
7915         case IPOINTER:
7916             pic14_emitcode("inc","%s",rname);
7917             pic14_emitcode("mov","a,@%s",rname);
7918             break;
7919             
7920         case PPOINTER:
7921             pic14_emitcode("inc","%s",rname);
7922             pic14_emitcode("movx","a,@%s",rname);
7923             break;
7924
7925         case FPOINTER:
7926             pic14_emitcode("inc","dptr");
7927             pic14_emitcode("movx","a,@dptr");
7928             break;
7929             
7930         case CPOINTER:
7931             pic14_emitcode("clr","a");
7932             pic14_emitcode("inc","dptr");
7933             pic14_emitcode("movc","a","@a+dptr");
7934             break;
7935             
7936         case GPOINTER:
7937             pic14_emitcode("inc","dptr");
7938             pic14_emitcode("lcall","__gptrget");
7939             break;
7940         }
7941
7942         rlen -= 8;            
7943         /* if we are done */
7944         if ( rlen <= 0 )
7945             break ;
7946         
7947         aopPut(AOP(result),"a",offset++);
7948                               
7949     }
7950     
7951     if (rlen) {
7952         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7953         aopPut(AOP(result),"a",offset);        
7954     }
7955     
7956     return ;
7957 }
7958
7959 #if 0
7960 /*-----------------------------------------------------------------*/
7961 /* genDataPointerGet - generates code when ptr offset is known     */
7962 /*-----------------------------------------------------------------*/
7963 static void genDataPointerGet (operand *left, 
7964                                operand *result, 
7965                                iCode *ic)
7966 {
7967   int size , offset = 0;
7968
7969
7970   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7971
7972
7973   /* optimization - most of the time, left and result are the same
7974    * address, but different types. for the pic code, we could omit
7975    * the following
7976    */
7977
7978   aopOp(result,ic,TRUE);
7979
7980   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7981
7982   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7983
7984   size = AOP_SIZE(result);
7985
7986   while (size--) {
7987     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7988     offset++;
7989   }
7990
7991   freeAsmop(left,NULL,ic,TRUE);
7992   freeAsmop(result,NULL,ic,TRUE);
7993 }
7994 #endif
7995 /*-----------------------------------------------------------------*/
7996 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7997 /*-----------------------------------------------------------------*/
7998 static void genNearPointerGet (operand *left, 
7999                                operand *result, 
8000                                iCode *ic)
8001 {
8002     asmop *aop = NULL;
8003     //regs *preg = NULL ;
8004     char *rname ;
8005     sym_link *rtype, *retype;
8006     sym_link *ltype = operandType(left);    
8007     //char buffer[80];
8008
8009     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8010
8011     rtype = operandType(result);
8012     retype= getSpec(rtype);
8013     
8014     aopOp(left,ic,FALSE);
8015     
8016     /* if left is rematerialisable and
8017        result is not bit variable type and
8018        the left is pointer to data space i.e
8019        lower 128 bytes of space */
8020     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8021         !IS_BITVAR(retype)         &&
8022         DCL_TYPE(ltype) == POINTER) {
8023       //genDataPointerGet (left,result,ic);
8024         return ;
8025     }
8026     
8027     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8028
8029         /* if the value is already in a pointer register
8030        then don't need anything more */
8031     if (!AOP_INPREG(AOP(left))) {
8032         /* otherwise get a free pointer register */
8033     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8034 /*
8035         aop = newAsmop(0);
8036         preg = getFreePtr(ic,&aop,FALSE);
8037         pic14_emitcode("mov","%s,%s",
8038                 preg->name,
8039                 aopGet(AOP(left),0,FALSE,TRUE));
8040         rname = preg->name ;
8041 */
8042     rname ="BAD";
8043     } else
8044         rname = aopGet(AOP(left),0,FALSE,FALSE);
8045     
8046     aopOp (result,ic,FALSE);
8047     
8048       /* if bitfield then unpack the bits */
8049     if (IS_BITVAR(retype)) 
8050         genUnpackBits (result,rname,POINTER);
8051     else {
8052         /* we have can just get the values */
8053       int size = AOP_SIZE(result);
8054       int offset = 0 ;  
8055         
8056       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8057
8058       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8059       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8060       while(size--) {
8061         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8062         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8063         if(size)
8064           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8065       }
8066 /*
8067         while (size--) {
8068             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8069
8070                 pic14_emitcode("mov","a,@%s",rname);
8071                 aopPut(AOP(result),"a",offset);
8072             } else {
8073                 sprintf(buffer,"@%s",rname);
8074                 aopPut(AOP(result),buffer,offset);
8075             }
8076             offset++ ;
8077             if (size)
8078                 pic14_emitcode("inc","%s",rname);
8079         }
8080 */
8081     }
8082
8083     /* now some housekeeping stuff */
8084     if (aop) {
8085         /* we had to allocate for this iCode */
8086     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8087         freeAsmop(NULL,aop,ic,TRUE);
8088     } else { 
8089         /* we did not allocate which means left
8090            already in a pointer register, then
8091            if size > 0 && this could be used again
8092            we have to point it back to where it 
8093            belongs */
8094     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8095         if (AOP_SIZE(result) > 1 &&
8096             !OP_SYMBOL(left)->remat &&
8097             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8098               ic->depth )) {
8099             int size = AOP_SIZE(result) - 1;
8100             while (size--)
8101                 pic14_emitcode("dec","%s",rname);
8102         }
8103     }
8104
8105     /* done */
8106     freeAsmop(left,NULL,ic,TRUE);
8107     freeAsmop(result,NULL,ic,TRUE);
8108      
8109 }
8110
8111 /*-----------------------------------------------------------------*/
8112 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8113 /*-----------------------------------------------------------------*/
8114 static void genPagedPointerGet (operand *left, 
8115                                operand *result, 
8116                                iCode *ic)
8117 {
8118     asmop *aop = NULL;
8119     regs *preg = NULL ;
8120     char *rname ;
8121     sym_link *rtype, *retype;    
8122
8123     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8124
8125     rtype = operandType(result);
8126     retype= getSpec(rtype);
8127     
8128     aopOp(left,ic,FALSE);
8129
8130   /* if the value is already in a pointer register
8131        then don't need anything more */
8132     if (!AOP_INPREG(AOP(left))) {
8133         /* otherwise get a free pointer register */
8134         aop = newAsmop(0);
8135         preg = getFreePtr(ic,&aop,FALSE);
8136         pic14_emitcode("mov","%s,%s",
8137                 preg->name,
8138                 aopGet(AOP(left),0,FALSE,TRUE));
8139         rname = preg->name ;
8140     } else
8141         rname = aopGet(AOP(left),0,FALSE,FALSE);
8142     
8143     freeAsmop(left,NULL,ic,TRUE);
8144     aopOp (result,ic,FALSE);
8145
8146     /* if bitfield then unpack the bits */
8147     if (IS_BITVAR(retype)) 
8148         genUnpackBits (result,rname,PPOINTER);
8149     else {
8150         /* we have can just get the values */
8151         int size = AOP_SIZE(result);
8152         int offset = 0 ;        
8153         
8154         while (size--) {
8155             
8156             pic14_emitcode("movx","a,@%s",rname);
8157             aopPut(AOP(result),"a",offset);
8158             
8159             offset++ ;
8160             
8161             if (size)
8162                 pic14_emitcode("inc","%s",rname);
8163         }
8164     }
8165
8166     /* now some housekeeping stuff */
8167     if (aop) {
8168         /* we had to allocate for this iCode */
8169         freeAsmop(NULL,aop,ic,TRUE);
8170     } else { 
8171         /* we did not allocate which means left
8172            already in a pointer register, then
8173            if size > 0 && this could be used again
8174            we have to point it back to where it 
8175            belongs */
8176         if (AOP_SIZE(result) > 1 &&
8177             !OP_SYMBOL(left)->remat &&
8178             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8179               ic->depth )) {
8180             int size = AOP_SIZE(result) - 1;
8181             while (size--)
8182                 pic14_emitcode("dec","%s",rname);
8183         }
8184     }
8185
8186     /* done */
8187     freeAsmop(result,NULL,ic,TRUE);
8188     
8189         
8190 }
8191
8192 /*-----------------------------------------------------------------*/
8193 /* genFarPointerGet - gget value from far space                    */
8194 /*-----------------------------------------------------------------*/
8195 static void genFarPointerGet (operand *left,
8196                               operand *result, iCode *ic)
8197 {
8198     int size, offset ;
8199     sym_link *retype = getSpec(operandType(result));
8200
8201     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8202
8203     aopOp(left,ic,FALSE);
8204
8205     /* if the operand is already in dptr 
8206     then we do nothing else we move the value to dptr */
8207     if (AOP_TYPE(left) != AOP_STR) {
8208         /* if this is remateriazable */
8209         if (AOP_TYPE(left) == AOP_IMMD)
8210             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8211         else { /* we need to get it byte by byte */
8212             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8213             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8214             if (options.model == MODEL_FLAT24)
8215             {
8216                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8217             }
8218         }
8219     }
8220     /* so dptr know contains the address */
8221     freeAsmop(left,NULL,ic,TRUE);
8222     aopOp(result,ic,FALSE);
8223
8224     /* if bit then unpack */
8225     if (IS_BITVAR(retype)) 
8226         genUnpackBits(result,"dptr",FPOINTER);
8227     else {
8228         size = AOP_SIZE(result);
8229         offset = 0 ;
8230
8231         while (size--) {
8232             pic14_emitcode("movx","a,@dptr");
8233             aopPut(AOP(result),"a",offset++);
8234             if (size)
8235                 pic14_emitcode("inc","dptr");
8236         }
8237     }
8238
8239     freeAsmop(result,NULL,ic,TRUE);
8240 }
8241 #if 0
8242 /*-----------------------------------------------------------------*/
8243 /* genCodePointerGet - get value from code space                  */
8244 /*-----------------------------------------------------------------*/
8245 static void genCodePointerGet (operand *left,
8246                                 operand *result, iCode *ic)
8247 {
8248     int size, offset ;
8249     sym_link *retype = getSpec(operandType(result));
8250
8251     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8252
8253     aopOp(left,ic,FALSE);
8254
8255     /* if the operand is already in dptr 
8256     then we do nothing else we move the value to dptr */
8257     if (AOP_TYPE(left) != AOP_STR) {
8258         /* if this is remateriazable */
8259         if (AOP_TYPE(left) == AOP_IMMD)
8260             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8261         else { /* we need to get it byte by byte */
8262             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8263             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8264             if (options.model == MODEL_FLAT24)
8265             {
8266                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8267             }
8268         }
8269     }
8270     /* so dptr know contains the address */
8271     freeAsmop(left,NULL,ic,TRUE);
8272     aopOp(result,ic,FALSE);
8273
8274     /* if bit then unpack */
8275     if (IS_BITVAR(retype)) 
8276         genUnpackBits(result,"dptr",CPOINTER);
8277     else {
8278         size = AOP_SIZE(result);
8279         offset = 0 ;
8280
8281         while (size--) {
8282             pic14_emitcode("clr","a");
8283             pic14_emitcode("movc","a,@a+dptr");
8284             aopPut(AOP(result),"a",offset++);
8285             if (size)
8286                 pic14_emitcode("inc","dptr");
8287         }
8288     }
8289
8290     freeAsmop(result,NULL,ic,TRUE);
8291 }
8292 #endif
8293 /*-----------------------------------------------------------------*/
8294 /* genGenPointerGet - gget value from generic pointer space        */
8295 /*-----------------------------------------------------------------*/
8296 static void genGenPointerGet (operand *left,
8297                               operand *result, iCode *ic)
8298 {
8299   int size, offset ;
8300   sym_link *retype = getSpec(operandType(result));
8301
8302   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8303   aopOp(left,ic,FALSE);
8304   aopOp(result,ic,FALSE);
8305
8306
8307   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8308
8309   /* if the operand is already in dptr 
8310      then we do nothing else we move the value to dptr */
8311   //  if (AOP_TYPE(left) != AOP_STR) {
8312     /* if this is remateriazable */
8313     if (AOP_TYPE(left) == AOP_IMMD) {
8314       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8315       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8316     }
8317     else { /* we need to get it byte by byte */
8318
8319       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8320       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8321
8322       size = AOP_SIZE(result);
8323       offset = 0 ;
8324
8325       while(size--) {
8326         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8327         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8328         if(size)
8329           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8330       }
8331       goto release;
8332     }
8333     //}
8334   /* so dptr know contains the address */
8335
8336   /* if bit then unpack */
8337   //if (IS_BITVAR(retype)) 
8338   //  genUnpackBits(result,"dptr",GPOINTER);
8339
8340  release:
8341   freeAsmop(left,NULL,ic,TRUE);
8342   freeAsmop(result,NULL,ic,TRUE);
8343
8344 }
8345
8346 /*-----------------------------------------------------------------*/
8347 /* genConstPointerGet - get value from const generic pointer space */
8348 /*-----------------------------------------------------------------*/
8349 static void genConstPointerGet (operand *left,
8350                                 operand *result, iCode *ic)
8351 {
8352   //sym_link *retype = getSpec(operandType(result));
8353   symbol *albl = newiTempLabel(NULL);
8354   symbol *blbl = newiTempLabel(NULL);
8355   PIC_OPCODE poc;
8356
8357   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8358   aopOp(left,ic,FALSE);
8359   aopOp(result,ic,FALSE);
8360
8361
8362   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8363
8364   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8365
8366   emitpcode(POC_CALL,popGetLabel(albl->key));
8367   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8368   emitpLabel(albl->key);
8369
8370   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8371     
8372   emitpcode(poc,popGet(AOP(left),1));
8373   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8374   emitpcode(poc,popGet(AOP(left),0));
8375   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8376
8377   emitpLabel(blbl->key);
8378
8379   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8380
8381
8382   freeAsmop(left,NULL,ic,TRUE);
8383   freeAsmop(result,NULL,ic,TRUE);
8384
8385 }
8386 /*-----------------------------------------------------------------*/
8387 /* genPointerGet - generate code for pointer get                   */
8388 /*-----------------------------------------------------------------*/
8389 static void genPointerGet (iCode *ic)
8390 {
8391     operand *left, *result ;
8392     sym_link *type, *etype;
8393     int p_type;
8394
8395     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8396
8397     left = IC_LEFT(ic);
8398     result = IC_RESULT(ic) ;
8399
8400     /* depending on the type of pointer we need to
8401     move it to the correct pointer register */
8402     type = operandType(left);
8403     etype = getSpec(type);
8404
8405     if (IS_PTR_CONST(type))
8406       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8407
8408     /* if left is of type of pointer then it is simple */
8409     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8410         p_type = DCL_TYPE(type);
8411     else {
8412         /* we have to go by the storage class */
8413         p_type = PTR_TYPE(SPEC_OCLS(etype));
8414
8415         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8416
8417         if (SPEC_OCLS(etype)->codesp ) {
8418           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8419           //p_type = CPOINTER ; 
8420         }
8421         else
8422             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8423               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8424                /*p_type = FPOINTER ;*/ 
8425             else
8426                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8427                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8428 /*                  p_type = PPOINTER; */
8429                 else
8430                     if (SPEC_OCLS(etype) == idata )
8431                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8432 /*                      p_type = IPOINTER; */
8433                     else
8434                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8435 /*                      p_type = POINTER ; */
8436     }
8437
8438     /* now that we have the pointer type we assign
8439     the pointer values */
8440     switch (p_type) {
8441
8442     case POINTER:       
8443     case IPOINTER:
8444         genNearPointerGet (left,result,ic);
8445         break;
8446
8447     case PPOINTER:
8448         genPagedPointerGet(left,result,ic);
8449         break;
8450
8451     case FPOINTER:
8452         genFarPointerGet (left,result,ic);
8453         break;
8454
8455     case CPOINTER:
8456         genConstPointerGet (left,result,ic);
8457         //pic14_emitcodePointerGet (left,result,ic);
8458         break;
8459
8460     case GPOINTER:
8461       if (IS_PTR_CONST(type))
8462         genConstPointerGet (left,result,ic);
8463       else
8464         genGenPointerGet (left,result,ic);
8465       break;
8466     }
8467
8468 }
8469
8470 /*-----------------------------------------------------------------*/
8471 /* genPackBits - generates code for packed bit storage             */
8472 /*-----------------------------------------------------------------*/
8473 static void genPackBits (sym_link    *etype ,
8474                          operand *right ,
8475                          char *rname, int p_type)
8476 {
8477     int shCount = 0 ;
8478     int offset = 0  ;
8479     int rLen = 0 ;
8480     int blen, bstr ;   
8481     char *l ;
8482
8483     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8484     blen = SPEC_BLEN(etype);
8485     bstr = SPEC_BSTR(etype);
8486
8487     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8488     MOVA(l);   
8489
8490     /* if the bit lenth is less than or    */
8491     /* it exactly fits a byte then         */
8492     if (SPEC_BLEN(etype) <= 8 )  {
8493         shCount = SPEC_BSTR(etype) ;
8494
8495         /* shift left acc */
8496         AccLsh(shCount);
8497
8498         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8499
8500
8501             switch (p_type) {
8502                 case POINTER:
8503                     pic14_emitcode ("mov","b,a");
8504                     pic14_emitcode("mov","a,@%s",rname);
8505                     break;
8506
8507                 case FPOINTER:
8508                     pic14_emitcode ("mov","b,a");
8509                     pic14_emitcode("movx","a,@dptr");
8510                     break;
8511
8512                 case GPOINTER:
8513                     pic14_emitcode ("push","b");
8514                     pic14_emitcode ("push","acc");
8515                     pic14_emitcode ("lcall","__gptrget");
8516                     pic14_emitcode ("pop","b");
8517                     break;
8518             }
8519
8520             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8521                       ((unsigned char)(0xFF << (blen+bstr)) | 
8522                        (unsigned char)(0xFF >> (8-bstr)) ) );
8523             pic14_emitcode ("orl","a,b");
8524             if (p_type == GPOINTER)
8525                 pic14_emitcode("pop","b");
8526         }
8527     }
8528
8529     switch (p_type) {
8530         case POINTER:
8531             pic14_emitcode("mov","@%s,a",rname);
8532             break;
8533
8534         case FPOINTER:
8535             pic14_emitcode("movx","@dptr,a");
8536             break;
8537
8538         case GPOINTER:
8539             DEBUGpic14_emitcode(";lcall","__gptrput");
8540             break;
8541     }
8542
8543     /* if we r done */
8544     if ( SPEC_BLEN(etype) <= 8 )
8545         return ;
8546
8547     pic14_emitcode("inc","%s",rname);
8548     rLen = SPEC_BLEN(etype) ;     
8549
8550     /* now generate for lengths greater than one byte */
8551     while (1) {
8552
8553         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8554
8555         rLen -= 8 ;
8556         if (rLen <= 0 )
8557             break ;
8558
8559         switch (p_type) {
8560             case POINTER:
8561                 if (*l == '@') {
8562                     MOVA(l);
8563                     pic14_emitcode("mov","@%s,a",rname);
8564                 } else
8565                     pic14_emitcode("mov","@%s,%s",rname,l);
8566                 break;
8567
8568             case FPOINTER:
8569                 MOVA(l);
8570                 pic14_emitcode("movx","@dptr,a");
8571                 break;
8572
8573             case GPOINTER:
8574                 MOVA(l);
8575                 DEBUGpic14_emitcode(";lcall","__gptrput");
8576                 break;  
8577         }   
8578         pic14_emitcode ("inc","%s",rname);
8579     }
8580
8581     MOVA(l);
8582
8583     /* last last was not complete */
8584     if (rLen)   {
8585         /* save the byte & read byte */
8586         switch (p_type) {
8587             case POINTER:
8588                 pic14_emitcode ("mov","b,a");
8589                 pic14_emitcode("mov","a,@%s",rname);
8590                 break;
8591
8592             case FPOINTER:
8593                 pic14_emitcode ("mov","b,a");
8594                 pic14_emitcode("movx","a,@dptr");
8595                 break;
8596
8597             case GPOINTER:
8598                 pic14_emitcode ("push","b");
8599                 pic14_emitcode ("push","acc");
8600                 pic14_emitcode ("lcall","__gptrget");
8601                 pic14_emitcode ("pop","b");
8602                 break;
8603         }
8604
8605         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8606         pic14_emitcode ("orl","a,b");
8607     }
8608
8609     if (p_type == GPOINTER)
8610         pic14_emitcode("pop","b");
8611
8612     switch (p_type) {
8613
8614     case POINTER:
8615         pic14_emitcode("mov","@%s,a",rname);
8616         break;
8617         
8618     case FPOINTER:
8619         pic14_emitcode("movx","@dptr,a");
8620         break;
8621         
8622     case GPOINTER:
8623         DEBUGpic14_emitcode(";lcall","__gptrput");
8624         break;                  
8625     }
8626 }
8627 /*-----------------------------------------------------------------*/
8628 /* genDataPointerSet - remat pointer to data space                 */
8629 /*-----------------------------------------------------------------*/
8630 static void genDataPointerSet(operand *right,
8631                               operand *result,
8632                               iCode *ic)
8633 {
8634     int size, offset = 0 ;
8635     char *l, buffer[256];
8636
8637     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8638     aopOp(right,ic,FALSE);
8639     
8640     l = aopGet(AOP(result),0,FALSE,TRUE);
8641     size = AOP_SIZE(right);
8642 /*
8643     if ( AOP_TYPE(result) == AOP_PCODE) {
8644       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8645               AOP(result)->aopu.pcop->name,
8646               PCOI(AOP(result)->aopu.pcop)->offset);
8647     }
8648 */
8649
8650     // tsd, was l+1 - the underline `_' prefix was being stripped
8651     while (size--) {
8652       if (offset) {
8653         sprintf(buffer,"(%s + %d)",l,offset);
8654         fprintf(stderr,"oops  %s\n",buffer);
8655       } else
8656         sprintf(buffer,"%s",l);
8657
8658         if (AOP_TYPE(right) == AOP_LIT) {
8659           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8660           lit = lit >> (8*offset);
8661           if(lit&0xff) {
8662             pic14_emitcode("movlw","%d",lit);
8663             pic14_emitcode("movwf","%s",buffer);
8664
8665             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8666             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8667             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8668
8669           } else {
8670             pic14_emitcode("clrf","%s",buffer);
8671             //emitpcode(POC_CLRF, popRegFromString(buffer));
8672             emitpcode(POC_CLRF, popGet(AOP(result),0));
8673           }
8674         }else {
8675           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8676           pic14_emitcode("movwf","%s",buffer);
8677
8678           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8679           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8680           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8681
8682         }
8683
8684         offset++;
8685     }
8686
8687     freeAsmop(right,NULL,ic,TRUE);
8688     freeAsmop(result,NULL,ic,TRUE);
8689 }
8690
8691 /*-----------------------------------------------------------------*/
8692 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8693 /*-----------------------------------------------------------------*/
8694 static void genNearPointerSet (operand *right,
8695                                operand *result, 
8696                                iCode *ic)
8697 {
8698   asmop *aop = NULL;
8699   char *l;
8700   sym_link *retype;
8701   sym_link *ptype = operandType(result);
8702
8703     
8704   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8705   retype= getSpec(operandType(right));
8706
8707   aopOp(result,ic,FALSE);
8708
8709     
8710   /* if the result is rematerializable &
8711      in data space & not a bit variable */
8712   //if (AOP_TYPE(result) == AOP_IMMD &&
8713   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8714       DCL_TYPE(ptype) == POINTER   &&
8715       !IS_BITVAR(retype)) {
8716     genDataPointerSet (right,result,ic);
8717     freeAsmop(result,NULL,ic,TRUE);
8718     return;
8719   }
8720
8721   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8722   aopOp(right,ic,FALSE);
8723   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8724
8725   /* if the value is already in a pointer register
8726      then don't need anything more */
8727   if (!AOP_INPREG(AOP(result))) {
8728     /* otherwise get a free pointer register */
8729     //aop = newAsmop(0);
8730     //preg = getFreePtr(ic,&aop,FALSE);
8731     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8732     //pic14_emitcode("mov","%s,%s",
8733     //         preg->name,
8734     //         aopGet(AOP(result),0,FALSE,TRUE));
8735     //rname = preg->name ;
8736     //pic14_emitcode("movwf","fsr");
8737     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8738     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8739     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8740     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8741     goto release;
8742
8743   }// else
8744   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8745
8746
8747   /* if bitfield then unpack the bits */
8748   if (IS_BITVAR(retype)) {
8749     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8750            "The programmer is obviously confused");
8751     //genPackBits (retype,right,rname,POINTER);
8752     exit(1);
8753   }
8754   else {
8755     /* we have can just get the values */
8756     int size = AOP_SIZE(right);
8757     int offset = 0 ;    
8758
8759     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8760     while (size--) {
8761       l = aopGet(AOP(right),offset,FALSE,TRUE);
8762       if (*l == '@' ) {
8763         //MOVA(l);
8764         //pic14_emitcode("mov","@%s,a",rname);
8765         pic14_emitcode("movf","indf,w ;1");
8766       } else {
8767
8768         if (AOP_TYPE(right) == AOP_LIT) {
8769           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8770           if(lit) {
8771             pic14_emitcode("movlw","%s",l);
8772             pic14_emitcode("movwf","indf ;2");
8773           } else 
8774             pic14_emitcode("clrf","indf");
8775         }else {
8776           pic14_emitcode("movf","%s,w",l);
8777           pic14_emitcode("movwf","indf ;2");
8778         }
8779         //pic14_emitcode("mov","@%s,%s",rname,l);
8780       }
8781       if (size)
8782         pic14_emitcode("incf","fsr,f ;3");
8783       //pic14_emitcode("inc","%s",rname);
8784       offset++;
8785     }
8786   }
8787
8788   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8789   /* now some housekeeping stuff */
8790   if (aop) {
8791     /* we had to allocate for this iCode */
8792     freeAsmop(NULL,aop,ic,TRUE);
8793   } else { 
8794     /* we did not allocate which means left
8795        already in a pointer register, then
8796        if size > 0 && this could be used again
8797        we have to point it back to where it 
8798        belongs */
8799     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8800     if (AOP_SIZE(right) > 1 &&
8801         !OP_SYMBOL(result)->remat &&
8802         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8803           ic->depth )) {
8804       int size = AOP_SIZE(right) - 1;
8805       while (size--)
8806         pic14_emitcode("decf","fsr,f");
8807       //pic14_emitcode("dec","%s",rname);
8808     }
8809   }
8810
8811   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8812   /* done */
8813  release:
8814   freeAsmop(right,NULL,ic,TRUE);
8815   freeAsmop(result,NULL,ic,TRUE);
8816 }
8817
8818 /*-----------------------------------------------------------------*/
8819 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8820 /*-----------------------------------------------------------------*/
8821 static void genPagedPointerSet (operand *right,
8822                                operand *result, 
8823                                iCode *ic)
8824 {
8825     asmop *aop = NULL;
8826     regs *preg = NULL ;
8827     char *rname , *l;
8828     sym_link *retype;
8829        
8830     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8831
8832     retype= getSpec(operandType(right));
8833     
8834     aopOp(result,ic,FALSE);
8835     
8836     /* if the value is already in a pointer register
8837        then don't need anything more */
8838     if (!AOP_INPREG(AOP(result))) {
8839         /* otherwise get a free pointer register */
8840         aop = newAsmop(0);
8841         preg = getFreePtr(ic,&aop,FALSE);
8842         pic14_emitcode("mov","%s,%s",
8843                 preg->name,
8844                 aopGet(AOP(result),0,FALSE,TRUE));
8845         rname = preg->name ;
8846     } else
8847         rname = aopGet(AOP(result),0,FALSE,FALSE);
8848     
8849     freeAsmop(result,NULL,ic,TRUE);
8850     aopOp (right,ic,FALSE);
8851
8852     /* if bitfield then unpack the bits */
8853     if (IS_BITVAR(retype)) 
8854         genPackBits (retype,right,rname,PPOINTER);
8855     else {
8856         /* we have can just get the values */
8857         int size = AOP_SIZE(right);
8858         int offset = 0 ;        
8859         
8860         while (size--) {
8861             l = aopGet(AOP(right),offset,FALSE,TRUE);
8862             
8863             MOVA(l);
8864             pic14_emitcode("movx","@%s,a",rname);
8865
8866             if (size)
8867                 pic14_emitcode("inc","%s",rname);
8868
8869             offset++;
8870         }
8871     }
8872     
8873     /* now some housekeeping stuff */
8874     if (aop) {
8875         /* we had to allocate for this iCode */
8876         freeAsmop(NULL,aop,ic,TRUE);
8877     } else { 
8878         /* we did not allocate which means left
8879            already in a pointer register, then
8880            if size > 0 && this could be used again
8881            we have to point it back to where it 
8882            belongs */
8883         if (AOP_SIZE(right) > 1 &&
8884             !OP_SYMBOL(result)->remat &&
8885             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8886               ic->depth )) {
8887             int size = AOP_SIZE(right) - 1;
8888             while (size--)
8889                 pic14_emitcode("dec","%s",rname);
8890         }
8891     }
8892
8893     /* done */
8894     freeAsmop(right,NULL,ic,TRUE);
8895     
8896         
8897 }
8898
8899 /*-----------------------------------------------------------------*/
8900 /* genFarPointerSet - set value from far space                     */
8901 /*-----------------------------------------------------------------*/
8902 static void genFarPointerSet (operand *right,
8903                               operand *result, iCode *ic)
8904 {
8905     int size, offset ;
8906     sym_link *retype = getSpec(operandType(right));
8907
8908     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8909     aopOp(result,ic,FALSE);
8910
8911     /* if the operand is already in dptr 
8912     then we do nothing else we move the value to dptr */
8913     if (AOP_TYPE(result) != AOP_STR) {
8914         /* if this is remateriazable */
8915         if (AOP_TYPE(result) == AOP_IMMD)
8916             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8917         else { /* we need to get it byte by byte */
8918             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8919             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8920             if (options.model == MODEL_FLAT24)
8921             {
8922                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8923             }
8924         }
8925     }
8926     /* so dptr know contains the address */
8927     freeAsmop(result,NULL,ic,TRUE);
8928     aopOp(right,ic,FALSE);
8929
8930     /* if bit then unpack */
8931     if (IS_BITVAR(retype)) 
8932         genPackBits(retype,right,"dptr",FPOINTER);
8933     else {
8934         size = AOP_SIZE(right);
8935         offset = 0 ;
8936
8937         while (size--) {
8938             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8939             MOVA(l);
8940             pic14_emitcode("movx","@dptr,a");
8941             if (size)
8942                 pic14_emitcode("inc","dptr");
8943         }
8944     }
8945
8946     freeAsmop(right,NULL,ic,TRUE);
8947 }
8948
8949 /*-----------------------------------------------------------------*/
8950 /* genGenPointerSet - set value from generic pointer space         */
8951 /*-----------------------------------------------------------------*/
8952 static void genGenPointerSet (operand *right,
8953                               operand *result, iCode *ic)
8954 {
8955   int size, offset ;
8956   sym_link *retype = getSpec(operandType(right));
8957
8958   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8959
8960   aopOp(result,ic,FALSE);
8961   aopOp(right,ic,FALSE);
8962   size = AOP_SIZE(right);
8963
8964   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8965
8966   /* if the operand is already in dptr 
8967      then we do nothing else we move the value to dptr */
8968   if (AOP_TYPE(result) != AOP_STR) {
8969     /* if this is remateriazable */
8970     if (AOP_TYPE(result) == AOP_IMMD) {
8971       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8972       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8973     }
8974     else { /* we need to get it byte by byte */
8975       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8976       size = AOP_SIZE(right);
8977       offset = 0 ;
8978
8979       /* hack hack! see if this the FSR. If so don't load W */
8980       if(AOP_TYPE(right) != AOP_ACC) {
8981
8982
8983         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8984         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8985
8986         if(AOP_SIZE(result) > 1) {
8987           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8988           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8989           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8990
8991         }
8992
8993         //if(size==2)
8994         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8995         //if(size==4) {
8996         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8997         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8998         //}
8999
9000         while(size--) {
9001           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9002           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9003           
9004           if(size)
9005             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9006         }
9007
9008
9009         goto release;
9010       } 
9011
9012       if(aopIdx(AOP(result),0) != 4) {
9013
9014         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9015         goto release;
9016       }
9017
9018       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9019       goto release;
9020
9021     }
9022   }
9023   /* so dptr know contains the address */
9024
9025
9026   /* if bit then unpack */
9027   if (IS_BITVAR(retype)) 
9028     genPackBits(retype,right,"dptr",GPOINTER);
9029   else {
9030     size = AOP_SIZE(right);
9031     offset = 0 ;
9032
9033   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9034
9035     while (size--) {
9036
9037       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9038       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9039
9040       if (AOP_TYPE(right) == AOP_LIT) 
9041         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9042       else
9043         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9044
9045       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9046
9047       offset++;
9048     }
9049   }
9050
9051  release:
9052   freeAsmop(right,NULL,ic,TRUE);
9053   freeAsmop(result,NULL,ic,TRUE);
9054 }
9055
9056 /*-----------------------------------------------------------------*/
9057 /* genPointerSet - stores the value into a pointer location        */
9058 /*-----------------------------------------------------------------*/
9059 static void genPointerSet (iCode *ic)
9060 {    
9061     operand *right, *result ;
9062     sym_link *type, *etype;
9063     int p_type;
9064
9065     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9066
9067     right = IC_RIGHT(ic);
9068     result = IC_RESULT(ic) ;
9069
9070     /* depending on the type of pointer we need to
9071     move it to the correct pointer register */
9072     type = operandType(result);
9073     etype = getSpec(type);
9074     /* if left is of type of pointer then it is simple */
9075     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9076         p_type = DCL_TYPE(type);
9077     }
9078     else {
9079         /* we have to go by the storage class */
9080         p_type = PTR_TYPE(SPEC_OCLS(etype));
9081
9082 /*      if (SPEC_OCLS(etype)->codesp ) { */
9083 /*          p_type = CPOINTER ;  */
9084 /*      } */
9085 /*      else */
9086 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9087 /*              p_type = FPOINTER ; */
9088 /*          else */
9089 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9090 /*                  p_type = PPOINTER ; */
9091 /*              else */
9092 /*                  if (SPEC_OCLS(etype) == idata ) */
9093 /*                      p_type = IPOINTER ; */
9094 /*                  else */
9095 /*                      p_type = POINTER ; */
9096     }
9097
9098     /* now that we have the pointer type we assign
9099     the pointer values */
9100     switch (p_type) {
9101
9102     case POINTER:
9103     case IPOINTER:
9104         genNearPointerSet (right,result,ic);
9105         break;
9106
9107     case PPOINTER:
9108         genPagedPointerSet (right,result,ic);
9109         break;
9110
9111     case FPOINTER:
9112         genFarPointerSet (right,result,ic);
9113         break;
9114
9115     case GPOINTER:
9116         genGenPointerSet (right,result,ic);
9117         break;
9118
9119     default:
9120       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9121               "genPointerSet: illegal pointer type");
9122     }
9123 }
9124
9125 /*-----------------------------------------------------------------*/
9126 /* genIfx - generate code for Ifx statement                        */
9127 /*-----------------------------------------------------------------*/
9128 static void genIfx (iCode *ic, iCode *popIc)
9129 {
9130   operand *cond = IC_COND(ic);
9131   int isbit =0;
9132
9133   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9134
9135   aopOp(cond,ic,FALSE);
9136
9137   /* get the value into acc */
9138   if (AOP_TYPE(cond) != AOP_CRY)
9139     pic14_toBoolean(cond);
9140   else
9141     isbit = 1;
9142   /* the result is now in the accumulator */
9143   freeAsmop(cond,NULL,ic,TRUE);
9144
9145   /* if there was something to be popped then do it */
9146   if (popIc)
9147     genIpop(popIc);
9148
9149   /* if the condition is  a bit variable */
9150   if (isbit && IS_ITEMP(cond) && 
9151       SPIL_LOC(cond)) {
9152     genIfxJump(ic,SPIL_LOC(cond)->rname);
9153     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9154   }
9155   else {
9156     if (isbit && !IS_ITEMP(cond))
9157       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9158     else
9159       genIfxJump(ic,"a");
9160   }
9161   ic->generated = 1;
9162
9163 }
9164
9165 /*-----------------------------------------------------------------*/
9166 /* genAddrOf - generates code for address of                       */
9167 /*-----------------------------------------------------------------*/
9168 static void genAddrOf (iCode *ic)
9169 {
9170   operand *right, *result, *left;
9171   int size, offset ;
9172
9173   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9174
9175
9176   //aopOp(IC_RESULT(ic),ic,FALSE);
9177
9178   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9179   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9180   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9181
9182   DEBUGpic14_AopType(__LINE__,left,right,result);
9183
9184   size = AOP_SIZE(IC_RESULT(ic));
9185   offset = 0;
9186
9187   while (size--) {
9188     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9189     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9190     offset++;
9191   }
9192
9193   freeAsmop(left,NULL,ic,FALSE);
9194   freeAsmop(result,NULL,ic,TRUE);
9195
9196 }
9197
9198 #if 0
9199 /*-----------------------------------------------------------------*/
9200 /* genFarFarAssign - assignment when both are in far space         */
9201 /*-----------------------------------------------------------------*/
9202 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9203 {
9204     int size = AOP_SIZE(right);
9205     int offset = 0;
9206     char *l ;
9207     /* first push the right side on to the stack */
9208     while (size--) {
9209         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9210         MOVA(l);
9211         pic14_emitcode ("push","acc");
9212     }
9213     
9214     freeAsmop(right,NULL,ic,FALSE);
9215     /* now assign DPTR to result */
9216     aopOp(result,ic,FALSE);
9217     size = AOP_SIZE(result);
9218     while (size--) {
9219         pic14_emitcode ("pop","acc");
9220         aopPut(AOP(result),"a",--offset);
9221     }
9222     freeAsmop(result,NULL,ic,FALSE);
9223         
9224 }
9225 #endif
9226
9227 /*-----------------------------------------------------------------*/
9228 /* genAssign - generate code for assignment                        */
9229 /*-----------------------------------------------------------------*/
9230 static void genAssign (iCode *ic)
9231 {
9232   operand *result, *right;
9233   int size, offset,know_W;
9234   unsigned long lit = 0L;
9235
9236   result = IC_RESULT(ic);
9237   right  = IC_RIGHT(ic) ;
9238
9239   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9240
9241   /* if they are the same */
9242   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9243     return ;
9244
9245   aopOp(right,ic,FALSE);
9246   aopOp(result,ic,TRUE);
9247
9248   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9249
9250   /* if they are the same registers */
9251   if (pic14_sameRegs(AOP(right),AOP(result)))
9252     goto release;
9253
9254   /* if the result is a bit */
9255   if (AOP_TYPE(result) == AOP_CRY) {
9256
9257     /* if the right size is a literal then
9258        we know what the value is */
9259     if (AOP_TYPE(right) == AOP_LIT) {
9260           
9261       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9262                   popGet(AOP(result),0));
9263
9264       if (((int) operandLitValue(right))) 
9265         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9266                        AOP(result)->aopu.aop_dir,
9267                        AOP(result)->aopu.aop_dir);
9268       else
9269         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9270                        AOP(result)->aopu.aop_dir,
9271                        AOP(result)->aopu.aop_dir);
9272       goto release;
9273     }
9274
9275     /* the right is also a bit variable */
9276     if (AOP_TYPE(right) == AOP_CRY) {
9277       emitpcode(POC_BCF,    popGet(AOP(result),0));
9278       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9279       emitpcode(POC_BSF,    popGet(AOP(result),0));
9280
9281       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9282                      AOP(result)->aopu.aop_dir,
9283                      AOP(result)->aopu.aop_dir);
9284       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9285                      AOP(right)->aopu.aop_dir,
9286                      AOP(right)->aopu.aop_dir);
9287       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9288                      AOP(result)->aopu.aop_dir,
9289                      AOP(result)->aopu.aop_dir);
9290       goto release ;
9291     }
9292
9293     /* we need to or */
9294     emitpcode(POC_BCF,    popGet(AOP(result),0));
9295     pic14_toBoolean(right);
9296     emitSKPZ;
9297     emitpcode(POC_BSF,    popGet(AOP(result),0));
9298     //aopPut(AOP(result),"a",0);
9299     goto release ;
9300   }
9301
9302   /* bit variables done */
9303   /* general case */
9304   size = AOP_SIZE(result);
9305   offset = 0 ;
9306   if(AOP_TYPE(right) == AOP_LIT)
9307     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9308
9309   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9310   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9311     if(aopIdx(AOP(result),0) == 4) {
9312   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9313       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9314       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9315       goto release;
9316     } else
9317       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9318   }
9319
9320   know_W=-1;
9321   while (size--) {
9322   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9323     if(AOP_TYPE(right) == AOP_LIT) {
9324       if(lit&0xff) {
9325         if(know_W != (lit&0xff))
9326           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9327         know_W = lit&0xff;
9328         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9329       } else
9330         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9331
9332       lit >>= 8;
9333
9334     } else if (AOP_TYPE(right) == AOP_CRY) {
9335       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9336       if(offset == 0) {
9337         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9338         emitpcode(POC_INCF, popGet(AOP(result),0));
9339       }
9340     } else {
9341   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9342       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9343       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9344     }
9345             
9346     offset++;
9347   }
9348
9349     
9350  release:
9351   freeAsmop (right,NULL,ic,FALSE);
9352   freeAsmop (result,NULL,ic,TRUE);
9353 }   
9354
9355 /*-----------------------------------------------------------------*/
9356 /* genJumpTab - genrates code for jump table                       */
9357 /*-----------------------------------------------------------------*/
9358 static void genJumpTab (iCode *ic)
9359 {
9360     symbol *jtab;
9361     char *l;
9362
9363     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9364
9365     aopOp(IC_JTCOND(ic),ic,FALSE);
9366     /* get the condition into accumulator */
9367     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9368     MOVA(l);
9369     /* multiply by three */
9370     pic14_emitcode("add","a,acc");
9371     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9372
9373     jtab = newiTempLabel(NULL);
9374     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9375     pic14_emitcode("jmp","@a+dptr");
9376     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9377
9378     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9379     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9380     emitSKPNC;
9381     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9382     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9383     emitpLabel(jtab->key);
9384
9385     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9386
9387     /* now generate the jump labels */
9388     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9389          jtab = setNextItem(IC_JTLABELS(ic))) {
9390         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9391         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9392         
9393     }
9394
9395 }
9396
9397 /*-----------------------------------------------------------------*/
9398 /* genMixedOperation - gen code for operators between mixed types  */
9399 /*-----------------------------------------------------------------*/
9400 /*
9401   TSD - Written for the PIC port - but this unfortunately is buggy.
9402   This routine is good in that it is able to efficiently promote 
9403   types to different (larger) sizes. Unfortunately, the temporary
9404   variables that are optimized out by this routine are sometimes
9405   used in other places. So until I know how to really parse the 
9406   iCode tree, I'm going to not be using this routine :(.
9407 */
9408 static int genMixedOperation (iCode *ic)
9409 {
9410 #if 0
9411   operand *result = IC_RESULT(ic);
9412   sym_link *ctype = operandType(IC_LEFT(ic));
9413   operand *right = IC_RIGHT(ic);
9414   int ret = 0;
9415   int big,small;
9416   int offset;
9417
9418   iCode *nextic;
9419   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9420
9421   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9422
9423   nextic = ic->next;
9424   if(!nextic)
9425     return 0;
9426
9427   nextright = IC_RIGHT(nextic);
9428   nextleft  = IC_LEFT(nextic);
9429   nextresult = IC_RESULT(nextic);
9430
9431   aopOp(right,ic,FALSE);
9432   aopOp(result,ic,FALSE);
9433   aopOp(nextright,  nextic, FALSE);
9434   aopOp(nextleft,   nextic, FALSE);
9435   aopOp(nextresult, nextic, FALSE);
9436
9437   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9438
9439     operand *t = right;
9440     right = nextright;
9441     nextright = t; 
9442
9443     pic14_emitcode(";remove right +","");
9444
9445   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9446 /*
9447     operand *t = right;
9448     right = nextleft;
9449     nextleft = t; 
9450 */
9451     pic14_emitcode(";remove left +","");
9452   } else
9453     return 0;
9454
9455   big = AOP_SIZE(nextleft);
9456   small = AOP_SIZE(nextright);
9457
9458   switch(nextic->op) {
9459
9460   case '+':
9461     pic14_emitcode(";optimize a +","");
9462     /* if unsigned or not an integral type */
9463     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9464       pic14_emitcode(";add a bit to something","");
9465     } else {
9466
9467       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9468
9469       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9470         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9471         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9472       } else
9473         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9474
9475       offset = 0;
9476       while(--big) {
9477
9478         offset++;
9479
9480         if(--small) {
9481           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9482             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9483             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9484           }
9485
9486           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9487           emitSKPNC;
9488           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9489                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9490                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9491           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9492           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9493
9494         } else {
9495           pic14_emitcode("rlf","known_zero,w");
9496
9497           /*
9498             if right is signed
9499               btfsc  right,7
9500                addlw ff
9501           */
9502           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9503             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9504             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9505           } else {
9506             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9507           }
9508         }
9509       }
9510       ret = 1;
9511     }
9512   }
9513   ret = 1;
9514
9515 release:
9516   freeAsmop(right,NULL,ic,TRUE);
9517   freeAsmop(result,NULL,ic,TRUE);
9518   freeAsmop(nextright,NULL,ic,TRUE);
9519   freeAsmop(nextleft,NULL,ic,TRUE);
9520   if(ret)
9521     nextic->generated = 1;
9522
9523   return ret;
9524 #else
9525   return 0;
9526 #endif
9527 }
9528 /*-----------------------------------------------------------------*/
9529 /* genCast - gen code for casting                                  */
9530 /*-----------------------------------------------------------------*/
9531 static void genCast (iCode *ic)
9532 {
9533     operand *result = IC_RESULT(ic);
9534     sym_link *ctype = operandType(IC_LEFT(ic));
9535     sym_link *rtype = operandType(IC_RIGHT(ic));
9536     operand *right = IC_RIGHT(ic);
9537     int size, offset ;
9538
9539     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9540     /* if they are equivalent then do nothing */
9541     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9542         return ;
9543
9544     aopOp(right,ic,FALSE) ;
9545     aopOp(result,ic,FALSE);
9546
9547     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9548
9549     /* if the result is a bit */
9550     if (AOP_TYPE(result) == AOP_CRY) {
9551         /* if the right size is a literal then
9552         we know what the value is */
9553       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9554         if (AOP_TYPE(right) == AOP_LIT) {
9555
9556           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9557                       popGet(AOP(result),0));
9558
9559             if (((int) operandLitValue(right))) 
9560               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9561                        AOP(result)->aopu.aop_dir,
9562                        AOP(result)->aopu.aop_dir);
9563             else
9564               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9565                        AOP(result)->aopu.aop_dir,
9566                        AOP(result)->aopu.aop_dir);
9567
9568             goto release;
9569         }
9570
9571         /* the right is also a bit variable */
9572         if (AOP_TYPE(right) == AOP_CRY) {
9573
9574           emitCLRC;
9575           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9576
9577           pic14_emitcode("clrc","");
9578           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9579                    AOP(right)->aopu.aop_dir,
9580                    AOP(right)->aopu.aop_dir);
9581             aopPut(AOP(result),"c",0);
9582             goto release ;
9583         }
9584
9585         /* we need to or */
9586         if (AOP_TYPE(right) == AOP_REG) {
9587           emitpcode(POC_BCF,    popGet(AOP(result),0));
9588           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9589           emitpcode(POC_BSF,    popGet(AOP(result),0));
9590         }
9591         pic14_toBoolean(right);
9592         aopPut(AOP(result),"a",0);
9593         goto release ;
9594     }
9595
9596     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9597       int offset = 1;
9598       size = AOP_SIZE(result);
9599
9600       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9601
9602       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9603       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9604       emitpcode(POC_INCF,   popGet(AOP(result),0));
9605
9606       while (size--)
9607         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9608
9609       goto release;
9610     }
9611
9612     /* if they are the same size : or less */
9613     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9614
9615         /* if they are in the same place */
9616       if (pic14_sameRegs(AOP(right),AOP(result)))
9617         goto release;
9618
9619       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9620       if (IS_PTR_CONST(rtype))
9621         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9622       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9623         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9624
9625       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9626         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9627         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9628         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9629         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9630         if(AOP_SIZE(result) <2)
9631           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9632
9633       } else {
9634
9635         /* if they in different places then copy */
9636         size = AOP_SIZE(result);
9637         offset = 0 ;
9638         while (size--) {
9639           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9640           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9641
9642           //aopPut(AOP(result),
9643           // aopGet(AOP(right),offset,FALSE,FALSE),
9644           // offset);
9645
9646           offset++;
9647         }
9648       }
9649       goto release;
9650     }
9651
9652
9653     /* if the result is of type pointer */
9654     if (IS_PTR(ctype)) {
9655
9656         int p_type;
9657         sym_link *type = operandType(right);
9658         sym_link *etype = getSpec(type);
9659       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9660
9661         /* pointer to generic pointer */
9662         if (IS_GENPTR(ctype)) {
9663             char *l = zero;
9664             
9665             if (IS_PTR(type)) 
9666                 p_type = DCL_TYPE(type);
9667             else {
9668                 /* we have to go by the storage class */
9669                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9670
9671 /*              if (SPEC_OCLS(etype)->codesp )  */
9672 /*                  p_type = CPOINTER ;  */
9673 /*              else */
9674 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9675 /*                      p_type = FPOINTER ; */
9676 /*                  else */
9677 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9678 /*                          p_type = PPOINTER; */
9679 /*                      else */
9680 /*                          if (SPEC_OCLS(etype) == idata ) */
9681 /*                              p_type = IPOINTER ; */
9682 /*                          else */
9683 /*                              p_type = POINTER ; */
9684             }
9685                 
9686             /* the first two bytes are known */
9687       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9688             size = GPTRSIZE - 1; 
9689             offset = 0 ;
9690             while (size--) {
9691               if(offset < AOP_SIZE(right)) {
9692       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9693                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9694                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9695                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9696                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9697                 } else { 
9698                   aopPut(AOP(result),
9699                          aopGet(AOP(right),offset,FALSE,FALSE),
9700                          offset);
9701                 }
9702               } else 
9703                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9704               offset++;
9705             }
9706             /* the last byte depending on type */
9707             switch (p_type) {
9708             case IPOINTER:
9709             case POINTER:
9710                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9711                 break;
9712             case FPOINTER:
9713               pic14_emitcode(";BUG!? ","%d",__LINE__);
9714                 l = one;
9715                 break;
9716             case CPOINTER:
9717               pic14_emitcode(";BUG!? ","%d",__LINE__);
9718                 l = "#0x02";
9719                 break;                          
9720             case PPOINTER:
9721               pic14_emitcode(";BUG!? ","%d",__LINE__);
9722                 l = "#0x03";
9723                 break;
9724                 
9725             default:
9726                 /* this should never happen */
9727                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9728                        "got unknown pointer type");
9729                 exit(1);
9730             }
9731             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9732             goto release ;
9733         }
9734         
9735         /* just copy the pointers */
9736         size = AOP_SIZE(result);
9737         offset = 0 ;
9738         while (size--) {
9739             aopPut(AOP(result),
9740                    aopGet(AOP(right),offset,FALSE,FALSE),
9741                    offset);
9742             offset++;
9743         }
9744         goto release ;
9745     }
9746     
9747
9748
9749     /* so we now know that the size of destination is greater
9750     than the size of the source.
9751     Now, if the next iCode is an operator then we might be
9752     able to optimize the operation without performing a cast.
9753     */
9754     if(genMixedOperation(ic))
9755       goto release;
9756
9757     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9758     
9759     /* we move to result for the size of source */
9760     size = AOP_SIZE(right);
9761     offset = 0 ;
9762     while (size--) {
9763       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9764       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9765       offset++;
9766     }
9767
9768     /* now depending on the sign of the destination */
9769     size = AOP_SIZE(result) - AOP_SIZE(right);
9770     /* if unsigned or not an integral type */
9771     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9772       while (size--)
9773         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9774     } else {
9775       /* we need to extend the sign :{ */
9776
9777       if(size == 1) {
9778         /* Save one instruction of casting char to int */
9779         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9780         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9781         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9782       } else {
9783         emitpcodeNULLop(POC_CLRW);
9784
9785         if(offset)
9786           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9787         else
9788           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9789         
9790         emitpcode(POC_MOVLW,   popGetLit(0xff));
9791
9792         while (size--)
9793           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9794       }
9795     }
9796
9797 release:
9798     freeAsmop(right,NULL,ic,TRUE);
9799     freeAsmop(result,NULL,ic,TRUE);
9800
9801 }
9802
9803 /*-----------------------------------------------------------------*/
9804 /* genDjnz - generate decrement & jump if not zero instrucion      */
9805 /*-----------------------------------------------------------------*/
9806 static int genDjnz (iCode *ic, iCode *ifx)
9807 {
9808     symbol *lbl, *lbl1;
9809     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9810
9811     if (!ifx)
9812         return 0;
9813     
9814     /* if the if condition has a false label
9815        then we cannot save */
9816     if (IC_FALSE(ifx))
9817         return 0;
9818
9819     /* if the minus is not of the form 
9820        a = a - 1 */
9821     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9822         !IS_OP_LITERAL(IC_RIGHT(ic)))
9823         return 0;
9824
9825     if (operandLitValue(IC_RIGHT(ic)) != 1)
9826         return 0;
9827
9828     /* if the size of this greater than one then no
9829        saving */
9830     if (getSize(operandType(IC_RESULT(ic))) > 1)
9831         return 0;
9832
9833     /* otherwise we can save BIG */
9834     lbl = newiTempLabel(NULL);
9835     lbl1= newiTempLabel(NULL);
9836
9837     aopOp(IC_RESULT(ic),ic,FALSE);
9838     
9839     if (IS_AOP_PREG(IC_RESULT(ic))) {
9840         pic14_emitcode("dec","%s",
9841                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9842         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9844     } else {    
9845
9846
9847       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9848       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9849
9850       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9851       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9852
9853     }
9854 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9855 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9856 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9857 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9858
9859     
9860     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9861     ifx->generated = 1;
9862     return 1;
9863 }
9864
9865 /*-----------------------------------------------------------------*/
9866 /* genReceive - generate code for a receive iCode                  */
9867 /*-----------------------------------------------------------------*/
9868 static void genReceive (iCode *ic)
9869 {    
9870   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9871
9872   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9873       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9874         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9875
9876     int size = getSize(operandType(IC_RESULT(ic)));
9877     int offset =  fReturnSizePic - size;
9878     while (size--) {
9879       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9880                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9881       offset++;
9882     }
9883     aopOp(IC_RESULT(ic),ic,FALSE);  
9884     size = AOP_SIZE(IC_RESULT(ic));
9885     offset = 0;
9886     while (size--) {
9887       pic14_emitcode ("pop","acc");
9888       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9889     }
9890         
9891   } else {
9892     _G.accInUse++;
9893     aopOp(IC_RESULT(ic),ic,FALSE);  
9894     _G.accInUse--;
9895     assignResultValue(IC_RESULT(ic));   
9896   }
9897
9898   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9899 }
9900
9901 /*-----------------------------------------------------------------*/
9902 /* genpic14Code - generate code for pic14 based controllers        */
9903 /*-----------------------------------------------------------------*/
9904 /*
9905  * At this point, ralloc.c has gone through the iCode and attempted
9906  * to optimize in a way suitable for a PIC. Now we've got to generate
9907  * PIC instructions that correspond to the iCode.
9908  *
9909  * Once the instructions are generated, we'll pass through both the
9910  * peep hole optimizer and the pCode optimizer.
9911  *-----------------------------------------------------------------*/
9912
9913 void genpic14Code (iCode *lic)
9914 {
9915     iCode *ic;
9916     int cln = 0;
9917
9918     lineHead = lineCurr = NULL;
9919
9920     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9921     addpBlock(pb);
9922
9923     /* if debug information required */
9924     if (options.debug && currFunc) { 
9925       if (currFunc) {
9926         debugFile->writeFunction(currFunc);
9927         _G.debugLine = 1;
9928         if (IS_STATIC(currFunc->etype)) {
9929           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9930           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9931         } else {
9932           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9933           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9934         }
9935         _G.debugLine = 0;
9936       }
9937     }
9938
9939
9940     for (ic = lic ; ic ; ic = ic->next ) {
9941
9942       DEBUGpic14_emitcode(";ic","");
9943         if ( cln != ic->lineno ) {
9944             if ( options.debug ) {
9945                 _G.debugLine = 1;
9946                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9947                          FileBaseName(ic->filename),ic->lineno,
9948                          ic->level,ic->block);
9949                 _G.debugLine = 0;
9950             }
9951             /*
9952               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9953               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9954               printCLine(ic->filename, ic->lineno));
9955             */
9956             if (!options.noCcodeInAsm) {
9957               addpCode2pBlock(pb,
9958                               newpCodeCSource(ic->lineno, 
9959                                               ic->filename, 
9960                                               printCLine(ic->filename, ic->lineno)));
9961             }
9962
9963             cln = ic->lineno ;
9964         }
9965
9966         // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9967
9968         /* if the result is marked as
9969            spilt and rematerializable or code for
9970            this has already been generated then
9971            do nothing */
9972         if (resultRemat(ic) || ic->generated ) 
9973             continue ;
9974         
9975         /* depending on the operation */
9976         switch (ic->op) {
9977         case '!' :
9978             genNot(ic);
9979             break;
9980             
9981         case '~' :
9982             genCpl(ic);
9983             break;
9984             
9985         case UNARYMINUS:
9986             genUminus (ic);
9987             break;
9988             
9989         case IPUSH:
9990             genIpush (ic);
9991             break;
9992             
9993         case IPOP:
9994             /* IPOP happens only when trying to restore a 
9995                spilt live range, if there is an ifx statement
9996                following this pop then the if statement might
9997                be using some of the registers being popped which
9998                would destory the contents of the register so
9999                we need to check for this condition and handle it */
10000             if (ic->next            && 
10001                 ic->next->op == IFX &&
10002                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10003                 genIfx (ic->next,ic);
10004             else
10005                 genIpop (ic);
10006             break; 
10007             
10008         case CALL:
10009             genCall (ic);
10010             break;
10011             
10012         case PCALL:
10013             genPcall (ic);
10014             break;
10015             
10016         case FUNCTION:
10017             genFunction (ic);
10018             break;
10019             
10020         case ENDFUNCTION:
10021             genEndFunction (ic);
10022             break;
10023             
10024         case RETURN:
10025             genRet (ic);
10026             break;
10027             
10028         case LABEL:
10029             genLabel (ic);
10030             break;
10031             
10032         case GOTO:
10033             genGoto (ic);
10034             break;
10035             
10036         case '+' :
10037             genPlus (ic) ;
10038             break;
10039             
10040         case '-' :
10041             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10042                 genMinus (ic);
10043             break;
10044             
10045         case '*' :
10046             genMult (ic);
10047             break;
10048             
10049         case '/' :
10050             genDiv (ic) ;
10051             break;
10052             
10053         case '%' :
10054             genMod (ic);
10055             break;
10056             
10057         case '>' :
10058             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10059             break;
10060             
10061         case '<' :
10062             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10063             break;
10064             
10065         case LE_OP:
10066         case GE_OP:
10067         case NE_OP:
10068             
10069             /* note these two are xlated by algebraic equivalence
10070                during parsing SDCC.y */
10071             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10072                    "got '>=' or '<=' shouldn't have come here");
10073             break;      
10074             
10075         case EQ_OP:
10076             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10077             break;          
10078             
10079         case AND_OP:
10080             genAndOp (ic);
10081             break;
10082             
10083         case OR_OP:
10084             genOrOp (ic);
10085             break;
10086             
10087         case '^' :
10088             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10089             break;
10090             
10091         case '|' :
10092                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10093             break;
10094             
10095         case BITWISEAND:
10096             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10097             break;
10098             
10099         case INLINEASM:
10100             genInline (ic);
10101             break;
10102             
10103         case RRC:
10104             genRRC (ic);
10105             break;
10106             
10107         case RLC:
10108             genRLC (ic);
10109             break;
10110             
10111         case GETHBIT:
10112             genGetHbit (ic);
10113             break;
10114             
10115         case LEFT_OP:
10116             genLeftShift (ic);
10117             break;
10118             
10119         case RIGHT_OP:
10120             genRightShift (ic);
10121             break;
10122             
10123         case GET_VALUE_AT_ADDRESS:
10124             genPointerGet(ic);
10125             break;
10126             
10127         case '=' :
10128             if (POINTER_SET(ic))
10129                 genPointerSet(ic);
10130             else
10131                 genAssign(ic);
10132             break;
10133             
10134         case IFX:
10135             genIfx (ic,NULL);
10136             break;
10137             
10138         case ADDRESS_OF:
10139             genAddrOf (ic);
10140             break;
10141             
10142         case JUMPTABLE:
10143             genJumpTab (ic);
10144             break;
10145             
10146         case CAST:
10147             genCast (ic);
10148             break;
10149             
10150         case RECEIVE:
10151             genReceive(ic);
10152             break;
10153             
10154         case SEND:
10155             addSet(&_G.sendSet,ic);
10156             break;
10157
10158         default :
10159             ic = ic;
10160         }
10161     }
10162     
10163
10164     /* now we are ready to call the 
10165        peep hole optimizer */
10166     if (!options.nopeep) {
10167       peepHole (&lineHead);
10168     }
10169     /* now do the actual printing */
10170     printLine (lineHead,codeOutFile);
10171
10172 #ifdef PCODE_DEBUG
10173     DFPRINTF((stderr,"printing pBlock\n\n"));
10174     printpBlock(stdout,pb);
10175 #endif
10176
10177     return;
10178 }