Fixed several pointer related bugs in the PIC port
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
41 #else
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
51 #endif
52 #endif
53 #endif
54 #endif
55
56 #include "common.h"
57 #include "SDCCpeeph.h"
58 #include "ralloc.h"
59 #include "pcode.h"
60 #include "gen.h"
61
62
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
66
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
70
71 /* max_key keeps track of the largest label number used in 
72    a function. This is then used to adjust the label offset
73    for the next function.
74 */
75 static int max_key=0;
76 static int GpsuedoStkPtr=0;
77
78 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
82
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
84
85 /* this is the down and dirty file with all kinds of 
86    kludgy & hacky stuff. This is what it is all about
87    CODE GENERATION for a specific MCU . some of the
88    routines may be reusable, will have to see */
89
90 static char *zero = "#0x00";
91 static char *one  = "#0x01";
92 static char *spname = "sp";
93
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
98
99 static char *accUse[] = {"a","b"};
100
101 //static short rbank = -1;
102
103 static struct {
104     short r0Pushed;
105     short r1Pushed;
106     short accInUse;
107     short inLine;
108     short debugLine;
109     short nRegsSaved;
110     set *sendSet;
111 } _G;
112
113 /* Resolved ifx structure. This structure stores information
114    about an iCode ifx that makes it easier to generate code.
115 */
116 typedef struct resolvedIfx {
117   symbol *lbl;     /* pointer to a label */
118   int condition;   /* true or false ifx */
119   int generated;   /* set true when the code associated with the ifx
120                     * is generated */
121 } resolvedIfx;
122
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
127
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
130
131 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
135
136 static  pBlock *pb;
137
138 /*-----------------------------------------------------------------*/
139 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
140 /*                 exponent of 2 is returned, otherwise -1 is      */
141 /*                 returned.                                       */
142 /* note that this is similar to the function `powof2' in SDCCsymt  */
143 /* if(n == 2^y)                                                    */
144 /*   return y;                                                     */
145 /* return -1;                                                      */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
148 {
149   if(num) {
150     if( (num & (num-1)) == 0) {
151       int nshifts = -1;
152       while(num) {
153         num>>=1;
154         nshifts++;
155       }
156       return nshifts;
157     }
158   }
159
160   return -1;
161 }
162
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
164 {
165
166   DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
167                        line_no,
168                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174                        ((result) ? AOP_SIZE(result) : 0));
175
176 }
177
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
179 {
180
181   DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
182                        line_no,
183                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
184                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
186                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
187                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
188                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
189
190 }
191
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
193 {
194     va_list ap;
195     char lb[INITIAL_INLINEASM];  
196     char *lbp = lb;
197
198     if(!debug_verbose)
199       return;
200
201     va_start(ap,fmt);   
202
203     if (inst && *inst) {
204         if (fmt && *fmt)
205             sprintf(lb,"%s\t",inst);
206         else
207             sprintf(lb,"%s",inst);
208         vsprintf(lb+(strlen(lb)),fmt,ap);
209     }  else
210         vsprintf(lb,fmt,ap);
211
212     while (isspace(*lbp)) lbp++;
213
214     if (lbp && *lbp) 
215         lineCurr = (lineCurr ?
216                     connectLine(lineCurr,newLineNode(lb)) :
217                     (lineHead = newLineNode(lb)));
218     lineCurr->isInline = _G.inLine;
219     lineCurr->isDebug  = _G.debugLine;
220
221     addpCode2pBlock(pb,newpCodeCharP(lb));
222
223     va_end(ap);
224 }
225
226
227 void emitpLabel(int key)
228 {
229   addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
230 }
231
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
233 {
234
235   if(pcop)
236     addpCode2pBlock(pb,newpCode(poc,pcop));
237   else
238     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
239 }
240
241 void emitpcodeNULLop(PIC_OPCODE poc)
242 {
243
244   addpCode2pBlock(pb,newpCode(poc,NULL));
245
246 }
247
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple    */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
252 {
253     va_list ap;
254     char lb[INITIAL_INLINEASM];  
255     char *lbp = lb;
256
257     va_start(ap,fmt);   
258
259     if (inst && *inst) {
260         if (fmt && *fmt)
261             sprintf(lb,"%s\t",inst);
262         else
263             sprintf(lb,"%s",inst);
264         vsprintf(lb+(strlen(lb)),fmt,ap);
265     }  else
266         vsprintf(lb,fmt,ap);
267
268     while (isspace(*lbp)) lbp++;
269
270     if (lbp && *lbp) 
271         lineCurr = (lineCurr ?
272                     connectLine(lineCurr,newLineNode(lb)) :
273                     (lineHead = newLineNode(lb)));
274     lineCurr->isInline = _G.inLine;
275     lineCurr->isDebug  = _G.debugLine;
276
277     if(debug_verbose)
278       addpCode2pBlock(pb,newpCodeCharP(lb));
279
280     va_end(ap);
281 }
282
283
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
288 {
289     bool r0iu = FALSE , r1iu = FALSE;
290     bool r0ou = FALSE , r1ou = FALSE;
291
292     /* the logic: if r0 & r1 used in the instruction
293     then we are in trouble otherwise */
294
295     /* first check if r0 & r1 are used by this
296     instruction, in which case we are in trouble */
297     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
299     {
300         goto endOfWorld;      
301     }
302
303     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
305
306     /* if no usage of r0 then return it */
307     if (!r0iu && !r0ou) {
308         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309         (*aopp)->type = AOP_R0;
310         
311         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
312     }
313
314     /* if no usage of r1 then return it */
315     if (!r1iu && !r1ou) {
316         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317         (*aopp)->type = AOP_R1;
318
319         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
320     }    
321
322     /* now we know they both have usage */
323     /* if r0 not used in this instruction */
324     if (!r0iu) {
325         /* push it if not already pushed */
326         if (!_G.r0Pushed) {
327           //pic14_emitcode ("push","%s",
328           //          pic14_regWithIdx(R0_IDX)->dname);
329             _G.r0Pushed++ ;
330         }
331         
332         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333         (*aopp)->type = AOP_R0;
334
335         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
336     }
337
338     /* if r1 not used then */
339
340     if (!r1iu) {
341         /* push it if not already pushed */
342         if (!_G.r1Pushed) {
343           //pic14_emitcode ("push","%s",
344           //          pic14_regWithIdx(R1_IDX)->dname);
345             _G.r1Pushed++ ;
346         }
347         
348         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349         (*aopp)->type = AOP_R1;
350         return pic14_regWithIdx(R1_IDX);
351     }
352
353 endOfWorld :
354     /* I said end of world but not quite end of world yet */
355     /* if this is a result then we can push it on the stack*/
356     if (result) {
357         (*aopp)->type = AOP_STK;    
358         return NULL;
359     }
360
361     /* other wise this is true end of the world */
362     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363            "getFreePtr should never reach here");
364     exit(0);
365 }
366
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp                                  */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
371 {
372     asmop *aop;
373
374     aop = Safe_calloc(1,sizeof(asmop));
375     aop->type = type;
376     return aop;
377 }
378
379 static void genSetDPTR(int n)
380 {
381     if (!n)
382     {
383         pic14_emitcode(";", "Select standard DPTR");
384         pic14_emitcode("mov", "dps, #0x00");
385     }
386     else
387     {
388         pic14_emitcode(";", "Select alternate DPTR");
389         pic14_emitcode("mov", "dps, #0x01");
390     }
391 }
392
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for  */
395 /*              generating code                                    */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
398 {
399   if(!resIfx) 
400     return;
401
402   DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
403
404   resIfx->condition = 1;    /* assume that the ifx is true */
405   resIfx->generated = 0;    /* indicate that the ifx has not been used */
406
407   if(!ifx) {
408     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
409     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410                         __FUNCTION__,__LINE__,resIfx->lbl->key);
411   } else {
412     if(IC_TRUE(ifx)) {
413       resIfx->lbl = IC_TRUE(ifx);
414     } else {
415       resIfx->lbl = IC_FALSE(ifx);
416       resIfx->condition = 0;
417     }
418     if(IC_TRUE(ifx)) 
419       DEBUGpic14_emitcode("; ***","ifx true is non-null");
420     if(IC_FALSE(ifx)) 
421       DEBUGpic14_emitcode("; ***","ifx false is non-null");
422   }
423
424   DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
425
426 }
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type               */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
431 {
432
433     return PTR_TYPE(SPEC_OCLS(etype));
434
435 }
436
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol                                   */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
441 {
442     asmop *aop;
443     memmap *space= SPEC_OCLS(sym->etype);
444
445     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446     /* if already has one */
447     if (sym->aop)
448         return sym->aop;
449
450     /* assign depending on the storage class */
451     /* if it is on the stack or indirectly addressable */
452     /* space we need to assign either r0 or r1 to it   */    
453     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454         sym->aop = aop = newAsmop(0);
455         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456         aop->size = getSize(sym->type);
457
458         /* now assign the address of the variable to 
459         the pointer register */
460         if (aop->type != AOP_STK) {
461
462             if (sym->onStack) {
463                     if ( _G.accInUse )
464                         pic14_emitcode("push","acc");
465
466                     pic14_emitcode("mov","a,_bp");
467                     pic14_emitcode("add","a,#0x%02x",
468                              ((sym->stack < 0) ?
469                               ((char)(sym->stack - _G.nRegsSaved )) :
470                               ((char)sym->stack)) & 0xff);
471                     pic14_emitcode("mov","%s,a",
472                              aop->aopu.aop_ptr->name);
473
474                     if ( _G.accInUse )
475                         pic14_emitcode("pop","acc");
476             } else
477                 pic14_emitcode("mov","%s,#%s",
478                          aop->aopu.aop_ptr->name,
479                          sym->rname);
480             aop->paged = space->paged;
481         } else
482             aop->aopu.aop_stk = sym->stack;
483         return aop;
484     }
485     
486     if (sym->onStack && options.stack10bit)
487     {
488         /* It's on the 10 bit stack, which is located in
489          * far data space.
490          */
491          
492       //DEBUGpic14_emitcode(";","%d",__LINE__);
493
494         if ( _G.accInUse )
495                 pic14_emitcode("push","acc");
496
497         pic14_emitcode("mov","a,_bp");
498         pic14_emitcode("add","a,#0x%02x",
499                  ((sym->stack < 0) ?
500                    ((char)(sym->stack - _G.nRegsSaved )) :
501                    ((char)sym->stack)) & 0xff);
502         
503         genSetDPTR(1);
504         pic14_emitcode ("mov","dpx1,#0x40");
505         pic14_emitcode ("mov","dph1,#0x00");
506         pic14_emitcode ("mov","dpl1, a");
507         genSetDPTR(0);
508         
509         if ( _G.accInUse )
510             pic14_emitcode("pop","acc");
511             
512         sym->aop = aop = newAsmop(AOP_DPTR2);
513         aop->size = getSize(sym->type); 
514         return aop;
515     }
516
517     //DEBUGpic14_emitcode(";","%d",__LINE__);
518     /* if in bit space */
519     if (IN_BITSPACE(space)) {
520         sym->aop = aop = newAsmop (AOP_CRY);
521         aop->aopu.aop_dir = sym->rname ;
522         aop->size = getSize(sym->type);
523         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524         return aop;
525     }
526     /* if it is in direct space */
527     if (IN_DIRSPACE(space)) {
528         sym->aop = aop = newAsmop (AOP_DIR);
529         aop->aopu.aop_dir = sym->rname ;
530         aop->size = getSize(sym->type);
531         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
532         return aop;
533     }
534
535     /* special case for a function */
536     if (IS_FUNC(sym->type)) {   
537         sym->aop = aop = newAsmop(AOP_IMMD);    
538         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540         strcpy(aop->aopu.aop_immd,sym->rname);
541         aop->size = FPTRSIZE; 
542         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
543         return aop;
544     }
545
546
547     /* only remaining is far space */
548     /* in which case DPTR gets the address */
549     sym->aop = aop = newAsmop(AOP_PCODE);
550
551     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
552     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
553     PCOI(aop->aopu.pcop)->index = 0;
554
555     DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
556                         sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
557
558     allocDirReg (IC_LEFT(ic));
559
560     aop->size = FPTRSIZE; 
561 /*
562     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
563     sym->aop = aop = newAsmop(AOP_DPTR);
564     pic14_emitcode ("mov","dptr,#%s", sym->rname);
565     aop->size = getSize(sym->type);
566
567     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
568 */
569
570     /* if it is in code space */
571     if (IN_CODESPACE(space))
572         aop->code = 1;
573
574     return aop;     
575 }
576
577 /*-----------------------------------------------------------------*/
578 /* aopForRemat - rematerialzes an object                           */
579 /*-----------------------------------------------------------------*/
580 static asmop *aopForRemat (operand *op) // x symbol *sym)
581 {
582   symbol *sym = OP_SYMBOL(op);
583   iCode *ic = NULL;
584   asmop *aop = newAsmop(AOP_PCODE);
585   int val = 0;
586   int offset = 0;
587
588   ic = sym->rematiCode;
589
590     DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
591
592     for (;;) {
593       if (ic->op == '+') {
594         val += (int) operandLitValue(IC_RIGHT(ic));
595       } else if (ic->op == '-') {
596         val -= (int) operandLitValue(IC_RIGHT(ic));
597       } else
598             break;
599         
600         ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
601     }
602
603     offset = OP_SYMBOL(IC_LEFT(ic))->offset;
604     aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
605     PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
606     PCOI(aop->aopu.pcop)->index = val;
607
608     DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
609                         OP_SYMBOL(IC_LEFT(ic))->rname,
610                         val, IS_PTR_CONST(operandType(op)));
611
612     //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
613
614     allocDirReg (IC_LEFT(ic));
615
616     return aop;        
617 }
618
619 int aopIdx (asmop *aop, int offset)
620 {
621   if(!aop)
622     return -1;
623
624   if(aop->type !=  AOP_REG)
625     return -2;
626         
627   return aop->aopu.aop_reg[offset]->rIdx;
628
629 }
630 /*-----------------------------------------------------------------*/
631 /* regsInCommon - two operands have some registers in common       */
632 /*-----------------------------------------------------------------*/
633 static bool regsInCommon (operand *op1, operand *op2)
634 {
635     symbol *sym1, *sym2;
636     int i;
637
638     /* if they have registers in common */
639     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
640         return FALSE ;
641
642     sym1 = OP_SYMBOL(op1);
643     sym2 = OP_SYMBOL(op2);
644
645     if (sym1->nRegs == 0 || sym2->nRegs == 0)
646         return FALSE ;
647
648     for (i = 0 ; i < sym1->nRegs ; i++) {
649         int j;
650         if (!sym1->regs[i])
651             continue ;
652
653         for (j = 0 ; j < sym2->nRegs ;j++ ) {
654             if (!sym2->regs[j])
655                 continue ;
656
657             if (sym2->regs[j] == sym1->regs[i])
658                 return TRUE ;
659         }
660     }
661
662     return FALSE ;
663 }
664
665 /*-----------------------------------------------------------------*/
666 /* operandsEqu - equivalent                                        */
667 /*-----------------------------------------------------------------*/
668 static bool operandsEqu ( operand *op1, operand *op2)
669 {
670     symbol *sym1, *sym2;
671
672     /* if they not symbols */
673     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
674         return FALSE;
675
676     sym1 = OP_SYMBOL(op1);
677     sym2 = OP_SYMBOL(op2);
678
679     /* if both are itemps & one is spilt
680        and the other is not then false */
681     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
682         sym1->isspilt != sym2->isspilt )
683         return FALSE ;
684
685     /* if they are the same */
686     if (sym1 == sym2)
687         return TRUE ;
688
689     if (strcmp(sym1->rname,sym2->rname) == 0)
690         return TRUE;
691
692
693     /* if left is a tmp & right is not */
694     if (IS_ITEMP(op1)  && 
695         !IS_ITEMP(op2) &&
696         sym1->isspilt  &&
697         (sym1->usl.spillLoc == sym2))
698         return TRUE;
699
700     if (IS_ITEMP(op2)  && 
701         !IS_ITEMP(op1) &&
702         sym2->isspilt  &&
703         sym1->level > 0 &&
704         (sym2->usl.spillLoc == sym1))
705         return TRUE ;
706
707     return FALSE ;
708 }
709
710 /*-----------------------------------------------------------------*/
711 /* pic14_sameRegs - two asmops have the same registers                   */
712 /*-----------------------------------------------------------------*/
713 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
714 {
715     int i;
716
717     if (aop1 == aop2)
718         return TRUE ;
719
720     if (aop1->type != AOP_REG ||
721         aop2->type != AOP_REG )
722         return FALSE ;
723
724     if (aop1->size != aop2->size )
725         return FALSE ;
726
727     for (i = 0 ; i < aop1->size ; i++ )
728         if (aop1->aopu.aop_reg[i] !=
729             aop2->aopu.aop_reg[i] )
730             return FALSE ;
731
732     return TRUE ;
733 }
734
735 /*-----------------------------------------------------------------*/
736 /* aopOp - allocates an asmop for an operand  :                    */
737 /*-----------------------------------------------------------------*/
738 void aopOp (operand *op, iCode *ic, bool result)
739 {
740     asmop *aop;
741     symbol *sym;
742     int i;
743
744     if (!op)
745         return ;
746
747     //    DEBUGpic14_emitcode(";","%d",__LINE__);
748     /* if this a literal */
749     if (IS_OP_LITERAL(op)) {
750         op->aop = aop = newAsmop(AOP_LIT);
751         aop->aopu.aop_lit = op->operand.valOperand;
752         aop->size = getSize(operandType(op));
753         return;
754     }
755
756     {
757       sym_link *type = operandType(op);
758       if(IS_PTR_CONST(type))
759         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
760     }
761
762     /* if already has a asmop then continue */
763     if (op->aop)
764         return ;
765
766     /* if the underlying symbol has a aop */
767     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
768       DEBUGpic14_emitcode(";","%d",__LINE__);
769         op->aop = OP_SYMBOL(op)->aop;
770         return;
771     }
772
773     /* if this is a true symbol */
774     if (IS_TRUE_SYMOP(op)) {    
775       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
776       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
777       return ;
778     }
779
780     /* this is a temporary : this has
781     only four choices :
782     a) register
783     b) spillocation
784     c) rematerialize 
785     d) conditional   
786     e) can be a return use only */
787
788     sym = OP_SYMBOL(op);
789
790
791     /* if the type is a conditional */
792     if (sym->regType == REG_CND) {
793         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
794         aop->size = 0;
795         return;
796     }
797
798     /* if it is spilt then two situations
799     a) is rematerialize 
800     b) has a spill location */
801     if (sym->isspilt || sym->nRegs == 0) {
802
803       DEBUGpic14_emitcode(";","%d",__LINE__);
804         /* rematerialize it NOW */
805         if (sym->remat) {
806
807             sym->aop = op->aop = aop =
808                                       aopForRemat (op);
809             aop->size = getSize(sym->type);
810             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
811             return;
812         }
813
814         if (sym->accuse) {
815             int i;
816             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
817             aop->size = getSize(sym->type);
818             for ( i = 0 ; i < 2 ; i++ )
819                 aop->aopu.aop_str[i] = accUse[i];
820             DEBUGpic14_emitcode(";","%d",__LINE__);
821             return;  
822         }
823
824         if (sym->ruonly ) {
825             unsigned i;
826             aop = op->aop = sym->aop = newAsmop(AOP_STR);
827             aop->size = getSize(sym->type);
828             for ( i = 0 ; i < fReturnSizePic ; i++ )
829               aop->aopu.aop_str[i] = fReturn[i];
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         // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
844         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845         aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846         //allocDirReg (IC_LEFT(ic));
847         aop->size = getSize(sym->type);
848
849         return;
850     }
851
852     {
853       sym_link *type = operandType(op);
854       if(IS_PTR_CONST(type)) 
855         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
856     }
857
858     /* must be in a register */
859     sym->aop = op->aop = aop = newAsmop(AOP_REG);
860     aop->size = sym->nRegs;
861     for ( i = 0 ; i < sym->nRegs ;i++)
862         aop->aopu.aop_reg[i] = sym->regs[i];
863 }
864
865 /*-----------------------------------------------------------------*/
866 /* freeAsmop - free up the asmop given to an operand               */
867 /*----------------------------------------------------------------*/
868 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
869 {   
870     asmop *aop ;
871
872     if (!op)
873         aop = aaop;
874     else 
875         aop = op->aop;
876
877     if (!aop)
878         return ;
879
880     if (aop->freed)
881         goto dealloc; 
882
883     aop->freed = 1;
884
885     /* depending on the asmop type only three cases need work AOP_RO
886        , AOP_R1 && AOP_STK */
887 #if 0
888     switch (aop->type) {
889         case AOP_R0 :
890             if (_G.r0Pushed ) {
891                 if (pop) {
892                     pic14_emitcode ("pop","ar0");     
893                     _G.r0Pushed--;
894                 }
895             }
896             bitVectUnSetBit(ic->rUsed,R0_IDX);
897             break;
898
899         case AOP_R1 :
900             if (_G.r1Pushed ) {
901                 if (pop) {
902                     pic14_emitcode ("pop","ar1");
903                     _G.r1Pushed--;
904                 }
905             }
906             bitVectUnSetBit(ic->rUsed,R1_IDX);          
907             break;
908
909         case AOP_STK :
910         {
911             int sz = aop->size;    
912             int stk = aop->aopu.aop_stk + aop->size;
913             bitVectUnSetBit(ic->rUsed,R0_IDX);
914             bitVectUnSetBit(ic->rUsed,R1_IDX);          
915
916             getFreePtr(ic,&aop,FALSE);
917             
918             if (options.stack10bit)
919             {
920                 /* I'm not sure what to do here yet... */
921                 /* #STUB */
922                 fprintf(stderr, 
923                         "*** Warning: probably generating bad code for "
924                         "10 bit stack mode.\n");
925             }
926             
927             if (stk) {
928                 pic14_emitcode ("mov","a,_bp");
929                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
930                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
931             } else {
932                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
933             }
934
935             while (sz--) {
936                 pic14_emitcode("pop","acc");
937                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
938                 if (!sz) break;
939                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
940             }
941             op->aop = aop;
942             freeAsmop(op,NULL,ic,TRUE);
943             if (_G.r0Pushed) {
944                 pic14_emitcode("pop","ar0");
945                 _G.r0Pushed--;
946             }
947
948             if (_G.r1Pushed) {
949                 pic14_emitcode("pop","ar1");
950                 _G.r1Pushed--;
951             }       
952         }
953     }
954 #endif
955
956 dealloc:
957     /* all other cases just dealloc */
958     if (op ) {
959         op->aop = NULL;
960         if (IS_SYMOP(op)) {
961             OP_SYMBOL(op)->aop = NULL;    
962             /* if the symbol has a spill */
963             if (SPIL_LOC(op))
964                 SPIL_LOC(op)->aop = NULL;
965         }
966     }
967 }
968
969 /*-----------------------------------------------------------------*/
970 /* aopGet - for fetching value of the aop                          */
971 /*-----------------------------------------------------------------*/
972 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
973 {
974     char *s = buffer ;
975     char *rs;
976
977     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
978     /* offset is greater than
979     size then zero */
980     if (offset > (aop->size - 1) &&
981         aop->type != AOP_LIT)
982         return zero;
983
984     /* depending on type */
985     switch (aop->type) {
986         
987     case AOP_R0:
988     case AOP_R1:
989         DEBUGpic14_emitcode(";","%d",__LINE__);
990         /* if we need to increment it */       
991         while (offset > aop->coff) {        
992             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
993             aop->coff++;
994         }
995         
996         while (offset < aop->coff) {
997             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
998             aop->coff--;
999         }
1000         
1001         aop->coff = offset ;
1002         if (aop->paged) {
1003             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1004             return (dname ? "acc" : "a");
1005         }       
1006         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1007         rs = Safe_calloc(1,strlen(s)+1);
1008         strcpy(rs,s);   
1009         return rs;
1010         
1011     case AOP_DPTR:
1012     case AOP_DPTR2:
1013         DEBUGpic14_emitcode(";","%d",__LINE__);
1014     if (aop->type == AOP_DPTR2)
1015     {
1016         genSetDPTR(1);
1017     }
1018     
1019         while (offset > aop->coff) {
1020             pic14_emitcode ("inc","dptr");
1021             aop->coff++;
1022         }
1023         
1024         while (offset < aop->coff) {        
1025             pic14_emitcode("lcall","__decdptr");
1026             aop->coff--;
1027         }
1028         
1029         aop->coff = offset;
1030         if (aop->code) {
1031             pic14_emitcode("clr","a");
1032             pic14_emitcode("movc","a,@a+dptr");
1033         }
1034     else {
1035             pic14_emitcode("movx","a,@dptr");
1036     }
1037             
1038     if (aop->type == AOP_DPTR2)
1039     {
1040         genSetDPTR(0);
1041     }
1042             
1043     return (dname ? "acc" : "a");
1044         
1045         
1046     case AOP_IMMD:
1047         if (bit16) 
1048             sprintf (s,"%s",aop->aopu.aop_immd);
1049         else
1050             if (offset) 
1051                 sprintf(s,"(%s >> %d)",
1052                         aop->aopu.aop_immd,
1053                         offset*8);
1054             else
1055                 sprintf(s,"%s",
1056                         aop->aopu.aop_immd);
1057         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1058         rs = Safe_calloc(1,strlen(s)+1);
1059         strcpy(rs,s);   
1060         return rs;
1061         
1062     case AOP_DIR:
1063       if (offset) {
1064         sprintf(s,"(%s + %d)",
1065                 aop->aopu.aop_dir,
1066                 offset);
1067         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1068       } else
1069             sprintf(s,"%s",aop->aopu.aop_dir);
1070         rs = Safe_calloc(1,strlen(s)+1);
1071         strcpy(rs,s);   
1072         return rs;
1073         
1074     case AOP_REG:
1075       //if (dname) 
1076       //    return aop->aopu.aop_reg[offset]->dname;
1077       //else
1078             return aop->aopu.aop_reg[offset]->name;
1079         
1080     case AOP_CRY:
1081       //pic14_emitcode(";","%d",__LINE__);
1082       return aop->aopu.aop_dir;
1083         
1084     case AOP_ACC:
1085         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1086         return "AOP_accumulator_bug";
1087
1088     case AOP_LIT:
1089         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1090         rs = Safe_calloc(1,strlen(s)+1);
1091         strcpy(rs,s);   
1092         return rs;
1093         
1094     case AOP_STR:
1095         DEBUGpic14_emitcode(";","%d",__LINE__);
1096         aop->coff = offset ;
1097         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1098             dname)
1099             return "acc";
1100         
1101         return aop->aopu.aop_str[offset];
1102         
1103     case AOP_PCODE:
1104       {
1105         pCodeOp *pcop = aop->aopu.pcop;
1106         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1107         if(pcop->name) {
1108           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1109           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1110           sprintf(s,"%s", pcop->name);
1111         } else
1112           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1113
1114       }
1115       rs = Safe_calloc(1,strlen(s)+1);
1116       strcpy(rs,s);   
1117       return rs;
1118
1119     }
1120
1121     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1122            "aopget got unsupported aop->type");
1123     exit(0);
1124 }
1125
1126
1127 /*-----------------------------------------------------------------*/
1128 /* popGetTempReg - create a new temporary pCodeOp                  */
1129 /*-----------------------------------------------------------------*/
1130 pCodeOp *popGetTempReg(void)
1131 {
1132
1133   pCodeOp *pcop;
1134
1135   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1136   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1137     PCOR(pcop)->r->wasUsed=1;
1138     PCOR(pcop)->r->isFree=0;
1139   }
1140
1141   return pcop;
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* popGetTempReg - create a new temporary pCodeOp                  */
1146 /*-----------------------------------------------------------------*/
1147 void popReleaseTempReg(pCodeOp *pcop)
1148 {
1149
1150   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1151     PCOR(pcop)->r->isFree = 1;
1152
1153 }
1154 /*-----------------------------------------------------------------*/
1155 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1156 /*-----------------------------------------------------------------*/
1157 pCodeOp *popGetLabel(unsigned int key)
1158 {
1159
1160   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1161
1162   if(key>max_key)
1163     max_key = key;
1164
1165   return newpCodeOpLabel(NULL,key+100+labelOffset);
1166 }
1167
1168 /*-----------------------------------------------------------------*/
1169 /* popCopyReg - copy a pcode operator                              */
1170 /*-----------------------------------------------------------------*/
1171 pCodeOp *popCopyReg(pCodeOpReg *pc)
1172 {
1173   pCodeOpReg *pcor;
1174
1175   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1176   pcor->pcop.type = pc->pcop.type;
1177   if(pc->pcop.name) {
1178     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1179       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1180   } else
1181     pcor->pcop.name = NULL;
1182
1183   pcor->r = pc->r;
1184   pcor->rIdx = pc->rIdx;
1185   pcor->r->wasUsed=1;
1186
1187   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1188
1189   return PCOP(pcor);
1190 }
1191 /*-----------------------------------------------------------------*/
1192 /* popGet - asm operator to pcode operator conversion              */
1193 /*-----------------------------------------------------------------*/
1194 pCodeOp *popGetLit(unsigned int lit)
1195 {
1196
1197   return newpCodeOpLit(lit);
1198 }
1199
1200
1201 /*-----------------------------------------------------------------*/
1202 /* popGetImmd - asm operator to pcode immediate conversion         */
1203 /*-----------------------------------------------------------------*/
1204 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1205 {
1206
1207   return newpCodeOpImmd(name, offset,index, 0);
1208 }
1209
1210
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion              */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetWithString(char *str)
1215 {
1216   pCodeOp *pcop;
1217
1218
1219   if(!str) {
1220     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1221     exit (1);
1222   }
1223
1224   pcop = newpCodeOp(str,PO_STR);
1225
1226   return pcop;
1227 }
1228
1229 pCodeOp *popRegFromString(char *str)
1230 {
1231
1232   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1233   pcop->type = PO_DIR;
1234
1235   DEBUGpic14_emitcode(";","%d",__LINE__);
1236   pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1237
1238   return pcop;
1239 }
1240
1241 pCodeOp *popRegFromIdx(int rIdx)
1242 {
1243   pCodeOp *pcop;
1244
1245   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1246                        __FUNCTION__,__LINE__,rIdx);
1247
1248   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1249
1250   PCOR(pcop)->rIdx = rIdx;
1251   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1252   PCOR(pcop)->r->isFree = 0;
1253   PCOR(pcop)->r->wasUsed = 1;
1254
1255   pcop->type = PCOR(pcop)->r->pc_type;
1256
1257
1258   return pcop;
1259 }
1260 /*-----------------------------------------------------------------*/
1261 /* popGet - asm operator to pcode operator conversion              */
1262 /*-----------------------------------------------------------------*/
1263 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1264 {
1265   //char *s = buffer ;
1266     //char *rs;
1267
1268     pCodeOp *pcop;
1269
1270     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1271     /* offset is greater than
1272     size then zero */
1273
1274     if (offset > (aop->size - 1) &&
1275         aop->type != AOP_LIT)
1276       return NULL;  //zero;
1277
1278     /* depending on type */
1279     switch (aop->type) {
1280         
1281     case AOP_R0:
1282     case AOP_R1:
1283     case AOP_DPTR:
1284     case AOP_DPTR2:
1285     case AOP_ACC:
1286         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1287         return NULL;
1288         
1289     case AOP_IMMD:
1290       DEBUGpic14_emitcode(";","%d",__LINE__);
1291       return popGetImmd(aop->aopu.aop_immd,offset,0);
1292
1293     case AOP_DIR:
1294         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295         pcop->type = PO_DIR;
1296
1297         /*
1298         if (offset)
1299             sprintf(s,"(%s + %d)",
1300                     aop->aopu.aop_dir,
1301                     offset);
1302         else
1303             sprintf(s,"%s",aop->aopu.aop_dir);
1304         pcop->name = Safe_calloc(1,strlen(s)+1);
1305         strcpy(pcop->name,s);   
1306         */
1307         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1308         strcpy(pcop->name,aop->aopu.aop_dir);   
1309         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1310         if(PCOR(pcop)->r == NULL) {
1311           fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1312           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1313         } 
1314
1315       DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1316         PCOR(pcop)->instance = offset;
1317
1318         return pcop;
1319         
1320     case AOP_REG:
1321       {
1322         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1323
1324         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1325         PCOR(pcop)->rIdx = rIdx;
1326         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1327         PCOR(pcop)->instance = offset;
1328         pcop->type = PCOR(pcop)->r->pc_type;
1329         //rs = aop->aopu.aop_reg[offset]->name;
1330         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1331         return pcop;
1332       }
1333
1334     case AOP_CRY:
1335       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1336       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1337       if(PCOR(pcop)->r == NULL)
1338         fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1339       return pcop;
1340         
1341     case AOP_LIT:
1342       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1343
1344     case AOP_STR:
1345       DEBUGpic14_emitcode(";","%d",__LINE__);
1346       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1347       /*
1348       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1349       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1350       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1351       pcop->type = PCOR(pcop)->r->pc_type;
1352       pcop->name = PCOR(pcop)->r->name;
1353
1354       return pcop;
1355       */
1356
1357     case AOP_PCODE:
1358       DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1359       pcop = pCodeOpCopy(aop->aopu.pcop);
1360       PCOI(pcop)->offset = offset;
1361       return pcop;
1362     }
1363
1364     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1365            "popGet got unsupported aop->type");
1366     exit(0);
1367 }
1368 /*-----------------------------------------------------------------*/
1369 /* aopPut - puts a string for a aop                                */
1370 /*-----------------------------------------------------------------*/
1371 void aopPut (asmop *aop, char *s, int offset)
1372 {
1373     char *d = buffer ;
1374     symbol *lbl ;
1375
1376     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1377
1378     if (aop->size && offset > ( aop->size - 1)) {
1379         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1380                "aopPut got offset > aop->size");
1381         exit(0);
1382     }
1383
1384     /* will assign value to value */
1385     /* depending on where it is ofcourse */
1386     switch (aop->type) {
1387     case AOP_DIR:
1388       if (offset) {
1389         sprintf(d,"(%s + %d)",
1390                 aop->aopu.aop_dir,offset);
1391         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1392
1393       } else
1394             sprintf(d,"%s",aop->aopu.aop_dir);
1395         
1396         if (strcmp(d,s)) {
1397           DEBUGpic14_emitcode(";","%d",__LINE__);
1398           if(strcmp(s,"W"))
1399             pic14_emitcode("movf","%s,w",s);
1400           pic14_emitcode("movwf","%s",d);
1401
1402           if(strcmp(s,"W")) {
1403             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1404             if(offset >= aop->size) {
1405               emitpcode(POC_CLRF,popGet(aop,offset));
1406               break;
1407             } else
1408               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1409           }
1410
1411           emitpcode(POC_MOVWF,popGet(aop,offset));
1412
1413
1414         }
1415         break;
1416         
1417     case AOP_REG:
1418       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1419         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1420           /*
1421             if (*s == '@'           ||
1422                 strcmp(s,"r0") == 0 ||
1423                 strcmp(s,"r1") == 0 ||
1424                 strcmp(s,"r2") == 0 ||
1425                 strcmp(s,"r3") == 0 ||
1426                 strcmp(s,"r4") == 0 ||
1427                 strcmp(s,"r5") == 0 ||
1428                 strcmp(s,"r6") == 0 || 
1429                 strcmp(s,"r7") == 0 )
1430                 pic14_emitcode("mov","%s,%s  ; %d",
1431                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1432             else
1433           */
1434
1435           if(strcmp(s,"W"))
1436             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1437
1438           pic14_emitcode("movwf","%s",
1439                    aop->aopu.aop_reg[offset]->name);
1440
1441           if(strcmp(s,"W")) {
1442             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1443             pcop->type = PO_GPR_REGISTER;
1444
1445             PCOR(pcop)->rIdx = -1;
1446             PCOR(pcop)->r = NULL;
1447
1448             DEBUGpic14_emitcode(";","%d",__LINE__);
1449             pcop->name = Safe_strdup(s);
1450             emitpcode(POC_MOVFW,pcop);
1451           }
1452           emitpcode(POC_MOVWF,popGet(aop,offset));
1453
1454         }
1455         break;
1456         
1457     case AOP_DPTR:
1458     case AOP_DPTR2:
1459     
1460     if (aop->type == AOP_DPTR2)
1461     {
1462         genSetDPTR(1);
1463     }
1464     
1465         if (aop->code) {
1466             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1467                    "aopPut writting to code space");
1468             exit(0);
1469         }
1470         
1471         while (offset > aop->coff) {
1472             aop->coff++;
1473             pic14_emitcode ("inc","dptr");
1474         }
1475         
1476         while (offset < aop->coff) {
1477             aop->coff-- ;
1478             pic14_emitcode("lcall","__decdptr");
1479         }
1480         
1481         aop->coff = offset;
1482         
1483         /* if not in accumulater */
1484         MOVA(s);        
1485         
1486         pic14_emitcode ("movx","@dptr,a");
1487         
1488     if (aop->type == AOP_DPTR2)
1489     {
1490         genSetDPTR(0);
1491     }
1492         break;
1493         
1494     case AOP_R0:
1495     case AOP_R1:
1496         while (offset > aop->coff) {
1497             aop->coff++;
1498             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1499         }
1500         while (offset < aop->coff) {
1501             aop->coff-- ;
1502             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1503         }
1504         aop->coff = offset;
1505         
1506         if (aop->paged) {
1507             MOVA(s);           
1508             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1509             
1510         } else
1511             if (*s == '@') {
1512                 MOVA(s);
1513                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1514             } else
1515                 if (strcmp(s,"r0") == 0 ||
1516                     strcmp(s,"r1") == 0 ||
1517                     strcmp(s,"r2") == 0 ||
1518                     strcmp(s,"r3") == 0 ||
1519                     strcmp(s,"r4") == 0 ||
1520                     strcmp(s,"r5") == 0 ||
1521                     strcmp(s,"r6") == 0 || 
1522                     strcmp(s,"r7") == 0 ) {
1523                     char buffer[10];
1524                     sprintf(buffer,"a%s",s);
1525                     pic14_emitcode("mov","@%s,%s",
1526                              aop->aopu.aop_ptr->name,buffer);
1527                 } else
1528                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1529         
1530         break;
1531         
1532     case AOP_STK:
1533         if (strcmp(s,"a") == 0)
1534             pic14_emitcode("push","acc");
1535         else
1536             pic14_emitcode("push","%s",s);
1537         
1538         break;
1539         
1540     case AOP_CRY:
1541         /* if bit variable */
1542         if (!aop->aopu.aop_dir) {
1543             pic14_emitcode("clr","a");
1544             pic14_emitcode("rlc","a");
1545         } else {
1546             if (s == zero) 
1547                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1548             else
1549                 if (s == one)
1550                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1551                 else
1552                     if (!strcmp(s,"c"))
1553                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1554                     else {
1555                         lbl = newiTempLabel(NULL);
1556                         
1557                         if (strcmp(s,"a")) {
1558                             MOVA(s);
1559                         }
1560                         pic14_emitcode("clr","c");
1561                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1562                         pic14_emitcode("cpl","c");
1563                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1564                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1565                     }
1566         }
1567         break;
1568         
1569     case AOP_STR:
1570         aop->coff = offset;
1571         if (strcmp(aop->aopu.aop_str[offset],s))
1572             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1573         break;
1574         
1575     case AOP_ACC:
1576         aop->coff = offset;
1577         if (!offset && (strcmp(s,"acc") == 0))
1578             break;
1579         
1580         if (strcmp(aop->aopu.aop_str[offset],s))
1581             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1582         break;
1583
1584     default :
1585         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1586                "aopPut got unsupported aop->type");
1587         exit(0);    
1588     }    
1589
1590 }
1591
1592 /*-----------------------------------------------------------------*/
1593 /* reAdjustPreg - points a register back to where it should        */
1594 /*-----------------------------------------------------------------*/
1595 static void reAdjustPreg (asmop *aop)
1596 {
1597     int size ;
1598
1599     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1600     aop->coff = 0;
1601     if ((size = aop->size) <= 1)
1602         return ;
1603     size-- ;
1604     switch (aop->type) {
1605         case AOP_R0 :
1606         case AOP_R1 :
1607             while (size--)
1608                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1609             break;          
1610         case AOP_DPTR :
1611         case AOP_DPTR2:
1612             if (aop->type == AOP_DPTR2)
1613             {
1614                 genSetDPTR(1);
1615             } 
1616             while (size--)
1617             {
1618                 pic14_emitcode("lcall","__decdptr");
1619             }
1620                 
1621             if (aop->type == AOP_DPTR2)
1622             {
1623                 genSetDPTR(0);
1624             }                
1625             break;  
1626
1627     }   
1628
1629 }
1630
1631 /*-----------------------------------------------------------------*/
1632 /* genNotFloat - generates not for float operations              */
1633 /*-----------------------------------------------------------------*/
1634 static void genNotFloat (operand *op, operand *res)
1635 {
1636     int size, offset;
1637     char *l;
1638     symbol *tlbl ;
1639
1640     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1641     /* we will put 127 in the first byte of 
1642     the result */
1643     aopPut(AOP(res),"#127",0);
1644     size = AOP_SIZE(op) - 1;
1645     offset = 1;
1646
1647     l = aopGet(op->aop,offset++,FALSE,FALSE);
1648     MOVA(l);    
1649
1650     while(size--) {
1651         pic14_emitcode("orl","a,%s",
1652                  aopGet(op->aop,
1653                         offset++,FALSE,FALSE));
1654     }
1655     tlbl = newiTempLabel(NULL);
1656
1657     tlbl = newiTempLabel(NULL);
1658     aopPut(res->aop,one,1);
1659     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1660     aopPut(res->aop,zero,1);
1661     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1662
1663     size = res->aop->size - 2;
1664     offset = 2;    
1665     /* put zeros in the rest */
1666     while (size--) 
1667         aopPut(res->aop,zero,offset++);
1668 }
1669
1670 #if 0
1671 /*-----------------------------------------------------------------*/
1672 /* opIsGptr: returns non-zero if the passed operand is             */   
1673 /* a generic pointer type.                                         */
1674 /*-----------------------------------------------------------------*/ 
1675 static int opIsGptr(operand *op)
1676 {
1677     sym_link *type = operandType(op);
1678     
1679     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1680     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1681     {
1682         return 1;
1683     }
1684     return 0;        
1685 }
1686 #endif
1687
1688 /*-----------------------------------------------------------------*/
1689 /* pic14_getDataSize - get the operand data size                         */
1690 /*-----------------------------------------------------------------*/
1691 int pic14_getDataSize(operand *op)
1692 {
1693     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1694
1695
1696     return AOP_SIZE(op);
1697
1698     // tsd- in the pic port, the genptr size is 1, so this code here
1699     // fails. ( in the 8051 port, the size was 4).
1700 #if 0
1701     int size;
1702     size = AOP_SIZE(op);
1703     if (size == GPTRSIZE)
1704     {
1705         sym_link *type = operandType(op);
1706         if (IS_GENPTR(type))
1707         {
1708             /* generic pointer; arithmetic operations
1709              * should ignore the high byte (pointer type).
1710              */
1711             size--;
1712     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1713         }
1714     }
1715     return size;
1716 #endif
1717 }
1718
1719 /*-----------------------------------------------------------------*/
1720 /* pic14_outAcc - output Acc                                             */
1721 /*-----------------------------------------------------------------*/
1722 void pic14_outAcc(operand *result)
1723 {
1724   int size,offset;
1725   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1726   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1727
1728
1729   size = pic14_getDataSize(result);
1730   if(size){
1731     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1732     size--;
1733     offset = 1;
1734     /* unsigned or positive */
1735     while(size--)
1736       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1737   }
1738
1739 }
1740
1741 /*-----------------------------------------------------------------*/
1742 /* pic14_outBitC - output a bit C                                        */
1743 /*-----------------------------------------------------------------*/
1744 void pic14_outBitC(operand *result)
1745 {
1746
1747     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1748     /* if the result is bit */
1749     if (AOP_TYPE(result) == AOP_CRY) 
1750         aopPut(AOP(result),"c",0);
1751     else {
1752         pic14_emitcode("clr","a  ; %d", __LINE__);
1753         pic14_emitcode("rlc","a");
1754         pic14_outAcc(result);
1755     }
1756 }
1757
1758 /*-----------------------------------------------------------------*/
1759 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1760 /*-----------------------------------------------------------------*/
1761 void pic14_toBoolean(operand *oper)
1762 {
1763     int size = AOP_SIZE(oper) - 1;
1764     int offset = 1;
1765
1766     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1767
1768     if ( AOP_TYPE(oper) != AOP_ACC) {
1769       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1770     }
1771     while (size--) {
1772       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1773     }
1774 }
1775
1776
1777 /*-----------------------------------------------------------------*/
1778 /* genNot - generate code for ! operation                          */
1779 /*-----------------------------------------------------------------*/
1780 static void genNot (iCode *ic)
1781 {
1782   symbol *tlbl;
1783   sym_link *optype = operandType(IC_LEFT(ic));
1784   int size;
1785
1786   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1787   /* assign asmOps to operand & result */
1788   aopOp (IC_LEFT(ic),ic,FALSE);
1789   aopOp (IC_RESULT(ic),ic,TRUE);
1790
1791   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1792   /* if in bit space then a special case */
1793   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1794     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1795       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1796       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1797     } else {
1798       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1799       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1800       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1801     }
1802     goto release;
1803   }
1804
1805   /* if type float then do float */
1806   if (IS_FLOAT(optype)) {
1807     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1808     goto release;
1809   }
1810
1811   size = AOP_SIZE(IC_RESULT(ic));
1812   if(size == 1) {
1813     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1814     emitpcode(POC_ANDLW,popGetLit(1));
1815     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1816     goto release;
1817   }
1818   pic14_toBoolean(IC_LEFT(ic));
1819
1820   tlbl = newiTempLabel(NULL);
1821   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1822   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1823   pic14_outBitC(IC_RESULT(ic));
1824
1825  release:    
1826   /* release the aops */
1827   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1828   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1829 }
1830
1831
1832 /*-----------------------------------------------------------------*/
1833 /* genCpl - generate code for complement                           */
1834 /*-----------------------------------------------------------------*/
1835 static void genCpl (iCode *ic)
1836 {
1837     int offset = 0;
1838     int size ;
1839
1840
1841     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1842     /* assign asmOps to operand & result */
1843     aopOp (IC_LEFT(ic),ic,FALSE);
1844     aopOp (IC_RESULT(ic),ic,TRUE);
1845
1846     /* if both are in bit space then 
1847     a special case */
1848     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1849         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1850
1851         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1852         pic14_emitcode("cpl","c"); 
1853         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1854         goto release; 
1855     } 
1856
1857     size = AOP_SIZE(IC_RESULT(ic));
1858     while (size--) {
1859         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1860         MOVA(l);       
1861         pic14_emitcode("cpl","a");
1862         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1863     }
1864
1865
1866 release:
1867     /* release the aops */
1868     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1869     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1870 }
1871
1872 /*-----------------------------------------------------------------*/
1873 /* genUminusFloat - unary minus for floating points                */
1874 /*-----------------------------------------------------------------*/
1875 static void genUminusFloat(operand *op,operand *result)
1876 {
1877     int size ,offset =0 ;
1878     char *l;
1879
1880     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1881     /* for this we just need to flip the 
1882     first it then copy the rest in place */
1883     size = AOP_SIZE(op) - 1;
1884     l = aopGet(AOP(op),3,FALSE,FALSE);
1885
1886     MOVA(l);    
1887
1888     pic14_emitcode("cpl","acc.7");
1889     aopPut(AOP(result),"a",3);    
1890
1891     while(size--) {
1892         aopPut(AOP(result),
1893                aopGet(AOP(op),offset,FALSE,FALSE),
1894                offset);
1895         offset++;
1896     }          
1897 }
1898
1899 /*-----------------------------------------------------------------*/
1900 /* genUminus - unary minus code generation                         */
1901 /*-----------------------------------------------------------------*/
1902 static void genUminus (iCode *ic)
1903 {
1904   int size, i;
1905   sym_link *optype, *rtype;
1906
1907
1908   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1909   /* assign asmops */
1910   aopOp(IC_LEFT(ic),ic,FALSE);
1911   aopOp(IC_RESULT(ic),ic,TRUE);
1912
1913   /* if both in bit space then special
1914      case */
1915   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1916       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1917
1918     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1919     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1920     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1921
1922     goto release; 
1923   } 
1924
1925   optype = operandType(IC_LEFT(ic));
1926   rtype = operandType(IC_RESULT(ic));
1927
1928   /* if float then do float stuff */
1929   if (IS_FLOAT(optype)) {
1930     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1931     goto release;
1932   }
1933
1934   /* otherwise subtract from zero by taking the 2's complement */
1935   size = AOP_SIZE(IC_LEFT(ic));
1936
1937   for(i=0; i<size; i++) {
1938     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1939       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1940     else {
1941       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1942       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1943     }
1944   }
1945
1946   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1947   for(i=1; i<size; i++) {
1948     emitSKPNZ;
1949     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1950   }
1951
1952  release:
1953   /* release the aops */
1954   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1955   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1956 }
1957
1958 /*-----------------------------------------------------------------*/
1959 /* saveRegisters - will look for a call and save the registers     */
1960 /*-----------------------------------------------------------------*/
1961 static void saveRegisters(iCode *lic) 
1962 {
1963     int i;
1964     iCode *ic;
1965     bitVect *rsave;
1966     sym_link *dtype;
1967
1968     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1969     /* look for call */
1970     for (ic = lic ; ic ; ic = ic->next) 
1971         if (ic->op == CALL || ic->op == PCALL)
1972             break;
1973
1974     if (!ic) {
1975         fprintf(stderr,"found parameter push with no function call\n");
1976         return ;
1977     }
1978
1979     /* if the registers have been saved already then
1980     do nothing */
1981     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1982         return ;
1983
1984     /* find the registers in use at this time 
1985     and push them away to safety */
1986     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1987                           ic->rUsed);
1988
1989     ic->regsSaved = 1;
1990     if (options.useXstack) {
1991         if (bitVectBitValue(rsave,R0_IDX))
1992             pic14_emitcode("mov","b,r0");
1993         pic14_emitcode("mov","r0,%s",spname);
1994         for (i = 0 ; i < pic14_nRegs ; i++) {
1995             if (bitVectBitValue(rsave,i)) {
1996                 if (i == R0_IDX)
1997                     pic14_emitcode("mov","a,b");
1998                 else
1999                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2000                 pic14_emitcode("movx","@r0,a");
2001                 pic14_emitcode("inc","r0");
2002             }
2003         }
2004         pic14_emitcode("mov","%s,r0",spname);
2005         if (bitVectBitValue(rsave,R0_IDX))
2006             pic14_emitcode("mov","r0,b");           
2007     }// else
2008     //for (i = 0 ; i < pic14_nRegs ; i++) {
2009     //    if (bitVectBitValue(rsave,i))
2010     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2011     //}
2012
2013     dtype = operandType(IC_LEFT(ic));
2014     if (currFunc && dtype && 
2015         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2016         IFFUNC_ISISR(currFunc->type) &&
2017         !ic->bankSaved) 
2018
2019         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2020
2021 }
2022 /*-----------------------------------------------------------------*/
2023 /* unsaveRegisters - pop the pushed registers                      */
2024 /*-----------------------------------------------------------------*/
2025 static void unsaveRegisters (iCode *ic)
2026 {
2027     int i;
2028     bitVect *rsave;
2029
2030     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2031     /* find the registers in use at this time 
2032     and push them away to safety */
2033     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2034                           ic->rUsed);
2035     
2036     if (options.useXstack) {
2037         pic14_emitcode("mov","r0,%s",spname);   
2038         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2039             if (bitVectBitValue(rsave,i)) {
2040                 pic14_emitcode("dec","r0");
2041                 pic14_emitcode("movx","a,@r0");
2042                 if (i == R0_IDX)
2043                     pic14_emitcode("mov","b,a");
2044                 else
2045                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2046             }       
2047
2048         }
2049         pic14_emitcode("mov","%s,r0",spname);
2050         if (bitVectBitValue(rsave,R0_IDX))
2051             pic14_emitcode("mov","r0,b");
2052     } //else
2053     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2054     //    if (bitVectBitValue(rsave,i))
2055     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2056     //}
2057
2058 }  
2059
2060
2061 /*-----------------------------------------------------------------*/
2062 /* pushSide -                                                      */
2063 /*-----------------------------------------------------------------*/
2064 static void pushSide(operand * oper, int size)
2065 {
2066 #if 0
2067         int offset = 0;
2068     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2069         while (size--) {
2070                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2071                 if (AOP_TYPE(oper) != AOP_REG &&
2072                     AOP_TYPE(oper) != AOP_DIR &&
2073                     strcmp(l,"a") ) {
2074                         pic14_emitcode("mov","a,%s",l);
2075                         pic14_emitcode("push","acc");
2076                 } else
2077                         pic14_emitcode("push","%s",l);
2078         }
2079 #endif
2080 }
2081
2082 /*-----------------------------------------------------------------*/
2083 /* assignResultValue -                                             */
2084 /*-----------------------------------------------------------------*/
2085 static void assignResultValue(operand * oper)
2086 {
2087   int size = AOP_SIZE(oper);
2088
2089   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2090
2091   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2092
2093   if(!GpsuedoStkPtr) {
2094     /* The last byte in the assignment is in W */
2095     size--;
2096     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2097     GpsuedoStkPtr++;
2098   }
2099
2100   while (size--) {
2101     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2102     GpsuedoStkPtr++;
2103     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2104   }
2105 }
2106
2107
2108 /*-----------------------------------------------------------------*/
2109 /* genIpush - genrate code for pushing this gets a little complex  */
2110 /*-----------------------------------------------------------------*/
2111 static void genIpush (iCode *ic)
2112 {
2113
2114   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2115 #if 0
2116     int size, offset = 0 ;
2117     char *l;
2118
2119
2120     /* if this is not a parm push : ie. it is spill push 
2121     and spill push is always done on the local stack */
2122     if (!ic->parmPush) {
2123
2124         /* and the item is spilt then do nothing */
2125         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2126             return ;
2127
2128         aopOp(IC_LEFT(ic),ic,FALSE);
2129         size = AOP_SIZE(IC_LEFT(ic));
2130         /* push it on the stack */
2131         while(size--) {
2132             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2133             if (*l == '#') {
2134                 MOVA(l);
2135                 l = "acc";
2136             }
2137             pic14_emitcode("push","%s",l);
2138         }
2139         return ;        
2140     }
2141
2142     /* this is a paramter push: in this case we call
2143     the routine to find the call and save those
2144     registers that need to be saved */   
2145     saveRegisters(ic);
2146
2147     /* then do the push */
2148     aopOp(IC_LEFT(ic),ic,FALSE);
2149
2150
2151         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2152     size = AOP_SIZE(IC_LEFT(ic));
2153
2154     while (size--) {
2155         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2156         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2157             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2158             strcmp(l,"a") ) {
2159             pic14_emitcode("mov","a,%s",l);
2160             pic14_emitcode("push","acc");
2161         } else
2162             pic14_emitcode("push","%s",l);
2163     }       
2164
2165     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2166 #endif
2167 }
2168
2169 /*-----------------------------------------------------------------*/
2170 /* genIpop - recover the registers: can happen only for spilling   */
2171 /*-----------------------------------------------------------------*/
2172 static void genIpop (iCode *ic)
2173 {
2174   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2175 #if 0
2176     int size,offset ;
2177
2178
2179     /* if the temp was not pushed then */
2180     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2181         return ;
2182
2183     aopOp(IC_LEFT(ic),ic,FALSE);
2184     size = AOP_SIZE(IC_LEFT(ic));
2185     offset = (size-1);
2186     while (size--) 
2187         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2188                                    FALSE,TRUE));
2189
2190     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2191 #endif
2192 }
2193
2194 /*-----------------------------------------------------------------*/
2195 /* unsaverbank - restores the resgister bank from stack            */
2196 /*-----------------------------------------------------------------*/
2197 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2198 {
2199   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2200 #if 0
2201     int i;
2202     asmop *aop ;
2203     regs *r = NULL;
2204
2205     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2206     if (popPsw) {
2207         if (options.useXstack) {
2208             aop = newAsmop(0);
2209             r = getFreePtr(ic,&aop,FALSE);
2210             
2211             
2212             pic14_emitcode("mov","%s,_spx",r->name);
2213             pic14_emitcode("movx","a,@%s",r->name);
2214             pic14_emitcode("mov","psw,a");
2215             pic14_emitcode("dec","%s",r->name);
2216             
2217         }else
2218             pic14_emitcode ("pop","psw");
2219     }
2220
2221     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2222         if (options.useXstack) {       
2223             pic14_emitcode("movx","a,@%s",r->name);
2224             //pic14_emitcode("mov","(%s+%d),a",
2225             //       regspic14[i].base,8*bank+regspic14[i].offset);
2226             pic14_emitcode("dec","%s",r->name);
2227
2228         } else 
2229           pic14_emitcode("pop",""); //"(%s+%d)",
2230         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2231     }
2232
2233     if (options.useXstack) {
2234
2235         pic14_emitcode("mov","_spx,%s",r->name);
2236         freeAsmop(NULL,aop,ic,TRUE);
2237
2238     }
2239 #endif 
2240 }
2241
2242 /*-----------------------------------------------------------------*/
2243 /* saverbank - saves an entire register bank on the stack          */
2244 /*-----------------------------------------------------------------*/
2245 static void saverbank (int bank, iCode *ic, bool pushPsw)
2246 {
2247   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2248 #if 0
2249     int i;
2250     asmop *aop ;
2251     regs *r = NULL;
2252
2253     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2254     if (options.useXstack) {
2255
2256         aop = newAsmop(0);
2257         r = getFreePtr(ic,&aop,FALSE);  
2258         pic14_emitcode("mov","%s,_spx",r->name);
2259
2260     }
2261
2262     for (i = 0 ; i < pic14_nRegs ;i++) {
2263         if (options.useXstack) {
2264             pic14_emitcode("inc","%s",r->name);
2265             //pic14_emitcode("mov","a,(%s+%d)",
2266             //         regspic14[i].base,8*bank+regspic14[i].offset);
2267             pic14_emitcode("movx","@%s,a",r->name);           
2268         } else 
2269           pic14_emitcode("push","");// "(%s+%d)",
2270                      //regspic14[i].base,8*bank+regspic14[i].offset);
2271     }
2272     
2273     if (pushPsw) {
2274         if (options.useXstack) {
2275             pic14_emitcode("mov","a,psw");
2276             pic14_emitcode("movx","@%s,a",r->name);     
2277             pic14_emitcode("inc","%s",r->name);
2278             pic14_emitcode("mov","_spx,%s",r->name);       
2279             freeAsmop (NULL,aop,ic,TRUE);
2280             
2281         } else
2282             pic14_emitcode("push","psw");
2283         
2284         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2285     }
2286     ic->bankSaved = 1;
2287 #endif
2288 }
2289
2290 /*-----------------------------------------------------------------*/
2291 /* genCall - generates a call statement                            */
2292 /*-----------------------------------------------------------------*/
2293 static void genCall (iCode *ic)
2294 {
2295   sym_link *dtype;   
2296
2297   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2298
2299   /* if caller saves & we have not saved then */
2300   if (!ic->regsSaved)
2301     saveRegisters(ic);
2302
2303   /* if we are calling a function that is not using
2304      the same register bank then we need to save the
2305      destination registers on the stack */
2306   dtype = operandType(IC_LEFT(ic));
2307   if (currFunc && dtype && 
2308       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2309       IFFUNC_ISISR(currFunc->type) &&
2310       !ic->bankSaved) 
2311
2312     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2313
2314   /* if send set is not empty the assign */
2315   if (_G.sendSet) {
2316     iCode *sic;
2317     /* For the Pic port, there is no data stack.
2318      * So parameters passed to functions are stored
2319      * in registers. (The pCode optimizer will get
2320      * rid of most of these :).
2321      */
2322     int psuedoStkPtr=-1; 
2323     int firstTimeThruLoop = 1;
2324
2325     _G.sendSet = reverseSet(_G.sendSet);
2326
2327     /* First figure how many parameters are getting passed */
2328     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2329          sic = setNextItem(_G.sendSet)) {
2330
2331       aopOp(IC_LEFT(sic),sic,FALSE);
2332       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2333       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2334     }
2335
2336     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2337          sic = setNextItem(_G.sendSet)) {
2338       int size, offset = 0;
2339
2340       aopOp(IC_LEFT(sic),sic,FALSE);
2341       size = AOP_SIZE(IC_LEFT(sic));
2342
2343
2344       while (size--) {
2345         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2346                              AopType(AOP_TYPE(IC_LEFT(sic))));
2347
2348         if(!firstTimeThruLoop) {
2349           /* If this is not the first time we've been through the loop
2350            * then we need to save the parameter in a temporary
2351            * register. The last byte of the last parameter is
2352            * passed in W. */
2353           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2354
2355         }
2356         firstTimeThruLoop=0;
2357
2358         //if (strcmp(l,fReturn[offset])) {
2359
2360         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2361              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2362           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2363         else
2364           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2365
2366         //}
2367         offset++;
2368       }
2369       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2370     }
2371     _G.sendSet = NULL;
2372   }
2373   /* make the call */
2374   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2375                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2376                                       OP_SYMBOL(IC_LEFT(ic))->name));
2377
2378   GpsuedoStkPtr=0;
2379   /* if we need assign a result value */
2380   if ((IS_ITEMP(IC_RESULT(ic)) && 
2381        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2382         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2383       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2384
2385     _G.accInUse++;
2386     aopOp(IC_RESULT(ic),ic,FALSE);
2387     _G.accInUse--;
2388
2389     assignResultValue(IC_RESULT(ic));
2390
2391     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2392                          AopType(AOP_TYPE(IC_RESULT(ic))));
2393                 
2394     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2395   }
2396
2397   /* adjust the stack for parameters if 
2398      required */
2399   if (ic->parmBytes) {
2400     int i;
2401     if (ic->parmBytes > 3) {
2402       pic14_emitcode("mov","a,%s",spname);
2403       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2404       pic14_emitcode("mov","%s,a",spname);
2405     } else 
2406       for ( i = 0 ; i <  ic->parmBytes ;i++)
2407         pic14_emitcode("dec","%s",spname);
2408
2409   }
2410
2411   /* if register bank was saved then pop them */
2412   if (ic->bankSaved)
2413     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2414
2415   /* if we hade saved some registers then unsave them */
2416   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2417     unsaveRegisters (ic);
2418
2419
2420 }
2421
2422 /*-----------------------------------------------------------------*/
2423 /* genPcall - generates a call by pointer statement                */
2424 /*-----------------------------------------------------------------*/
2425 static void genPcall (iCode *ic)
2426 {
2427     sym_link *dtype;
2428     symbol *rlbl = newiTempLabel(NULL);
2429
2430
2431     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2432     /* if caller saves & we have not saved then */
2433     if (!ic->regsSaved)
2434         saveRegisters(ic);
2435
2436     /* if we are calling a function that is not using
2437     the same register bank then we need to save the
2438     destination registers on the stack */
2439     dtype = operandType(IC_LEFT(ic));
2440     if (currFunc && dtype && 
2441         IFFUNC_ISISR(currFunc->type) &&
2442         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2443         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2444
2445
2446     /* push the return address on to the stack */
2447     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2448     pic14_emitcode("push","acc");    
2449     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2450     pic14_emitcode("push","acc");
2451     
2452     if (options.model == MODEL_FLAT24)
2453     {
2454         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2455         pic14_emitcode("push","acc");    
2456     }
2457
2458     /* now push the calling address */
2459     aopOp(IC_LEFT(ic),ic,FALSE);
2460
2461     pushSide(IC_LEFT(ic), FPTRSIZE);
2462
2463     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2464
2465     /* if send set is not empty the assign */
2466     if (_G.sendSet) {
2467         iCode *sic ;
2468
2469         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2470              sic = setNextItem(_G.sendSet)) {
2471             int size, offset = 0;
2472             aopOp(IC_LEFT(sic),sic,FALSE);
2473             size = AOP_SIZE(IC_LEFT(sic));
2474             while (size--) {
2475                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2476                                 FALSE,FALSE);
2477                 if (strcmp(l,fReturn[offset]))
2478                     pic14_emitcode("mov","%s,%s",
2479                              fReturn[offset],
2480                              l);
2481                 offset++;
2482             }
2483             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2484         }
2485         _G.sendSet = NULL;
2486     }
2487
2488     pic14_emitcode("ret","");
2489     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2490
2491
2492     /* if we need assign a result value */
2493     if ((IS_ITEMP(IC_RESULT(ic)) &&
2494          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2495           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2496         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2497
2498         _G.accInUse++;
2499         aopOp(IC_RESULT(ic),ic,FALSE);
2500         _G.accInUse--;
2501         
2502         assignResultValue(IC_RESULT(ic));
2503
2504         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2505     }
2506
2507     /* adjust the stack for parameters if 
2508     required */
2509     if (ic->parmBytes) {
2510         int i;
2511         if (ic->parmBytes > 3) {
2512             pic14_emitcode("mov","a,%s",spname);
2513             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2514             pic14_emitcode("mov","%s,a",spname);
2515         } else 
2516             for ( i = 0 ; i <  ic->parmBytes ;i++)
2517                 pic14_emitcode("dec","%s",spname);
2518
2519     }
2520
2521     /* if register bank was saved then unsave them */
2522     if (currFunc && dtype && 
2523         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2524         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2525
2526     /* if we hade saved some registers then
2527     unsave them */
2528     if (ic->regsSaved)
2529         unsaveRegisters (ic);
2530
2531 }
2532
2533 /*-----------------------------------------------------------------*/
2534 /* resultRemat - result  is rematerializable                       */
2535 /*-----------------------------------------------------------------*/
2536 static int resultRemat (iCode *ic)
2537 {
2538     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2539     if (SKIP_IC(ic) || ic->op == IFX)
2540         return 0;
2541
2542     if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2543         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2544         if (sym->remat && !POINTER_SET(ic)) 
2545             return 1;
2546     }
2547
2548     return 0;
2549 }
2550
2551 #if defined(__BORLANDC__) || defined(_MSC_VER)
2552 #define STRCASECMP stricmp
2553 #else
2554 #define STRCASECMP strcasecmp
2555 #endif
2556
2557 #if 0
2558 /*-----------------------------------------------------------------*/
2559 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2560 /*-----------------------------------------------------------------*/
2561 static bool inExcludeList(char *s)
2562 {
2563   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2564     int i =0;
2565     
2566     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2567     if (options.excludeRegs[i] &&
2568     STRCASECMP(options.excludeRegs[i],"none") == 0)
2569         return FALSE ;
2570
2571     for ( i = 0 ; options.excludeRegs[i]; i++) {
2572         if (options.excludeRegs[i] &&
2573         STRCASECMP(s,options.excludeRegs[i]) == 0)
2574             return TRUE;
2575     }
2576     return FALSE ;
2577 }
2578 #endif
2579
2580 /*-----------------------------------------------------------------*/
2581 /* genFunction - generated code for function entry                 */
2582 /*-----------------------------------------------------------------*/
2583 static void genFunction (iCode *ic)
2584 {
2585     symbol *sym;
2586     sym_link *ftype;
2587
2588     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2589
2590     labelOffset += (max_key+4);
2591     max_key=0;
2592     GpsuedoStkPtr=0;
2593     _G.nRegsSaved = 0;
2594     /* create the function header */
2595     pic14_emitcode(";","-----------------------------------------");
2596     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2597     pic14_emitcode(";","-----------------------------------------");
2598
2599     pic14_emitcode("","%s:",sym->rname);
2600     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2601
2602     ftype = operandType(IC_LEFT(ic));
2603
2604     /* if critical function then turn interrupts off */
2605     if (IFFUNC_ISCRITICAL(ftype))
2606         pic14_emitcode("clr","ea");
2607
2608     /* here we need to generate the equates for the
2609        register bank if required */
2610 #if 0
2611     if (FUNC_REGBANK(ftype) != rbank) {
2612         int i ;
2613
2614         rbank = FUNC_REGBANK(ftype);
2615         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2616             if (strcmp(regspic14[i].base,"0") == 0)
2617                 pic14_emitcode("","%s = 0x%02x",
2618                          regspic14[i].dname,
2619                          8*rbank+regspic14[i].offset);
2620             else
2621                 pic14_emitcode ("","%s = %s + 0x%02x",
2622                           regspic14[i].dname,
2623                           regspic14[i].base,
2624                           8*rbank+regspic14[i].offset);
2625         }
2626     }
2627 #endif
2628
2629     /* if this is an interrupt service routine then
2630     save acc, b, dpl, dph  */
2631     if (IFFUNC_ISISR(sym->type)) {
2632       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2633       emitpcodeNULLop(POC_NOP);
2634       emitpcodeNULLop(POC_NOP);
2635       emitpcodeNULLop(POC_NOP);
2636       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2637       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2638       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2639       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2640
2641       pBlockConvert2ISR(pb);
2642 #if 0  
2643         if (!inExcludeList("acc"))          
2644             pic14_emitcode ("push","acc");      
2645         if (!inExcludeList("b"))
2646             pic14_emitcode ("push","b");
2647         if (!inExcludeList("dpl"))
2648             pic14_emitcode ("push","dpl");
2649         if (!inExcludeList("dph"))
2650             pic14_emitcode ("push","dph");
2651         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2652         {
2653             pic14_emitcode ("push", "dpx");
2654             /* Make sure we're using standard DPTR */
2655             pic14_emitcode ("push", "dps");
2656             pic14_emitcode ("mov", "dps, #0x00");
2657             if (options.stack10bit)
2658             {   
2659                 /* This ISR could conceivably use DPTR2. Better save it. */
2660                 pic14_emitcode ("push", "dpl1");
2661                 pic14_emitcode ("push", "dph1");
2662                 pic14_emitcode ("push", "dpx1");
2663             }
2664         }
2665         /* if this isr has no bank i.e. is going to
2666            run with bank 0 , then we need to save more
2667            registers :-) */
2668         if (!FUNC_REGBANK(sym->type)) {
2669
2670             /* if this function does not call any other
2671                function then we can be economical and
2672                save only those registers that are used */
2673             if (! IFFUNC_HASFCALL(sym->type)) {
2674                 int i;
2675
2676                 /* if any registers used */
2677                 if (sym->regsUsed) {
2678                     /* save the registers used */
2679                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2680                         if (bitVectBitValue(sym->regsUsed,i) ||
2681                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2682                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2683                     }
2684                 }
2685                 
2686             } else {
2687                 /* this function has  a function call cannot
2688                    determines register usage so we will have the
2689                    entire bank */
2690                 saverbank(0,ic,FALSE);
2691             }       
2692         }
2693 #endif
2694     } else {
2695         /* if callee-save to be used for this function
2696            then save the registers being used in this function */
2697         if (IFFUNC_CALLEESAVES(sym->type)) {
2698             int i;
2699             
2700             /* if any registers used */
2701             if (sym->regsUsed) {
2702                 /* save the registers used */
2703                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2704                     if (bitVectBitValue(sym->regsUsed,i) ||
2705                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2706                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2707                         _G.nRegsSaved++;
2708                     }
2709                 }
2710             }
2711         }
2712     }
2713
2714     /* set the register bank to the desired value */
2715     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2716         pic14_emitcode("push","psw");
2717         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2718     }
2719
2720     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2721
2722         if (options.useXstack) {
2723             pic14_emitcode("mov","r0,%s",spname);
2724             pic14_emitcode("mov","a,_bp");
2725             pic14_emitcode("movx","@r0,a");
2726             pic14_emitcode("inc","%s",spname);
2727         }
2728         else
2729         {
2730             /* set up the stack */
2731             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2732         }
2733         pic14_emitcode ("mov","_bp,%s",spname);
2734     }
2735
2736     /* adjust the stack for the function */
2737     if (sym->stack) {
2738
2739         int i = sym->stack;
2740         if (i > 256 ) 
2741             werror(W_STACK_OVERFLOW,sym->name);
2742
2743         if (i > 3 && sym->recvSize < 4) {              
2744
2745             pic14_emitcode ("mov","a,sp");
2746             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2747             pic14_emitcode ("mov","sp,a");
2748            
2749         }
2750         else
2751             while(i--)
2752                 pic14_emitcode("inc","sp");
2753     }
2754
2755      if (sym->xstack) {
2756
2757         pic14_emitcode ("mov","a,_spx");
2758         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2759         pic14_emitcode ("mov","_spx,a");
2760     }    
2761
2762 }
2763
2764 /*-----------------------------------------------------------------*/
2765 /* genEndFunction - generates epilogue for functions               */
2766 /*-----------------------------------------------------------------*/
2767 static void genEndFunction (iCode *ic)
2768 {
2769     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2770
2771     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2772
2773     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2774     {
2775         pic14_emitcode ("mov","%s,_bp",spname);
2776     }
2777
2778     /* if use external stack but some variables were
2779     added to the local stack then decrement the
2780     local stack */
2781     if (options.useXstack && sym->stack) {      
2782         pic14_emitcode("mov","a,sp");
2783         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2784         pic14_emitcode("mov","sp,a");
2785     }
2786
2787
2788     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2789         if (options.useXstack) {
2790             pic14_emitcode("mov","r0,%s",spname);
2791             pic14_emitcode("movx","a,@r0");
2792             pic14_emitcode("mov","_bp,a");
2793             pic14_emitcode("dec","%s",spname);
2794         }
2795         else
2796         {
2797             pic14_emitcode ("pop","_bp");
2798         }
2799     }
2800
2801     /* restore the register bank  */    
2802     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2803         pic14_emitcode ("pop","psw");
2804
2805     if (IFFUNC_ISISR(sym->type)) {
2806
2807         /* now we need to restore the registers */
2808         /* if this isr has no bank i.e. is going to
2809            run with bank 0 , then we need to save more
2810            registers :-) */
2811         if (!FUNC_REGBANK(sym->type)) {
2812             
2813             /* if this function does not call any other
2814                function then we can be economical and
2815                save only those registers that are used */
2816             if (! IFFUNC_HASFCALL(sym->type)) {
2817                 int i;
2818                 
2819                 /* if any registers used */
2820                 if (sym->regsUsed) {
2821                     /* save the registers used */
2822                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2823                         if (bitVectBitValue(sym->regsUsed,i) ||
2824                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2825                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2826                     }
2827                 }
2828                 
2829             } else {
2830                 /* this function has  a function call cannot
2831                    determines register usage so we will have the
2832                    entire bank */
2833                 unsaverbank(0,ic,FALSE);
2834             }       
2835         }
2836 #if 0
2837         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2838         {
2839             if (options.stack10bit)
2840             {
2841                 pic14_emitcode ("pop", "dpx1");
2842                 pic14_emitcode ("pop", "dph1");
2843                 pic14_emitcode ("pop", "dpl1");
2844             }   
2845             pic14_emitcode ("pop", "dps");
2846             pic14_emitcode ("pop", "dpx");
2847         }
2848         if (!inExcludeList("dph"))
2849             pic14_emitcode ("pop","dph");
2850         if (!inExcludeList("dpl"))
2851             pic14_emitcode ("pop","dpl");
2852         if (!inExcludeList("b"))
2853             pic14_emitcode ("pop","b");
2854         if (!inExcludeList("acc"))
2855             pic14_emitcode ("pop","acc");
2856
2857         if (IFFUNC_ISCRITICAL(sym->type))
2858             pic14_emitcode("setb","ea");
2859 #endif
2860
2861         /* if debug then send end of function */
2862 /*      if (options.debug && currFunc) { */
2863         if (currFunc) {
2864             _G.debugLine = 1;
2865             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2866                      FileBaseName(ic->filename),currFunc->lastLine,
2867                      ic->level,ic->block); 
2868             if (IS_STATIC(currFunc->etype))         
2869                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2870             else
2871                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2872             _G.debugLine = 0;
2873         }
2874         
2875         pic14_emitcode ("reti","");
2876
2877         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2878         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2879         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2880         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2881         emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
2882         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2883
2884         emitpcodeNULLop(POC_RETFIE);
2885
2886     }
2887     else {
2888         if (IFFUNC_ISCRITICAL(sym->type))
2889             pic14_emitcode("setb","ea");
2890         
2891         if (IFFUNC_CALLEESAVES(sym->type)) {
2892             int i;
2893             
2894             /* if any registers used */
2895             if (sym->regsUsed) {
2896                 /* save the registers used */
2897                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2898                     if (bitVectBitValue(sym->regsUsed,i) ||
2899                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2900                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2901                 }
2902             }
2903             
2904         }
2905
2906         /* if debug then send end of function */
2907         if (currFunc) {
2908             _G.debugLine = 1;
2909             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2910                      FileBaseName(ic->filename),currFunc->lastLine,
2911                      ic->level,ic->block); 
2912             if (IS_STATIC(currFunc->etype))         
2913                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2914             else
2915                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2916             _G.debugLine = 0;
2917         }
2918
2919         pic14_emitcode ("return","");
2920         emitpcodeNULLop(POC_RETURN);
2921
2922         /* Mark the end of a function */
2923         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2924     }
2925
2926 }
2927
2928 /*-----------------------------------------------------------------*/
2929 /* genRet - generate code for return statement                     */
2930 /*-----------------------------------------------------------------*/
2931 static void genRet (iCode *ic)
2932 {
2933   int size,offset = 0 , pushed = 0;
2934     
2935   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2936   /* if we have no return value then
2937      just generate the "ret" */
2938   if (!IC_LEFT(ic)) 
2939     goto jumpret;       
2940     
2941   /* we have something to return then
2942      move the return value into place */
2943   aopOp(IC_LEFT(ic),ic,FALSE);
2944   size = AOP_SIZE(IC_LEFT(ic));
2945     
2946   while (size--) {
2947     char *l ;
2948     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2949       /* #NOCHANGE */
2950       l = aopGet(AOP(IC_LEFT(ic)),offset++,
2951                  FALSE,TRUE);
2952       pic14_emitcode("push","%s",l);
2953       pushed++;
2954     } else {
2955       l = aopGet(AOP(IC_LEFT(ic)),offset,
2956                  FALSE,FALSE);
2957       if (strcmp(fReturn[offset],l)) {
2958         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2959             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2960           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2961         }else {
2962           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2963         }
2964         if(size) {
2965           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2966           pic14_emitcode("movwf","%s",fReturn[offset]);
2967         }
2968         offset++;
2969       }
2970     }
2971   }    
2972
2973   if (pushed) {
2974     while(pushed) {
2975       pushed--;
2976       if (strcmp(fReturn[pushed],"a"))
2977         pic14_emitcode("pop",fReturn[pushed]);
2978       else
2979         pic14_emitcode("pop","acc");
2980     }
2981   }
2982   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2983     
2984  jumpret:
2985   /* generate a jump to the return label
2986      if the next is not the return statement */
2987   if (!(ic->next && ic->next->op == LABEL &&
2988         IC_LABEL(ic->next) == returnLabel)) {
2989         
2990     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2991     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2992   }
2993     
2994 }
2995
2996 /*-----------------------------------------------------------------*/
2997 /* genLabel - generates a label                                    */
2998 /*-----------------------------------------------------------------*/
2999 static void genLabel (iCode *ic)
3000 {
3001     /* special case never generate */
3002     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3003     if (IC_LABEL(ic) == entryLabel)
3004         return ;
3005
3006     emitpLabel(IC_LABEL(ic)->key);
3007     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3008 }
3009
3010 /*-----------------------------------------------------------------*/
3011 /* genGoto - generates a goto                                      */
3012 /*-----------------------------------------------------------------*/
3013 //tsd
3014 static void genGoto (iCode *ic)
3015 {
3016   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3017   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3018 }
3019
3020
3021 /*-----------------------------------------------------------------*/
3022 /* genMultbits :- multiplication of bits                           */
3023 /*-----------------------------------------------------------------*/
3024 static void genMultbits (operand *left, 
3025                          operand *right, 
3026                          operand *result)
3027 {
3028   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3029
3030   if(!pic14_sameRegs(AOP(result),AOP(right)))
3031     emitpcode(POC_BSF,  popGet(AOP(result),0));
3032
3033   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3034   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3035   emitpcode(POC_BCF,  popGet(AOP(result),0));
3036
3037 }
3038
3039
3040 /*-----------------------------------------------------------------*/
3041 /* genMultOneByte : 8 bit multiplication & division                */
3042 /*-----------------------------------------------------------------*/
3043 static void genMultOneByte (operand *left,
3044                             operand *right,
3045                             operand *result)
3046 {
3047   sym_link *opetype = operandType(result);
3048
3049   // symbol *lbl ;
3050   int size,offset;
3051
3052   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3053   DEBUGpic14_AopType(__LINE__,left,right,result);
3054   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3055
3056   /* (if two literals, the value is computed before) */
3057   /* if one literal, literal on the right */
3058   if (AOP_TYPE(left) == AOP_LIT){
3059     operand *t = right;
3060     right = left;
3061     left = t;
3062   }
3063
3064   size = AOP_SIZE(result);
3065   if(size == 1) {
3066
3067     if (AOP_TYPE(right) == AOP_LIT){
3068       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3069                      aopGet(AOP(right),0,FALSE,FALSE), 
3070                      aopGet(AOP(left),0,FALSE,FALSE), 
3071                      aopGet(AOP(result),0,FALSE,FALSE));
3072       pic14_emitcode("call","genMultLit");
3073     } else {
3074       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3075                      aopGet(AOP(right),0,FALSE,FALSE), 
3076                      aopGet(AOP(left),0,FALSE,FALSE), 
3077                      aopGet(AOP(result),0,FALSE,FALSE));
3078       pic14_emitcode("call","genMult8X8_8");
3079
3080     }
3081     genMult8X8_8 (left, right,result);
3082
3083
3084     /* signed or unsigned */
3085     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3086     //l = aopGet(AOP(left),0,FALSE,FALSE);
3087     //MOVA(l);       
3088     //pic14_emitcode("mul","ab");
3089     /* if result size = 1, mul signed = mul unsigned */
3090     //aopPut(AOP(result),"a",0);
3091
3092   } else {  // (size > 1)
3093
3094     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3095                    aopGet(AOP(right),0,FALSE,FALSE), 
3096                    aopGet(AOP(left),0,FALSE,FALSE), 
3097                    aopGet(AOP(result),0,FALSE,FALSE));
3098
3099     if (SPEC_USIGN(opetype)){
3100       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3101       genUMult8X8_16 (left, right, result, NULL);
3102
3103       if (size > 2) {
3104         /* for filling the MSBs */
3105         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3106         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3107       }
3108     }
3109     else{
3110       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3111
3112       pic14_emitcode("mov","a,b");
3113
3114       /* adjust the MSB if left or right neg */
3115
3116       /* if one literal */
3117       if (AOP_TYPE(right) == AOP_LIT){
3118         pic14_emitcode("multiply ","right is a lit");
3119         /* AND literal negative */
3120         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3121           /* adjust MSB (c==0 after mul) */
3122           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3123         }
3124       }
3125       else{
3126         genSMult8X8_16 (left, right, result, NULL);
3127       }
3128
3129       if(size > 2){
3130         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3131         /* get the sign */
3132         pic14_emitcode("rlc","a");
3133         pic14_emitcode("subb","a,acc");
3134       }
3135     }
3136
3137     size -= 2;   
3138     offset = 2;
3139     if (size > 0)
3140       while (size--)
3141         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3142     //aopPut(AOP(result),"a",offset++);
3143   }
3144 }
3145
3146 /*-----------------------------------------------------------------*/
3147 /* genMult - generates code for multiplication                     */
3148 /*-----------------------------------------------------------------*/
3149 static void genMult (iCode *ic)
3150 {
3151     operand *left = IC_LEFT(ic);
3152     operand *right = IC_RIGHT(ic);
3153     operand *result= IC_RESULT(ic);   
3154
3155     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3156     /* assign the amsops */
3157     aopOp (left,ic,FALSE);
3158     aopOp (right,ic,FALSE);
3159     aopOp (result,ic,TRUE);
3160
3161   DEBUGpic14_AopType(__LINE__,left,right,result);
3162
3163     /* special cases first */
3164     /* both are bits */
3165     if (AOP_TYPE(left) == AOP_CRY &&
3166         AOP_TYPE(right)== AOP_CRY) {
3167         genMultbits(left,right,result);
3168         goto release ;
3169     }
3170
3171     /* if both are of size == 1 */
3172     if (AOP_SIZE(left) == 1 &&
3173         AOP_SIZE(right) == 1 ) {
3174         genMultOneByte(left,right,result);
3175         goto release ;
3176     }
3177
3178     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3179
3180     /* should have been converted to function call */
3181     //assert(0) ;
3182
3183 release :
3184     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3185     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3186     freeAsmop(result,NULL,ic,TRUE); 
3187 }
3188
3189 /*-----------------------------------------------------------------*/
3190 /* genDivbits :- division of bits                                  */
3191 /*-----------------------------------------------------------------*/
3192 static void genDivbits (operand *left, 
3193                         operand *right, 
3194                         operand *result)
3195 {
3196
3197     char *l;
3198
3199     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3200     /* the result must be bit */    
3201     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3202     l = aopGet(AOP(left),0,FALSE,FALSE);
3203
3204     MOVA(l);    
3205
3206     pic14_emitcode("div","ab");
3207     pic14_emitcode("rrc","a");
3208     aopPut(AOP(result),"c",0);
3209 }
3210
3211 /*-----------------------------------------------------------------*/
3212 /* genDivOneByte : 8 bit division                                  */
3213 /*-----------------------------------------------------------------*/
3214 static void genDivOneByte (operand *left,
3215                            operand *right,
3216                            operand *result)
3217 {
3218     sym_link *opetype = operandType(result);
3219     char *l ;
3220     symbol *lbl ;
3221     int size,offset;
3222
3223     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3224     size = AOP_SIZE(result) - 1;
3225     offset = 1;
3226     /* signed or unsigned */
3227     if (SPEC_USIGN(opetype)) {
3228         /* unsigned is easy */
3229         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3230         l = aopGet(AOP(left),0,FALSE,FALSE);
3231         MOVA(l);        
3232         pic14_emitcode("div","ab");
3233         aopPut(AOP(result),"a",0);
3234         while (size--)
3235             aopPut(AOP(result),zero,offset++);
3236         return ;
3237     }
3238
3239     /* signed is a little bit more difficult */
3240
3241     /* save the signs of the operands */
3242     l = aopGet(AOP(left),0,FALSE,FALSE);    
3243     MOVA(l);    
3244     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3245     pic14_emitcode("push","acc"); /* save it on the stack */
3246
3247     /* now sign adjust for both left & right */
3248     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3249     MOVA(l);       
3250     lbl = newiTempLabel(NULL);
3251     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3252     pic14_emitcode("cpl","a");   
3253     pic14_emitcode("inc","a");
3254     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3255     pic14_emitcode("mov","b,a");
3256
3257     /* sign adjust left side */
3258     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3259     MOVA(l);
3260
3261     lbl = newiTempLabel(NULL);
3262     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3263     pic14_emitcode("cpl","a");
3264     pic14_emitcode("inc","a");
3265     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3266
3267     /* now the division */
3268     pic14_emitcode("div","ab");
3269     /* we are interested in the lower order
3270     only */
3271     pic14_emitcode("mov","b,a");
3272     lbl = newiTempLabel(NULL);
3273     pic14_emitcode("pop","acc");   
3274     /* if there was an over flow we don't 
3275     adjust the sign of the result */
3276     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3277     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3278     CLRC;
3279     pic14_emitcode("clr","a");
3280     pic14_emitcode("subb","a,b");
3281     pic14_emitcode("mov","b,a");
3282     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3283
3284     /* now we are done */
3285     aopPut(AOP(result),"b",0);
3286     if(size > 0){
3287         pic14_emitcode("mov","c,b.7");
3288         pic14_emitcode("subb","a,acc");   
3289     }
3290     while (size--)
3291         aopPut(AOP(result),"a",offset++);
3292
3293 }
3294
3295 /*-----------------------------------------------------------------*/
3296 /* genDiv - generates code for division                            */
3297 /*-----------------------------------------------------------------*/
3298 static void genDiv (iCode *ic)
3299 {
3300     operand *left = IC_LEFT(ic);
3301     operand *right = IC_RIGHT(ic);
3302     operand *result= IC_RESULT(ic);   
3303
3304     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3305     /* assign the amsops */
3306     aopOp (left,ic,FALSE);
3307     aopOp (right,ic,FALSE);
3308     aopOp (result,ic,TRUE);
3309
3310     /* special cases first */
3311     /* both are bits */
3312     if (AOP_TYPE(left) == AOP_CRY &&
3313         AOP_TYPE(right)== AOP_CRY) {
3314         genDivbits(left,right,result);
3315         goto release ;
3316     }
3317
3318     /* if both are of size == 1 */
3319     if (AOP_SIZE(left) == 1 &&
3320         AOP_SIZE(right) == 1 ) {
3321         genDivOneByte(left,right,result);
3322         goto release ;
3323     }
3324
3325     /* should have been converted to function call */
3326     assert(0);
3327 release :
3328     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3329     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3330     freeAsmop(result,NULL,ic,TRUE); 
3331 }
3332
3333 /*-----------------------------------------------------------------*/
3334 /* genModbits :- modulus of bits                                   */
3335 /*-----------------------------------------------------------------*/
3336 static void genModbits (operand *left, 
3337                         operand *right, 
3338                         operand *result)
3339 {
3340
3341     char *l;
3342
3343     /* the result must be bit */    
3344     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3345     l = aopGet(AOP(left),0,FALSE,FALSE);
3346
3347     MOVA(l);       
3348
3349     pic14_emitcode("div","ab");
3350     pic14_emitcode("mov","a,b");
3351     pic14_emitcode("rrc","a");
3352     aopPut(AOP(result),"c",0);
3353 }
3354
3355 /*-----------------------------------------------------------------*/
3356 /* genModOneByte : 8 bit modulus                                   */
3357 /*-----------------------------------------------------------------*/
3358 static void genModOneByte (operand *left,
3359                            operand *right,
3360                            operand *result)
3361 {
3362     sym_link *opetype = operandType(result);
3363     char *l ;
3364     symbol *lbl ;
3365
3366     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3367     /* signed or unsigned */
3368     if (SPEC_USIGN(opetype)) {
3369         /* unsigned is easy */
3370         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3371         l = aopGet(AOP(left),0,FALSE,FALSE);
3372         MOVA(l);    
3373         pic14_emitcode("div","ab");
3374         aopPut(AOP(result),"b",0);
3375         return ;
3376     }
3377
3378     /* signed is a little bit more difficult */
3379
3380     /* save the signs of the operands */
3381     l = aopGet(AOP(left),0,FALSE,FALSE);    
3382     MOVA(l);
3383
3384     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3385     pic14_emitcode("push","acc"); /* save it on the stack */
3386
3387     /* now sign adjust for both left & right */
3388     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3389     MOVA(l);
3390
3391     lbl = newiTempLabel(NULL);
3392     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3393     pic14_emitcode("cpl","a");   
3394     pic14_emitcode("inc","a");
3395     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3396     pic14_emitcode("mov","b,a"); 
3397
3398     /* sign adjust left side */
3399     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3400     MOVA(l);
3401
3402     lbl = newiTempLabel(NULL);
3403     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3404     pic14_emitcode("cpl","a");   
3405     pic14_emitcode("inc","a");
3406     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3407
3408     /* now the multiplication */
3409     pic14_emitcode("div","ab");
3410     /* we are interested in the lower order
3411     only */
3412     lbl = newiTempLabel(NULL);
3413     pic14_emitcode("pop","acc");   
3414     /* if there was an over flow we don't 
3415     adjust the sign of the result */
3416     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3417     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3418     CLRC ;
3419     pic14_emitcode("clr","a");
3420     pic14_emitcode("subb","a,b");
3421     pic14_emitcode("mov","b,a");
3422     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3423
3424     /* now we are done */
3425     aopPut(AOP(result),"b",0);
3426
3427 }
3428
3429 /*-----------------------------------------------------------------*/
3430 /* genMod - generates code for division                            */
3431 /*-----------------------------------------------------------------*/
3432 static void genMod (iCode *ic)
3433 {
3434     operand *left = IC_LEFT(ic);
3435     operand *right = IC_RIGHT(ic);
3436     operand *result= IC_RESULT(ic);  
3437
3438     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3439     /* assign the amsops */
3440     aopOp (left,ic,FALSE);
3441     aopOp (right,ic,FALSE);
3442     aopOp (result,ic,TRUE);
3443
3444     /* special cases first */
3445     /* both are bits */
3446     if (AOP_TYPE(left) == AOP_CRY &&
3447         AOP_TYPE(right)== AOP_CRY) {
3448         genModbits(left,right,result);
3449         goto release ;
3450     }
3451
3452     /* if both are of size == 1 */
3453     if (AOP_SIZE(left) == 1 &&
3454         AOP_SIZE(right) == 1 ) {
3455         genModOneByte(left,right,result);
3456         goto release ;
3457     }
3458
3459     /* should have been converted to function call */
3460     assert(0);
3461
3462 release :
3463     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3464     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3465     freeAsmop(result,NULL,ic,TRUE); 
3466 }
3467
3468 /*-----------------------------------------------------------------*/
3469 /* genIfxJump :- will create a jump depending on the ifx           */
3470 /*-----------------------------------------------------------------*/
3471 /*
3472   note: May need to add parameter to indicate when a variable is in bit space.
3473 */
3474 static void genIfxJump (iCode *ic, char *jval)
3475 {
3476
3477     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3478     /* if true label then we jump if condition
3479     supplied is true */
3480     if ( IC_TRUE(ic) ) {
3481
3482         if(strcmp(jval,"a") == 0)
3483           emitSKPZ;
3484         else if (strcmp(jval,"c") == 0)
3485           emitSKPC;
3486         else {
3487           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3488           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3489         }
3490
3491         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3492         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3493
3494     }
3495     else {
3496         /* false label is present */
3497         if(strcmp(jval,"a") == 0)
3498           emitSKPNZ;
3499         else if (strcmp(jval,"c") == 0)
3500           emitSKPNC;
3501         else {
3502           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3503           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3504         }
3505
3506         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3507         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3508
3509     }
3510
3511
3512     /* mark the icode as generated */
3513     ic->generated = 1;
3514 }
3515
3516 /*-----------------------------------------------------------------*/
3517 /* genSkip                                                         */
3518 /*-----------------------------------------------------------------*/
3519 static void genSkip(iCode *ifx,int status_bit)
3520 {
3521   if(!ifx)
3522     return;
3523
3524   if ( IC_TRUE(ifx) ) {
3525     switch(status_bit) {
3526     case 'z':
3527       emitSKPNZ;
3528       break;
3529
3530     case 'c':
3531       emitSKPNC;
3532       break;
3533
3534     case 'd':
3535       emitSKPDC;
3536       break;
3537
3538     }
3539
3540     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3541     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3542
3543   } else {
3544
3545     switch(status_bit) {
3546
3547     case 'z':
3548       emitSKPZ;
3549       break;
3550
3551     case 'c':
3552       emitSKPC;
3553       break;
3554
3555     case 'd':
3556       emitSKPDC;
3557       break;
3558     }
3559     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3560     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3561
3562   }
3563
3564 }
3565
3566 /*-----------------------------------------------------------------*/
3567 /* genSkipc                                                        */
3568 /*-----------------------------------------------------------------*/
3569 static void genSkipc(resolvedIfx *rifx)
3570 {
3571   if(!rifx)
3572     return;
3573
3574   if(rifx->condition)
3575     emitSKPC;
3576   else
3577     emitSKPNC;
3578
3579   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3580   rifx->generated = 1;
3581 }
3582
3583 /*-----------------------------------------------------------------*/
3584 /* genSkipz2                                                       */
3585 /*-----------------------------------------------------------------*/
3586 static void genSkipz2(resolvedIfx *rifx)
3587 {
3588   if(!rifx)
3589     return;
3590
3591   if(rifx->condition)
3592     emitSKPZ;
3593   else
3594     emitSKPNZ;
3595
3596   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3597   rifx->generated = 1;
3598 }
3599
3600 /*-----------------------------------------------------------------*/
3601 /* genSkipz                                                        */
3602 /*-----------------------------------------------------------------*/
3603 static void genSkipz(iCode *ifx, int condition)
3604 {
3605   if(!ifx)
3606     return;
3607
3608   if(condition)
3609     emitSKPNZ;
3610   else
3611     emitSKPZ;
3612
3613   if ( IC_TRUE(ifx) )
3614     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3615   else
3616     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3617
3618   if ( IC_TRUE(ifx) )
3619     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3620   else
3621     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3622
3623 }
3624 /*-----------------------------------------------------------------*/
3625 /* genSkipCond                                                     */
3626 /*-----------------------------------------------------------------*/
3627 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3628 {
3629   if(!rifx)
3630     return;
3631
3632   if(rifx->condition)
3633     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3634   else
3635     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3636
3637
3638   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3639   rifx->generated = 1;
3640 }
3641
3642 #if 0
3643 /*-----------------------------------------------------------------*/
3644 /* genChkZeroes :- greater or less than comparison                 */
3645 /*     For each byte in a literal that is zero, inclusive or the   */
3646 /*     the corresponding byte in the operand with W                */
3647 /*     returns true if any of the bytes are zero                   */
3648 /*-----------------------------------------------------------------*/
3649 static int genChkZeroes(operand *op, int lit,  int size)
3650 {
3651
3652   int i;
3653   int flag =1;
3654
3655   while(size--) {
3656     i = (lit >> (size*8)) & 0xff;
3657
3658     if(i==0) {
3659       if(flag) 
3660         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3661       else
3662         emitpcode(POC_IORFW, popGet(AOP(op),size));
3663       flag = 0;
3664     }
3665   }
3666
3667   return (flag==0);
3668 }
3669 #endif
3670
3671 /*-----------------------------------------------------------------*/
3672 /* genCmp :- greater or less than comparison                       */
3673 /*-----------------------------------------------------------------*/
3674 static void genCmp (operand *left,operand *right,
3675                     operand *result, iCode *ifx, int sign)
3676 {
3677   int size, offset = 0 ;
3678   unsigned long lit = 0L,i = 0;
3679   resolvedIfx rFalseIfx;
3680   //  resolvedIfx rTrueIfx;
3681   symbol *truelbl;
3682   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3683   if(ifx) {
3684   DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3685   DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3686   }
3687
3688
3689   resolveIfx(&rFalseIfx,ifx);
3690   truelbl  = newiTempLabel(NULL);
3691
3692   //if(IC_TRUE(ifx) == NULL)
3693   /* if left & right are bit variables */
3694   if (AOP_TYPE(left) == AOP_CRY &&
3695       AOP_TYPE(right) == AOP_CRY ) {
3696     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3697     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3698   } else {
3699     /* subtract right from left if at the
3700        end the carry flag is set then we know that
3701        left is greater than right */
3702     size = max(AOP_SIZE(left),AOP_SIZE(right));
3703
3704     /* if unsigned char cmp with lit, do cjne left,#right,zz */
3705     if((size == 1) && !sign &&
3706        (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3707       symbol *lbl  = newiTempLabel(NULL);
3708       pic14_emitcode("cjne","%s,%s,%05d_DS_",
3709                aopGet(AOP(left),offset,FALSE,FALSE),
3710                aopGet(AOP(right),offset,FALSE,FALSE),
3711                lbl->key+100);
3712       pic14_emitcode("","%05d_DS_:",lbl->key+100);
3713     } else {
3714
3715       symbol *lbl  = newiTempLabel(NULL);
3716
3717       if(AOP_TYPE(right) == AOP_LIT) {
3718
3719         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3720
3721         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3722
3723         /* special cases */
3724
3725         if(lit == 0) {
3726
3727           if(sign != 0) 
3728             genSkipCond(&rFalseIfx,left,size-1,7);
3729           else 
3730             /* no need to compare to 0...*/
3731             /* NOTE: this is a de-generate compare that most certainly 
3732              *       creates some dead code. */
3733             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3734
3735           if(ifx) ifx->generated = 1;
3736           return;
3737
3738         }
3739         size--;
3740
3741         if(size == 0) {
3742           //i = (lit >> (size*8)) & 0xff;
3743           DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3744         
3745           emitpcode(POC_MOVFW, popGet(AOP(left),size));
3746
3747           i = ((0-lit) & 0xff);
3748           if(sign) {
3749             if( i == 0x81) { 
3750               /* lit is 0x7f, all signed chars are less than
3751                * this except for 0x7f itself */
3752               emitpcode(POC_XORLW, popGetLit(0x7f));
3753               genSkipz2(&rFalseIfx);
3754             } else {
3755               emitpcode(POC_ADDLW, popGetLit(0x80));
3756               emitpcode(POC_ADDLW, popGetLit(i^0x80));
3757               genSkipc(&rFalseIfx);
3758             }
3759
3760           } else {
3761             emitpcode(POC_ADDLW, popGetLit(i));
3762             genSkipc(&rFalseIfx);
3763
3764           }
3765
3766           if(ifx) ifx->generated = 1;
3767           return;
3768         }
3769
3770         /* chars are out of the way. now do ints and longs */
3771
3772
3773         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3774         
3775         /* special cases */
3776
3777         if(sign) {
3778
3779           if(lit == 0) {
3780             genSkipCond(&rFalseIfx,left,size,7);
3781             if(ifx) ifx->generated = 1;
3782             return;
3783           }
3784
3785           if(lit <0x100) {
3786             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3787
3788             //rFalseIfx.condition ^= 1;
3789             //genSkipCond(&rFalseIfx,left,size,7);
3790             //rFalseIfx.condition ^= 1;
3791
3792             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3793             if(rFalseIfx.condition)
3794               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3795             else
3796               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3797
3798             emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3799             emitpcode(POC_ADDFW, popGet(AOP(left),0));
3800             emitpcode(POC_MOVFW, popGet(AOP(left),1));
3801
3802             while(size > 1)
3803               emitpcode(POC_IORFW, popGet(AOP(left),size--));
3804
3805             if(rFalseIfx.condition) {
3806               emitSKPZ;
3807               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3808
3809             } else {
3810               emitSKPNZ;
3811             }
3812
3813             genSkipc(&rFalseIfx);
3814             emitpLabel(truelbl->key);
3815             if(ifx) ifx->generated = 1;
3816             return;
3817
3818           }
3819
3820           if(size == 1) {
3821
3822             if( (lit & 0xff) == 0) {
3823               /* lower byte is zero */
3824               DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3825               i = ((lit >> 8) & 0xff) ^0x80;
3826               emitpcode(POC_MOVFW, popGet(AOP(left),size));
3827               emitpcode(POC_ADDLW, popGetLit( 0x80));
3828               emitpcode(POC_ADDLW, popGetLit(0x100-i));
3829               genSkipc(&rFalseIfx);
3830
3831
3832               if(ifx) ifx->generated = 1;
3833               return;
3834
3835             }
3836           } else {
3837             /* Special cases for signed longs */
3838             if( (lit & 0xffffff) == 0) {
3839               /* lower byte is zero */
3840               DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3841               i = ((lit >> 8*3) & 0xff) ^0x80;
3842               emitpcode(POC_MOVFW, popGet(AOP(left),size));
3843               emitpcode(POC_ADDLW, popGetLit( 0x80));
3844               emitpcode(POC_ADDLW, popGetLit(0x100-i));
3845               genSkipc(&rFalseIfx);
3846
3847
3848               if(ifx) ifx->generated = 1;
3849               return;
3850
3851             }
3852
3853           }
3854
3855
3856           if(lit & (0x80 << (size*8))) {
3857             /* lit is negative */
3858             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3859
3860             //genSkipCond(&rFalseIfx,left,size,7);
3861
3862             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3863
3864             if(rFalseIfx.condition)
3865               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3866             else
3867               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3868
3869
3870           } else {
3871             /* lit is positive */
3872             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3873             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3874             if(rFalseIfx.condition)
3875               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3876             else
3877               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3878
3879             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3880             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3881             //rFalseIfx.condition ^= 1;
3882             //genSkipCond(&rFalseIfx,left,size,7);
3883             //rFalseIfx.condition ^= 1;
3884           }
3885
3886           /*
3887             This works, but is only good for ints.
3888             It also requires a "known zero" register.
3889             emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3890             emitpcode(POC_ADDFW, popGet(AOP(left),0));
3891             emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3892             emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3893             emitpcode(POC_ADDFW, popGet(AOP(left),1));
3894             genSkipc(&rFalseIfx);
3895
3896             emitpLabel(truelbl->key);
3897             if(ifx) ifx->generated = 1;
3898             return;
3899           **/
3900           
3901           /* There are no more special cases, so perform a general compare */
3902   
3903           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3904           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3905
3906           while(size--) {
3907
3908             emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3909             emitSKPNZ;
3910             emitpcode(POC_SUBFW, popGet(AOP(left),size));
3911           }
3912           //rFalseIfx.condition ^= 1;
3913           genSkipc(&rFalseIfx);
3914
3915           emitpLabel(truelbl->key);
3916
3917           if(ifx) ifx->generated = 1;
3918           return;
3919
3920
3921         }
3922
3923
3924         /* sign is out of the way. So now do an unsigned compare */
3925         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3926
3927
3928         //genChkZeroes(left)
3929
3930         /* General case - compare to an unsigned literal on the right.*/
3931
3932         i = (lit >> (size*8)) & 0xff;
3933         emitpcode(POC_MOVLW, popGetLit(i));
3934         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3935         while(size--) {
3936           i = (lit >> (size*8)) & 0xff;
3937
3938           if(i) {
3939             emitpcode(POC_MOVLW, popGetLit(i));
3940             emitSKPNZ;
3941             emitpcode(POC_SUBFW, popGet(AOP(left),size));
3942           } else {
3943             /* this byte of the lit is zero, 
3944              *if it's not the last then OR in the variable */
3945             if(size)
3946               emitpcode(POC_IORFW, popGet(AOP(left),size));
3947           }
3948         }
3949
3950
3951         emitpLabel(lbl->key);
3952         //if(emitFinalCheck)
3953           genSkipc(&rFalseIfx);
3954         if(sign)
3955           emitpLabel(truelbl->key);
3956
3957         if(ifx) ifx->generated = 1;
3958         return;
3959
3960
3961       }
3962
3963       if(AOP_TYPE(left) == AOP_LIT) {
3964         //symbol *lbl = newiTempLabel(NULL);
3965
3966         lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3967
3968
3969         DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3970
3971         /* Special cases */
3972         if((lit == 0) && (sign == 0)){
3973
3974           size--;
3975           emitpcode(POC_MOVFW, popGet(AOP(right),size));
3976           while(size) 
3977             emitpcode(POC_IORFW, popGet(AOP(right),--size));
3978
3979           //rFalseIfx.condition ^= 1;
3980           genSkipz2(&rFalseIfx);
3981           if(ifx) ifx->generated = 1;
3982           return;
3983         }
3984
3985         if(size==1) {
3986           /* Special cases */
3987           lit &= 0xff;
3988           if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3989             /* degenerate compare can never be true */
3990             if(rFalseIfx.condition == 0)
3991               emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3992
3993             if(ifx) ifx->generated = 1;
3994             return;
3995           }
3996
3997           if(sign) {
3998             if((lit+1)&0xff) {
3999               emitpcode(POC_MOVFW, popGet(AOP(right),0));
4000               emitpcode(POC_ADDLW, popGetLit(0x80));
4001               emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4002               rFalseIfx.condition ^= 1;
4003               genSkipc(&rFalseIfx);
4004             } else {
4005               rFalseIfx.condition ^= 1;
4006               genSkipCond(&rFalseIfx,right,0,7);
4007             }
4008             
4009           } else {
4010             if(lit & 0xff) {
4011               emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4012               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4013               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4014               rFalseIfx.condition ^= 1;
4015               genSkipc(&rFalseIfx);
4016             } else { 
4017               emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018               genSkipz2(&rFalseIfx);
4019             }
4020           }
4021
4022           if(ifx) ifx->generated = 1;
4023           return;
4024
4025         } else {
4026
4027           /* Size is greater than 1 */
4028
4029
4030
4031           if(sign) {
4032             int lp1 = lit+1;
4033
4034             size--;
4035
4036             if(lp1 == 0) {
4037               /* this means lit = 0xffffffff, or -1 */
4038
4039
4040               DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4041               rFalseIfx.condition ^= 1;
4042               genSkipCond(&rFalseIfx,right,size,7);
4043               if(ifx) ifx->generated = 1;
4044               return;
4045             }
4046
4047             if(lit == 0) {
4048               int s = size;
4049
4050               if(rFalseIfx.condition) {
4051                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4052                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4053               }
4054
4055               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4056               while(size--)
4057                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4058
4059
4060               emitSKPZ;
4061               if(rFalseIfx.condition) {
4062                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4063                 emitpLabel(truelbl->key);
4064               }else {
4065                 rFalseIfx.condition ^= 1;
4066                 genSkipCond(&rFalseIfx,right,s,7);
4067               }
4068
4069               if(ifx) ifx->generated = 1;
4070               return;
4071             }
4072
4073
4074             if(lit & (0x80 << (size*8))) {
4075               /* Lit is less than zero */
4076               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4077               //rFalseIfx.condition ^= 1;
4078               //genSkipCond(&rFalseIfx,left,size,7);
4079               //rFalseIfx.condition ^= 1;
4080               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4081               //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4082
4083               if(rFalseIfx.condition)
4084                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4085               else
4086                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4087
4088
4089             } else {
4090               /* Lit is greater than or equal to zero */
4091               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4092               //rFalseIfx.condition ^= 1;
4093               //genSkipCond(&rFalseIfx,right,size,7);
4094               //rFalseIfx.condition ^= 1;
4095
4096               //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4097               //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4098
4099               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4100               if(rFalseIfx.condition)
4101                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4102               else
4103                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4104
4105             }
4106             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4107             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4108
4109             while(size--) {
4110
4111               emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4112               emitSKPNZ;
4113               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4114             }
4115             rFalseIfx.condition ^= 1;
4116             //rFalseIfx.condition = 1;
4117             genSkipc(&rFalseIfx);
4118
4119             emitpLabel(truelbl->key);
4120
4121             if(ifx) ifx->generated = 1;
4122             return;
4123
4124           } else {
4125             /* Unsigned compare for sizes greater than 1 */
4126
4127             while(size--) {
4128               i = (lit >> (size*8)) & 0xff;
4129
4130
4131               if(size) {
4132                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4133                 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4134                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4135                 emitSKPZ;
4136                 emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4137               } else {
4138                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4139                 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4140                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4141
4142               }
4143             }
4144
4145             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4146
4147             emitpLabel(lbl->key);
4148
4149             rFalseIfx.condition ^= 1;
4150             genSkipc(&rFalseIfx);
4151
4152           }
4153         if(sign)
4154           emitpLabel(truelbl->key);
4155         if(ifx) ifx->generated = 1;
4156         return;
4157         }
4158       }
4159       /* Compare two variables */
4160
4161       DEBUGpic14_emitcode(";sign","%d",sign);
4162
4163       size--;
4164       if(sign) {
4165         /* Sigh. thus sucks... */
4166         if(size) {
4167           emitpcode(POC_MOVFW, popGet(AOP(left),size));
4168           emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4169           emitpcode(POC_MOVLW, popGetLit(0x80));
4170           emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4171           emitpcode(POC_XORFW, popGet(AOP(right),size));
4172           emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4173         } else {
4174           /* Signed char comparison */
4175           /* Special thanks to Nikolai Golovchenko for this snippet */
4176           emitpcode(POC_MOVFW, popGet(AOP(right),0));
4177           emitpcode(POC_SUBFW, popGet(AOP(left),0));
4178           emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4179           emitpcode(POC_XORFW, popGet(AOP(left),0));
4180           emitpcode(POC_XORFW, popGet(AOP(right),0));
4181           emitpcode(POC_ADDLW, popGetLit(0x80));
4182
4183           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4184           genSkipc(&rFalseIfx);
4185           
4186           if(ifx) ifx->generated = 1;
4187           return;
4188         }
4189
4190       } else {
4191
4192         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4193         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4194       }
4195
4196
4197       /* The rest of the bytes of a multi-byte compare */
4198       while (size) {
4199
4200         emitSKPZ;
4201         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4202         size--;
4203
4204         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4205         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4206
4207
4208       }
4209
4210       emitpLabel(lbl->key);
4211
4212       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4213       genSkipc(&rFalseIfx);
4214       if(ifx) ifx->generated = 1;
4215       return;
4216
4217     }
4218   }
4219
4220   //release:
4221   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4222     pic14_outBitC(result);
4223   } else {
4224     /* if the result is used in the next
4225        ifx conditional branch then generate
4226        code a little differently */
4227     if (ifx )
4228       genIfxJump (ifx,"c");
4229     else
4230       pic14_outBitC(result);
4231     /* leave the result in acc */
4232   }
4233
4234 }
4235
4236 /*-----------------------------------------------------------------*/
4237 /* genCmpGt :- greater than comparison                             */
4238 /*-----------------------------------------------------------------*/
4239 static void genCmpGt (iCode *ic, iCode *ifx)
4240 {
4241     operand *left, *right, *result;
4242     sym_link *letype , *retype;
4243     int sign ;
4244
4245     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4246     left = IC_LEFT(ic);
4247     right= IC_RIGHT(ic);
4248     result = IC_RESULT(ic);
4249
4250     letype = getSpec(operandType(left));
4251     retype =getSpec(operandType(right));
4252     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4253     /* assign the amsops */
4254     aopOp (left,ic,FALSE);
4255     aopOp (right,ic,FALSE);
4256     aopOp (result,ic,TRUE);
4257
4258     genCmp(right, left, result, ifx, sign);
4259
4260     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4261     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4262     freeAsmop(result,NULL,ic,TRUE); 
4263 }
4264
4265 /*-----------------------------------------------------------------*/
4266 /* genCmpLt - less than comparisons                                */
4267 /*-----------------------------------------------------------------*/
4268 static void genCmpLt (iCode *ic, iCode *ifx)
4269 {
4270     operand *left, *right, *result;
4271     sym_link *letype , *retype;
4272     int sign ;
4273
4274     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4275     left = IC_LEFT(ic);
4276     right= IC_RIGHT(ic);
4277     result = IC_RESULT(ic);
4278
4279     letype = getSpec(operandType(left));
4280     retype =getSpec(operandType(right));
4281     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4282
4283     /* assign the amsops */
4284     aopOp (left,ic,FALSE);
4285     aopOp (right,ic,FALSE);
4286     aopOp (result,ic,TRUE);
4287
4288     genCmp(left, right, result, ifx, sign);
4289
4290     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4291     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4292     freeAsmop(result,NULL,ic,TRUE); 
4293 }
4294
4295 /*-----------------------------------------------------------------*/
4296 /* genc16bit2lit - compare a 16 bit value to a literal             */
4297 /*-----------------------------------------------------------------*/
4298 static void genc16bit2lit(operand *op, int lit, int offset)
4299 {
4300   int i;
4301
4302   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4303   if( (lit&0xff) == 0) 
4304     i=1;
4305   else
4306     i=0;
4307
4308   switch( BYTEofLONG(lit,i)) { 
4309   case 0:
4310     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4311     break;
4312   case 1:
4313     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4314     break;
4315   case 0xff:
4316     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4317     break;
4318   default:
4319     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4320     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4321   }
4322
4323   i ^= 1;
4324
4325   switch( BYTEofLONG(lit,i)) { 
4326   case 0:
4327     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4328     break;
4329   case 1:
4330     emitSKPNZ;
4331     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4332     break;
4333   case 0xff:
4334     emitSKPNZ;
4335     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4336     break;
4337   default:
4338     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4339     emitSKPNZ;
4340     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4341
4342   }
4343
4344 }
4345
4346 /*-----------------------------------------------------------------*/
4347 /* gencjneshort - compare and jump if not equal                    */
4348 /*-----------------------------------------------------------------*/
4349 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4350 {
4351   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4352   int offset = 0;
4353   resolvedIfx rIfx;
4354   symbol *lbl;
4355
4356   unsigned long lit = 0L;
4357   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4358   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4359
4360   resolveIfx(&rIfx,ifx);
4361   lbl =  newiTempLabel(NULL);
4362
4363
4364   /* if the left side is a literal or 
4365      if the right is in a pointer register and left 
4366      is not */
4367   if ((AOP_TYPE(left) == AOP_LIT) || 
4368       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4369     operand *t = right;
4370     right = left;
4371     left = t;
4372   }
4373   if(AOP_TYPE(right) == AOP_LIT)
4374     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4375
4376   /* if the right side is a literal then anything goes */
4377   if (AOP_TYPE(right) == AOP_LIT &&
4378       AOP_TYPE(left) != AOP_DIR ) {
4379     switch(size) {
4380     case 2:
4381       genc16bit2lit(left, lit, 0);
4382       emitSKPNZ;
4383       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4384       break;
4385     default:
4386       while (size--) {
4387         if(lit & 0xff) {
4388           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4389           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4390         } else {
4391           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4392         }
4393
4394         emitSKPNZ;
4395         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4396         offset++;
4397         lit >>= 8;
4398       }
4399       break;
4400     }
4401   }
4402
4403   /* if the right side is in a register or in direct space or
4404      if the left is a pointer register & right is not */    
4405   else if (AOP_TYPE(right) == AOP_REG ||
4406            AOP_TYPE(right) == AOP_DIR || 
4407            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4408            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4409     switch(size) {
4410     case 2:
4411       genc16bit2lit(left, lit, 0);
4412       emitSKPNZ;
4413       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4414       break;
4415     default:
4416       while (size--) {
4417         int emit_skip=1;
4418         if((AOP_TYPE(left) == AOP_DIR) && 
4419            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4420
4421           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4422           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4423
4424         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4425             
4426           switch (lit & 0xff) {
4427           case 0:
4428             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4429             break;
4430           case 1:
4431             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4432             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4433             emit_skip=0;
4434             break;
4435           case 0xff:
4436             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4437             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4438             emit_skip=0;
4439             break;
4440           default:
4441             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4442             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4443           }
4444           lit >>= 8;
4445
4446         } else {
4447           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4448         }
4449         if(emit_skip) {
4450           if(AOP_TYPE(result) == AOP_CRY) {
4451             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4452             if(rIfx.condition)
4453               emitSKPNZ;
4454             else
4455               emitSKPZ;
4456             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4457           } else {
4458             /* fix me. probably need to check result size too */
4459             emitpcode(POC_CLRF,popGet(AOP(result),0));
4460             if(rIfx.condition)
4461               emitSKPNZ;
4462             else
4463               emitSKPZ;
4464             emitpcode(POC_INCF,popGet(AOP(result),0));
4465           }
4466           if(ifx)
4467             ifx->generated=1;
4468         }
4469         emit_skip++;
4470         offset++;
4471       }
4472       break;
4473     }
4474   } else if(AOP_TYPE(right) == AOP_REG &&
4475             AOP_TYPE(left) != AOP_DIR){
4476
4477     while(size--) {
4478       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4479       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4480       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4481       if(rIfx.condition)
4482         emitSKPNZ;
4483       else
4484         emitSKPZ;
4485       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4486       offset++;
4487     }
4488       
4489   }else{
4490     /* right is a pointer reg need both a & b */
4491     while(size--) {
4492       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4493       if(strcmp(l,"b"))
4494         pic14_emitcode("mov","b,%s",l);
4495       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4496       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4497       offset++;
4498     }
4499   }
4500   emitpLabel(lbl->key);
4501
4502   if(ifx)
4503     ifx->generated = 1;
4504 }
4505
4506 #if 0
4507 /*-----------------------------------------------------------------*/
4508 /* gencjne - compare and jump if not equal                         */
4509 /*-----------------------------------------------------------------*/
4510 static void gencjne(operand *left, operand *right, iCode *ifx)
4511 {
4512     symbol *tlbl  = newiTempLabel(NULL);
4513
4514     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4515     gencjneshort(left, right, lbl);
4516
4517     pic14_emitcode("mov","a,%s",one);
4518     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4519     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4520     pic14_emitcode("clr","a");
4521     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4522
4523     emitpLabel(lbl->key);
4524     emitpLabel(tlbl->key);
4525
4526 }
4527 #endif
4528
4529 /*-----------------------------------------------------------------*/
4530 /* genCmpEq - generates code for equal to                          */
4531 /*-----------------------------------------------------------------*/
4532 static void genCmpEq (iCode *ic, iCode *ifx)
4533 {
4534     operand *left, *right, *result;
4535     unsigned long lit = 0L;
4536     int size,offset=0;
4537
4538     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4539
4540     if(ifx)
4541       DEBUGpic14_emitcode ("; ifx is non-null","");
4542     else
4543       DEBUGpic14_emitcode ("; ifx is null","");
4544
4545     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4546     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4547     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4548
4549     size = max(AOP_SIZE(left),AOP_SIZE(right));
4550
4551     DEBUGpic14_AopType(__LINE__,left,right,result);
4552
4553     /* if literal, literal on the right or 
4554     if the right is in a pointer register and left 
4555     is not */
4556     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4557         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4558       operand *tmp = right ;
4559       right = left;
4560       left = tmp;
4561     }
4562
4563
4564     if(ifx && !AOP_SIZE(result)){
4565         symbol *tlbl;
4566         /* if they are both bit variables */
4567         if (AOP_TYPE(left) == AOP_CRY &&
4568             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4569             if(AOP_TYPE(right) == AOP_LIT){
4570                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4571                 if(lit == 0L){
4572                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4573                     pic14_emitcode("cpl","c");
4574                 } else if(lit == 1L) {
4575                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4576                 } else {
4577                     pic14_emitcode("clr","c");
4578                 }
4579                 /* AOP_TYPE(right) == AOP_CRY */
4580             } else {
4581                 symbol *lbl = newiTempLabel(NULL);
4582                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4583                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4584                 pic14_emitcode("cpl","c");
4585                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4586             }
4587             /* if true label then we jump if condition
4588             supplied is true */
4589             tlbl = newiTempLabel(NULL);
4590             if ( IC_TRUE(ifx) ) {
4591                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4592                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4593             } else {
4594                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4595                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4596             }
4597             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4598
4599             {
4600               /* left and right are both bit variables, result is carry */
4601               resolvedIfx rIfx;
4602               
4603               resolveIfx(&rIfx,ifx);
4604
4605               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4606               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4607               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4608               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4609               genSkipz2(&rIfx);
4610             }
4611         } else {
4612
4613           /* They're not both bit variables. Is the right a literal? */
4614           if(AOP_TYPE(right) == AOP_LIT) {
4615             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4616             
4617             switch(size) {
4618
4619             case 1:
4620               switch(lit & 0xff) {
4621               case 1:
4622                 if ( IC_TRUE(ifx) ) {
4623                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4624                   emitSKPNZ;
4625                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4626                 } else {
4627                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4628                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4629                 }
4630                 break;
4631               case 0xff:
4632                 if ( IC_TRUE(ifx) ) {
4633                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4634                   emitSKPNZ;
4635                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4636                 } else {
4637                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4638                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4639                 }
4640                 break;
4641               default:
4642                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4643                 if(lit)
4644                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4645                 genSkip(ifx,'z');
4646               }
4647
4648
4649               /* end of size == 1 */
4650               break;
4651               
4652             case 2:
4653               genc16bit2lit(left,lit,offset);
4654               genSkip(ifx,'z');
4655               break;
4656               /* end of size == 2 */
4657
4658             default:
4659               /* size is 4 */
4660               if(lit==0) {
4661                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4662                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4663                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4664                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4665
4666               } else {
4667
4668                 /* search for patterns that can be optimized */
4669
4670                 genc16bit2lit(left,lit,0);
4671                 lit >>= 16;
4672                 if(lit) {
4673                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4674                   //genSkip(ifx,'z');
4675                   genc16bit2lit(left,lit,2);
4676                 } else {
4677                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4678                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4679
4680                 }
4681                 
4682               }
4683
4684               genSkip(ifx,'z');
4685             }
4686           
4687             ifx->generated = 1;
4688             goto release ;
4689             
4690
4691           } else if(AOP_TYPE(right) == AOP_CRY ) {
4692             /* we know the left is not a bit, but that the right is */
4693             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4694             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4695                       popGet(AOP(right),offset));
4696             emitpcode(POC_XORLW,popGetLit(1));
4697
4698             /* if the two are equal, then W will be 0 and the Z bit is set
4699              * we could test Z now, or go ahead and check the high order bytes if
4700              * the variable we're comparing is larger than a byte. */
4701
4702             while(--size)
4703               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4704
4705             if ( IC_TRUE(ifx) ) {
4706               emitSKPNZ;
4707               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4708               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4709             } else {
4710               emitSKPZ;
4711               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4712               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4713             }
4714
4715           } else {
4716             /* They're both variables that are larger than bits */
4717             int s = size;
4718
4719             tlbl = newiTempLabel(NULL);
4720
4721             while(size--) {
4722               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4723               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4724
4725               if ( IC_TRUE(ifx) ) {
4726                 if(size) {
4727                   emitSKPZ;
4728                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4729                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4730                 } else {
4731                   emitSKPNZ;
4732                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4733                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4734                 }
4735               } else {
4736                 emitSKPZ;
4737                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4738                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4739               }
4740               offset++;
4741             }
4742             if(s>1 && IC_TRUE(ifx)) {
4743               emitpLabel(tlbl->key);
4744               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4745             }
4746           }
4747         }
4748         /* mark the icode as generated */
4749         ifx->generated = 1;
4750         goto release ;
4751     }
4752
4753     /* if they are both bit variables */
4754     if (AOP_TYPE(left) == AOP_CRY &&
4755         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4756         if(AOP_TYPE(right) == AOP_LIT){
4757             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4758             if(lit == 0L){
4759                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4760                 pic14_emitcode("cpl","c");
4761             } else if(lit == 1L) {
4762                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4763             } else {
4764                 pic14_emitcode("clr","c");
4765             }
4766             /* AOP_TYPE(right) == AOP_CRY */
4767         } else {
4768             symbol *lbl = newiTempLabel(NULL);
4769             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4770             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4771             pic14_emitcode("cpl","c");
4772             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4773         }
4774         /* c = 1 if egal */
4775         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4776             pic14_outBitC(result);
4777             goto release ;
4778         }
4779         if (ifx) {
4780             genIfxJump (ifx,"c");
4781             goto release ;
4782         }
4783         /* if the result is used in an arithmetic operation
4784         then put the result in place */
4785         pic14_outBitC(result);
4786     } else {
4787       
4788       gencjne(left,right,result,ifx);
4789 /*
4790       if(ifx) 
4791         gencjne(left,right,newiTempLabel(NULL));
4792       else {
4793         if(IC_TRUE(ifx)->key)
4794           gencjne(left,right,IC_TRUE(ifx)->key);
4795         else
4796           gencjne(left,right,IC_FALSE(ifx)->key);
4797         ifx->generated = 1;
4798         goto release ;
4799       }
4800       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4801         aopPut(AOP(result),"a",0);
4802         goto release ;
4803       }
4804
4805       if (ifx) {
4806         genIfxJump (ifx,"a");
4807         goto release ;
4808       }
4809 */
4810       /* if the result is used in an arithmetic operation
4811          then put the result in place */
4812 /*
4813       if (AOP_TYPE(result) != AOP_CRY) 
4814         pic14_outAcc(result);
4815 */
4816       /* leave the result in acc */
4817     }
4818
4819 release:
4820     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4821     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4822     freeAsmop(result,NULL,ic,TRUE);
4823 }
4824
4825 /*-----------------------------------------------------------------*/
4826 /* ifxForOp - returns the icode containing the ifx for operand     */
4827 /*-----------------------------------------------------------------*/
4828 static iCode *ifxForOp ( operand *op, iCode *ic )
4829 {
4830     /* if true symbol then needs to be assigned */
4831     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4832     if (IS_TRUE_SYMOP(op))
4833         return NULL ;
4834
4835     /* if this has register type condition and
4836     the next instruction is ifx with the same operand
4837     and live to of the operand is upto the ifx only then */
4838     if (ic->next &&
4839         ic->next->op == IFX &&
4840         IC_COND(ic->next)->key == op->key &&
4841         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4842         return ic->next;
4843
4844     if (ic->next &&
4845         ic->next->op == IFX &&
4846         IC_COND(ic->next)->key == op->key) {
4847       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4848       return ic->next;
4849     }
4850
4851     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4852     if (ic->next &&
4853         ic->next->op == IFX)
4854       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4855
4856     if (ic->next &&
4857         ic->next->op == IFX &&
4858         IC_COND(ic->next)->key == op->key) {
4859       DEBUGpic14_emitcode ("; "," key is okay");
4860       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4861                            OP_SYMBOL(op)->liveTo,
4862                            ic->next->seq);
4863     }
4864
4865
4866     return NULL;
4867 }
4868 /*-----------------------------------------------------------------*/
4869 /* genAndOp - for && operation                                     */
4870 /*-----------------------------------------------------------------*/
4871 static void genAndOp (iCode *ic)
4872 {
4873     operand *left,*right, *result;
4874     symbol *tlbl;
4875
4876     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4877     /* note here that && operations that are in an
4878     if statement are taken away by backPatchLabels
4879     only those used in arthmetic operations remain */
4880     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4881     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4882     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4883
4884     /* if both are bit variables */
4885     if (AOP_TYPE(left) == AOP_CRY &&
4886         AOP_TYPE(right) == AOP_CRY ) {
4887         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4888         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4889         pic14_outBitC(result);
4890     } else {
4891         tlbl = newiTempLabel(NULL);
4892         pic14_toBoolean(left);    
4893         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4894         pic14_toBoolean(right);
4895         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4896         pic14_outBitAcc(result);
4897     }
4898
4899     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4900     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4901     freeAsmop(result,NULL,ic,TRUE);
4902 }
4903
4904
4905 /*-----------------------------------------------------------------*/
4906 /* genOrOp - for || operation                                      */
4907 /*-----------------------------------------------------------------*/
4908 /*
4909   tsd pic port -
4910   modified this code, but it doesn't appear to ever get called
4911 */
4912
4913 static void genOrOp (iCode *ic)
4914 {
4915     operand *left,*right, *result;
4916     symbol *tlbl;
4917
4918     /* note here that || operations that are in an
4919     if statement are taken away by backPatchLabels
4920     only those used in arthmetic operations remain */
4921     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4922     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4923     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4924     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4925
4926     DEBUGpic14_AopType(__LINE__,left,right,result);
4927
4928     /* if both are bit variables */
4929     if (AOP_TYPE(left) == AOP_CRY &&
4930         AOP_TYPE(right) == AOP_CRY ) {
4931       pic14_emitcode("clrc","");
4932       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4933                AOP(left)->aopu.aop_dir,
4934                AOP(left)->aopu.aop_dir);
4935       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4936                AOP(right)->aopu.aop_dir,
4937                AOP(right)->aopu.aop_dir);
4938       pic14_emitcode("setc","");
4939
4940     } else {
4941         tlbl = newiTempLabel(NULL);
4942         pic14_toBoolean(left);
4943         emitSKPZ;
4944         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4945         pic14_toBoolean(right);
4946         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4947
4948         pic14_outBitAcc(result);
4949     }
4950
4951     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4952     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4953     freeAsmop(result,NULL,ic,TRUE);            
4954 }
4955
4956 /*-----------------------------------------------------------------*/
4957 /* isLiteralBit - test if lit == 2^n                               */
4958 /*-----------------------------------------------------------------*/
4959 static int isLiteralBit(unsigned long lit)
4960 {
4961     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4962     0x100L,0x200L,0x400L,0x800L,
4963     0x1000L,0x2000L,0x4000L,0x8000L,
4964     0x10000L,0x20000L,0x40000L,0x80000L,
4965     0x100000L,0x200000L,0x400000L,0x800000L,
4966     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4967     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4968     int idx;
4969     
4970     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4971     for(idx = 0; idx < 32; idx++)
4972         if(lit == pw[idx])
4973             return idx+1;
4974     return 0;
4975 }
4976
4977 /*-----------------------------------------------------------------*/
4978 /* continueIfTrue -                                                */
4979 /*-----------------------------------------------------------------*/
4980 static void continueIfTrue (iCode *ic)
4981 {
4982     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4983     if(IC_TRUE(ic))
4984         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4985     ic->generated = 1;
4986 }
4987
4988 /*-----------------------------------------------------------------*/
4989 /* jmpIfTrue -                                                     */
4990 /*-----------------------------------------------------------------*/
4991 static void jumpIfTrue (iCode *ic)
4992 {
4993     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4994     if(!IC_TRUE(ic))
4995         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4996     ic->generated = 1;
4997 }
4998
4999 /*-----------------------------------------------------------------*/
5000 /* jmpTrueOrFalse -                                                */
5001 /*-----------------------------------------------------------------*/
5002 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5003 {
5004     // ugly but optimized by peephole
5005     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5006     if(IC_TRUE(ic)){
5007         symbol *nlbl = newiTempLabel(NULL);
5008         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5009         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5010         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5011         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5012     }
5013     else{
5014         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5015         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5016     }
5017     ic->generated = 1;
5018 }
5019
5020 /*-----------------------------------------------------------------*/
5021 /* genAnd  - code for and                                          */
5022 /*-----------------------------------------------------------------*/
5023 static void genAnd (iCode *ic, iCode *ifx)
5024 {
5025   operand *left, *right, *result;
5026   int size, offset=0;  
5027   unsigned long lit = 0L;
5028   int bytelit = 0;
5029   resolvedIfx rIfx;
5030
5031
5032   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5033   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5034   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5035   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5036
5037   resolveIfx(&rIfx,ifx);
5038
5039   /* if left is a literal & right is not then exchange them */
5040   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5041       AOP_NEEDSACC(left)) {
5042     operand *tmp = right ;
5043     right = left;
5044     left = tmp;
5045   }
5046
5047   /* if result = right then exchange them */
5048   if(pic14_sameRegs(AOP(result),AOP(right))){
5049     operand *tmp = right ;
5050     right = left;
5051     left = tmp;
5052   }
5053
5054   /* if right is bit then exchange them */
5055   if (AOP_TYPE(right) == AOP_CRY &&
5056       AOP_TYPE(left) != AOP_CRY){
5057     operand *tmp = right ;
5058     right = left;
5059     left = tmp;
5060   }
5061   if(AOP_TYPE(right) == AOP_LIT)
5062     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5063
5064   size = AOP_SIZE(result);
5065
5066   DEBUGpic14_AopType(__LINE__,left,right,result);
5067
5068   // if(bit & yy)
5069   // result = bit & yy;
5070   if (AOP_TYPE(left) == AOP_CRY){
5071     // c = bit & literal;
5072     if(AOP_TYPE(right) == AOP_LIT){
5073       if(lit & 1) {
5074         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5075           // no change
5076           goto release;
5077         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5078       } else {
5079         // bit(result) = 0;
5080         if(size && (AOP_TYPE(result) == AOP_CRY)){
5081           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5082           goto release;
5083         }
5084         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5085           jumpIfTrue(ifx);
5086           goto release;
5087         }
5088         pic14_emitcode("clr","c");
5089       }
5090     } else {
5091       if (AOP_TYPE(right) == AOP_CRY){
5092         // c = bit & bit;
5093         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5094         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5095       } else {
5096         // c = bit & val;
5097         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5098         // c = lsb
5099         pic14_emitcode("rrc","a");
5100         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5101       }
5102     }
5103     // bit = c
5104     // val = c
5105     if(size)
5106       pic14_outBitC(result);
5107     // if(bit & ...)
5108     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5109       genIfxJump(ifx, "c");           
5110     goto release ;
5111   }
5112
5113   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5114   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5115   if((AOP_TYPE(right) == AOP_LIT) &&
5116      (AOP_TYPE(result) == AOP_CRY) &&
5117      (AOP_TYPE(left) != AOP_CRY)){
5118     int posbit = isLiteralBit(lit);
5119     /* left &  2^n */
5120     if(posbit){
5121       posbit--;
5122       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5123       // bit = left & 2^n
5124       if(size)
5125         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5126       // if(left &  2^n)
5127       else{
5128         if(ifx){
5129 /*
5130           if(IC_TRUE(ifx)) {
5131             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5132             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5133           } else {
5134             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5135             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5136           }
5137 */
5138           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5139                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5140           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5141           
5142           ifx->generated = 1;
5143         }
5144         goto release;
5145       }
5146     } else {
5147       symbol *tlbl = newiTempLabel(NULL);
5148       int sizel = AOP_SIZE(left);
5149       if(size)
5150         pic14_emitcode("setb","c");
5151       while(sizel--){
5152         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5153           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5154           // byte ==  2^n ?
5155           if((posbit = isLiteralBit(bytelit)) != 0)
5156             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5157           else{
5158             if(bytelit != 0x0FFL)
5159               pic14_emitcode("anl","a,%s",
5160                              aopGet(AOP(right),offset,FALSE,TRUE));
5161             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5162           }
5163         }
5164         offset++;
5165       }
5166       // bit = left & literal
5167       if(size){
5168         pic14_emitcode("clr","c");
5169         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5170       }
5171       // if(left & literal)
5172       else{
5173         if(ifx)
5174           jmpTrueOrFalse(ifx, tlbl);
5175         goto release ;
5176       }
5177     }
5178     pic14_outBitC(result);
5179     goto release ;
5180   }
5181
5182   /* if left is same as result */
5183   if(pic14_sameRegs(AOP(result),AOP(left))){
5184     int know_W = -1;
5185     for(;size--; offset++,lit>>=8) {
5186       if(AOP_TYPE(right) == AOP_LIT){
5187         switch(lit & 0xff) {
5188         case 0x00:
5189           /*  and'ing with 0 has clears the result */
5190           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5191           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5192           break;
5193         case 0xff:
5194           /* and'ing with 0xff is a nop when the result and left are the same */
5195           break;
5196
5197         default:
5198           {
5199             int p = my_powof2( (~lit) & 0xff );
5200             if(p>=0) {
5201               /* only one bit is set in the literal, so use a bcf instruction */
5202               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5203               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5204
5205             } else {
5206               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5207               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5208               if(know_W != (lit&0xff))
5209                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5210               know_W = lit &0xff;
5211               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5212             }
5213           }    
5214         }
5215       } else {
5216         if (AOP_TYPE(left) == AOP_ACC) {
5217           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5218         } else {                    
5219           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5220           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5221
5222         }
5223       }
5224     }
5225
5226   } else {
5227     // left & result in different registers
5228     if(AOP_TYPE(result) == AOP_CRY){
5229       // result = bit
5230       // if(size), result in bit
5231       // if(!size && ifx), conditional oper: if(left & right)
5232       symbol *tlbl = newiTempLabel(NULL);
5233       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5234       if(size)
5235         pic14_emitcode("setb","c");
5236       while(sizer--){
5237         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5238         pic14_emitcode("anl","a,%s",
5239                        aopGet(AOP(left),offset,FALSE,FALSE));
5240         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5241         offset++;
5242       }
5243       if(size){
5244         CLRC;
5245         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5246         pic14_outBitC(result);
5247       } else if(ifx)
5248         jmpTrueOrFalse(ifx, tlbl);
5249     } else {
5250       for(;(size--);offset++) {
5251         // normal case
5252         // result = left & right
5253         if(AOP_TYPE(right) == AOP_LIT){
5254           int t = (lit >> (offset*8)) & 0x0FFL;
5255           switch(t) { 
5256           case 0x00:
5257             pic14_emitcode("clrf","%s",
5258                            aopGet(AOP(result),offset,FALSE,FALSE));
5259             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5260             break;
5261           case 0xff:
5262             pic14_emitcode("movf","%s,w",
5263                            aopGet(AOP(left),offset,FALSE,FALSE));
5264             pic14_emitcode("movwf","%s",
5265                            aopGet(AOP(result),offset,FALSE,FALSE));
5266             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5267             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5268             break;
5269           default:
5270             pic14_emitcode("movlw","0x%x",t);
5271             pic14_emitcode("andwf","%s,w",
5272                            aopGet(AOP(left),offset,FALSE,FALSE));
5273             pic14_emitcode("movwf","%s",
5274                            aopGet(AOP(result),offset,FALSE,FALSE));
5275               
5276             emitpcode(POC_MOVLW, popGetLit(t));
5277             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5278             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5279           }
5280           continue;
5281         }
5282
5283         if (AOP_TYPE(left) == AOP_ACC) {
5284           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5285           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5286         } else {
5287           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5288           pic14_emitcode("andwf","%s,w",
5289                          aopGet(AOP(left),offset,FALSE,FALSE));
5290           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5291           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5292         }
5293         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5294         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5295       }
5296     }
5297   }
5298
5299   release :
5300     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5301   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5302   freeAsmop(result,NULL,ic,TRUE);     
5303 }
5304
5305 /*-----------------------------------------------------------------*/
5306 /* genOr  - code for or                                            */
5307 /*-----------------------------------------------------------------*/
5308 static void genOr (iCode *ic, iCode *ifx)
5309 {
5310     operand *left, *right, *result;
5311     int size, offset=0;
5312     unsigned long lit = 0L;
5313
5314     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5315
5316     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5317     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5318     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5319
5320     DEBUGpic14_AopType(__LINE__,left,right,result);
5321
5322     /* if left is a literal & right is not then exchange them */
5323     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5324         AOP_NEEDSACC(left)) {
5325         operand *tmp = right ;
5326         right = left;
5327         left = tmp;
5328     }
5329
5330     /* if result = right then exchange them */
5331     if(pic14_sameRegs(AOP(result),AOP(right))){
5332         operand *tmp = right ;
5333         right = left;
5334         left = tmp;
5335     }
5336
5337     /* if right is bit then exchange them */
5338     if (AOP_TYPE(right) == AOP_CRY &&
5339         AOP_TYPE(left) != AOP_CRY){
5340         operand *tmp = right ;
5341         right = left;
5342         left = tmp;
5343     }
5344
5345     DEBUGpic14_AopType(__LINE__,left,right,result);
5346
5347     if(AOP_TYPE(right) == AOP_LIT)
5348         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5349
5350     size = AOP_SIZE(result);
5351
5352     // if(bit | yy)
5353     // xx = bit | yy;
5354     if (AOP_TYPE(left) == AOP_CRY){
5355         if(AOP_TYPE(right) == AOP_LIT){
5356             // c = bit & literal;
5357             if(lit){
5358                 // lit != 0 => result = 1
5359                 if(AOP_TYPE(result) == AOP_CRY){
5360                   if(size)
5361                     emitpcode(POC_BSF, popGet(AOP(result),0));
5362                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5363                   //     AOP(result)->aopu.aop_dir,
5364                   //     AOP(result)->aopu.aop_dir);
5365                     else if(ifx)
5366                         continueIfTrue(ifx);
5367                     goto release;
5368                 }
5369             } else {
5370                 // lit == 0 => result = left
5371                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5372                     goto release;
5373                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5374             }
5375         } else {
5376             if (AOP_TYPE(right) == AOP_CRY){
5377               if(pic14_sameRegs(AOP(result),AOP(left))){
5378                 // c = bit | bit;
5379                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5380                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5381                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5382
5383                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5384                          AOP(result)->aopu.aop_dir,
5385                          AOP(result)->aopu.aop_dir);
5386                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5387                          AOP(right)->aopu.aop_dir,
5388                          AOP(right)->aopu.aop_dir);
5389                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5390                          AOP(result)->aopu.aop_dir,
5391                          AOP(result)->aopu.aop_dir);
5392               } else {
5393                 if( AOP_TYPE(result) == AOP_ACC) {
5394                   emitpcode(POC_MOVLW, popGetLit(0));
5395                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5396                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5397                   emitpcode(POC_MOVLW, popGetLit(1));
5398
5399                 } else {
5400
5401                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5402                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5403                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5404                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5405
5406                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5407                                  AOP(result)->aopu.aop_dir,
5408                                  AOP(result)->aopu.aop_dir);
5409                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5410                                  AOP(right)->aopu.aop_dir,
5411                                  AOP(right)->aopu.aop_dir);
5412                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5413                                  AOP(left)->aopu.aop_dir,
5414                                  AOP(left)->aopu.aop_dir);
5415                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5416                                  AOP(result)->aopu.aop_dir,
5417                                  AOP(result)->aopu.aop_dir);
5418                 }
5419               }
5420             } else {
5421                 // c = bit | val;
5422                 symbol *tlbl = newiTempLabel(NULL);
5423                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5424
5425
5426                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5427                 if( AOP_TYPE(right) == AOP_ACC) {
5428                   emitpcode(POC_IORLW, popGetLit(0));
5429                   emitSKPNZ;
5430                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5431                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5432                 }
5433
5434
5435
5436                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5437                     pic14_emitcode(";XXX setb","c");
5438                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5439                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5440                 pic14_toBoolean(right);
5441                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5442                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5443                     jmpTrueOrFalse(ifx, tlbl);
5444                     goto release;
5445                 } else {
5446                     CLRC;
5447                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5448                 }
5449             }
5450         }
5451         // bit = c
5452         // val = c
5453         if(size)
5454             pic14_outBitC(result);
5455         // if(bit | ...)
5456         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5457             genIfxJump(ifx, "c");           
5458         goto release ;
5459     }
5460
5461     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5462     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5463     if((AOP_TYPE(right) == AOP_LIT) &&
5464        (AOP_TYPE(result) == AOP_CRY) &&
5465        (AOP_TYPE(left) != AOP_CRY)){
5466         if(lit){
5467           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5468             // result = 1
5469             if(size)
5470                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5471             else 
5472                 continueIfTrue(ifx);
5473             goto release;
5474         } else {
5475           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5476             // lit = 0, result = boolean(left)
5477             if(size)
5478                 pic14_emitcode(";XXX setb","c");
5479             pic14_toBoolean(right);
5480             if(size){
5481                 symbol *tlbl = newiTempLabel(NULL);
5482                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5483                 CLRC;
5484                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5485             } else {
5486                 genIfxJump (ifx,"a");
5487                 goto release;
5488             }
5489         }
5490         pic14_outBitC(result);
5491         goto release ;
5492     }
5493
5494     /* if left is same as result */
5495     if(pic14_sameRegs(AOP(result),AOP(left))){
5496       int know_W = -1;
5497       for(;size--; offset++,lit>>=8) {
5498         if(AOP_TYPE(right) == AOP_LIT){
5499           if((lit & 0xff) == 0)
5500             /*  or'ing with 0 has no effect */
5501             continue;
5502           else {
5503             int p = my_powof2(lit & 0xff);
5504             if(p>=0) {
5505               /* only one bit is set in the literal, so use a bsf instruction */
5506               emitpcode(POC_BSF,
5507                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5508             } else {
5509               if(know_W != (lit & 0xff))
5510                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5511               know_W = lit & 0xff;
5512               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5513             }
5514                     
5515           }
5516         } else {
5517           if (AOP_TYPE(left) == AOP_ACC) {
5518             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5519             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5520           } else {                  
5521             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5522             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5523
5524             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5525             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5526
5527           }
5528         }
5529       }
5530     } else {
5531         // left & result in different registers
5532         if(AOP_TYPE(result) == AOP_CRY){
5533             // result = bit
5534             // if(size), result in bit
5535             // if(!size && ifx), conditional oper: if(left | right)
5536             symbol *tlbl = newiTempLabel(NULL);
5537             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5538             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5539
5540
5541             if(size)
5542                 pic14_emitcode(";XXX setb","c");
5543             while(sizer--){
5544                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5545                 pic14_emitcode(";XXX orl","a,%s",
5546                          aopGet(AOP(left),offset,FALSE,FALSE));
5547                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5548                 offset++;
5549             }
5550             if(size){
5551                 CLRC;
5552                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5553                 pic14_outBitC(result);
5554             } else if(ifx)
5555                 jmpTrueOrFalse(ifx, tlbl);
5556         } else for(;(size--);offset++){
5557           // normal case
5558           // result = left & right
5559           if(AOP_TYPE(right) == AOP_LIT){
5560             int t = (lit >> (offset*8)) & 0x0FFL;
5561             switch(t) { 
5562             case 0x00:
5563               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5564               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5565
5566               pic14_emitcode("movf","%s,w",
5567                        aopGet(AOP(left),offset,FALSE,FALSE));
5568               pic14_emitcode("movwf","%s",
5569                        aopGet(AOP(result),offset,FALSE,FALSE));
5570               break;
5571             default:
5572               emitpcode(POC_MOVLW,  popGetLit(t));
5573               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5574               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5575
5576               pic14_emitcode("movlw","0x%x",t);
5577               pic14_emitcode("iorwf","%s,w",
5578                        aopGet(AOP(left),offset,FALSE,FALSE));
5579               pic14_emitcode("movwf","%s",
5580                        aopGet(AOP(result),offset,FALSE,FALSE));
5581               
5582             }
5583             continue;
5584           }
5585
5586           // faster than result <- left, anl result,right
5587           // and better if result is SFR
5588           if (AOP_TYPE(left) == AOP_ACC) {
5589             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5590             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5591           } else {
5592             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5593             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5594
5595             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5596             pic14_emitcode("iorwf","%s,w",
5597                      aopGet(AOP(left),offset,FALSE,FALSE));
5598           }
5599           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5600           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5601         }
5602     }
5603
5604 release :
5605     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5606     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5607     freeAsmop(result,NULL,ic,TRUE);     
5608 }
5609
5610 /*-----------------------------------------------------------------*/
5611 /* genXor - code for xclusive or                                   */
5612 /*-----------------------------------------------------------------*/
5613 static void genXor (iCode *ic, iCode *ifx)
5614 {
5615   operand *left, *right, *result;
5616   int size, offset=0;
5617   unsigned long lit = 0L;
5618
5619   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5620
5621   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5622   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5623   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5624
5625   /* if left is a literal & right is not ||
5626      if left needs acc & right does not */
5627   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5628       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5629     operand *tmp = right ;
5630     right = left;
5631     left = tmp;
5632   }
5633
5634   /* if result = right then exchange them */
5635   if(pic14_sameRegs(AOP(result),AOP(right))){
5636     operand *tmp = right ;
5637     right = left;
5638     left = tmp;
5639   }
5640
5641   /* if right is bit then exchange them */
5642   if (AOP_TYPE(right) == AOP_CRY &&
5643       AOP_TYPE(left) != AOP_CRY){
5644     operand *tmp = right ;
5645     right = left;
5646     left = tmp;
5647   }
5648   if(AOP_TYPE(right) == AOP_LIT)
5649     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5650
5651   size = AOP_SIZE(result);
5652
5653   // if(bit ^ yy)
5654   // xx = bit ^ yy;
5655   if (AOP_TYPE(left) == AOP_CRY){
5656     if(AOP_TYPE(right) == AOP_LIT){
5657       // c = bit & literal;
5658       if(lit>>1){
5659         // lit>>1  != 0 => result = 1
5660         if(AOP_TYPE(result) == AOP_CRY){
5661           if(size)
5662             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5663             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5664           else if(ifx)
5665             continueIfTrue(ifx);
5666           goto release;
5667         }
5668         pic14_emitcode("setb","c");
5669       } else{
5670         // lit == (0 or 1)
5671         if(lit == 0){
5672           // lit == 0, result = left
5673           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5674             goto release;
5675           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5676         } else{
5677           // lit == 1, result = not(left)
5678           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5679             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5680             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5681             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5682             goto release;
5683           } else {
5684             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5685             pic14_emitcode("cpl","c");
5686           }
5687         }
5688       }
5689
5690     } else {
5691       // right != literal
5692       symbol *tlbl = newiTempLabel(NULL);
5693       if (AOP_TYPE(right) == AOP_CRY){
5694         // c = bit ^ bit;
5695         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5696       }
5697       else{
5698         int sizer = AOP_SIZE(right);
5699         // c = bit ^ val
5700         // if val>>1 != 0, result = 1
5701         pic14_emitcode("setb","c");
5702         while(sizer){
5703           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5704           if(sizer == 1)
5705             // test the msb of the lsb
5706             pic14_emitcode("anl","a,#0xfe");
5707           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5708           sizer--;
5709         }
5710         // val = (0,1)
5711         pic14_emitcode("rrc","a");
5712       }
5713       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5714       pic14_emitcode("cpl","c");
5715       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5716     }
5717     // bit = c
5718     // val = c
5719     if(size)
5720       pic14_outBitC(result);
5721     // if(bit | ...)
5722     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5723       genIfxJump(ifx, "c");           
5724     goto release ;
5725   }
5726
5727   if(pic14_sameRegs(AOP(result),AOP(left))){
5728     /* if left is same as result */
5729     for(;size--; offset++) {
5730       if(AOP_TYPE(right) == AOP_LIT){
5731         int t  = (lit >> (offset*8)) & 0x0FFL;
5732         if(t == 0x00L)
5733           continue;
5734         else
5735           if (IS_AOP_PREG(left)) {
5736             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5737             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5738             aopPut(AOP(result),"a",offset);
5739           } else {
5740             emitpcode(POC_MOVLW, popGetLit(t));
5741             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5742             pic14_emitcode("xrl","%s,%s",
5743                            aopGet(AOP(left),offset,FALSE,TRUE),
5744                            aopGet(AOP(right),offset,FALSE,FALSE));
5745           }
5746       } else {
5747         if (AOP_TYPE(left) == AOP_ACC)
5748           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5749         else {
5750           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5751           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5752 /*
5753           if (IS_AOP_PREG(left)) {
5754             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5755             aopPut(AOP(result),"a",offset);
5756           } else
5757             pic14_emitcode("xrl","%s,a",
5758                            aopGet(AOP(left),offset,FALSE,TRUE));
5759 */
5760         }
5761       }
5762     }
5763   } else {
5764     // left & result in different registers
5765     if(AOP_TYPE(result) == AOP_CRY){
5766       // result = bit
5767       // if(size), result in bit
5768       // if(!size && ifx), conditional oper: if(left ^ right)
5769       symbol *tlbl = newiTempLabel(NULL);
5770       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5771       if(size)
5772         pic14_emitcode("setb","c");
5773       while(sizer--){
5774         if((AOP_TYPE(right) == AOP_LIT) &&
5775            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5776           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5777         } else {
5778           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5779           pic14_emitcode("xrl","a,%s",
5780                          aopGet(AOP(left),offset,FALSE,FALSE));
5781         }
5782         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5783         offset++;
5784       }
5785       if(size){
5786         CLRC;
5787         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5788         pic14_outBitC(result);
5789       } else if(ifx)
5790         jmpTrueOrFalse(ifx, tlbl);
5791     } else for(;(size--);offset++){
5792       // normal case
5793       // result = left & right
5794       if(AOP_TYPE(right) == AOP_LIT){
5795         int t = (lit >> (offset*8)) & 0x0FFL;
5796         switch(t) { 
5797         case 0x00:
5798           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5799           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5800           pic14_emitcode("movf","%s,w",
5801                          aopGet(AOP(left),offset,FALSE,FALSE));
5802           pic14_emitcode("movwf","%s",
5803                          aopGet(AOP(result),offset,FALSE,FALSE));
5804           break;
5805         case 0xff:
5806           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5807           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5808           pic14_emitcode("comf","%s,w",
5809                          aopGet(AOP(left),offset,FALSE,FALSE));
5810           pic14_emitcode("movwf","%s",
5811                          aopGet(AOP(result),offset,FALSE,FALSE));
5812           break;
5813         default:
5814           emitpcode(POC_MOVLW, popGetLit(t));
5815           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5816           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5817           pic14_emitcode("movlw","0x%x",t);
5818           pic14_emitcode("xorwf","%s,w",
5819                          aopGet(AOP(left),offset,FALSE,FALSE));
5820           pic14_emitcode("movwf","%s",
5821                          aopGet(AOP(result),offset,FALSE,FALSE));
5822
5823         }
5824         continue;
5825       }
5826
5827       // faster than result <- left, anl result,right
5828       // and better if result is SFR
5829       if (AOP_TYPE(left) == AOP_ACC) {
5830         emitpcode(POC_XORFW,popGet(AOP(right),offset));
5831         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5832       } else {
5833         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5834         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5835         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5836         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5837       }
5838       if ( AOP_TYPE(result) != AOP_ACC){
5839         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5840         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5841       }
5842     }
5843   }
5844
5845   release :
5846     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5847   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5848   freeAsmop(result,NULL,ic,TRUE);     
5849 }
5850
5851 /*-----------------------------------------------------------------*/
5852 /* genInline - write the inline code out                           */
5853 /*-----------------------------------------------------------------*/
5854 static void genInline (iCode *ic)
5855 {
5856     char *buffer, *bp, *bp1;
5857     
5858     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5859
5860     _G.inLine += (!options.asmpeep);
5861
5862     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5863     strcpy(buffer,IC_INLINE(ic));
5864
5865     /* emit each line as a code */
5866     while (*bp) {
5867         if (*bp == '\n') {
5868             *bp++ = '\0';
5869             pic14_emitcode(bp1,"");
5870             bp1 = bp;
5871         } else {
5872             if (*bp == ':') {
5873                 bp++;
5874                 *bp = '\0';
5875                 bp++;
5876                 pic14_emitcode(bp1,"");
5877                 bp1 = bp;
5878             } else
5879                 bp++;
5880         }
5881     }
5882     if (bp1 != bp)
5883         pic14_emitcode(bp1,"");
5884     /*     pic14_emitcode("",buffer); */
5885     _G.inLine -= (!options.asmpeep);
5886 }
5887
5888 /*-----------------------------------------------------------------*/
5889 /* genRRC - rotate right with carry                                */
5890 /*-----------------------------------------------------------------*/
5891 static void genRRC (iCode *ic)
5892 {
5893   operand *left , *result ;
5894   int size, offset = 0, same;
5895
5896   /* rotate right with carry */
5897   left = IC_LEFT(ic);
5898   result=IC_RESULT(ic);
5899   aopOp (left,ic,FALSE);
5900   aopOp (result,ic,FALSE);
5901
5902   DEBUGpic14_AopType(__LINE__,left,NULL,result);
5903
5904   same = pic14_sameRegs(AOP(result),AOP(left));
5905
5906   size = AOP_SIZE(result);    
5907
5908   /* get the lsb and put it into the carry */
5909   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5910
5911   offset = 0 ;
5912
5913   while(size--) {
5914
5915     if(same) {
5916       emitpcode(POC_RRF, popGet(AOP(left),offset));
5917     } else {
5918       emitpcode(POC_RRFW, popGet(AOP(left),offset));
5919       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5920     }
5921
5922     offset++;
5923   }
5924
5925   freeAsmop(left,NULL,ic,TRUE);
5926   freeAsmop(result,NULL,ic,TRUE);
5927 }
5928
5929 /*-----------------------------------------------------------------*/
5930 /* genRLC - generate code for rotate left with carry               */
5931 /*-----------------------------------------------------------------*/
5932 static void genRLC (iCode *ic)
5933 {    
5934   operand *left , *result ;
5935   int size, offset = 0;
5936   int same;
5937
5938   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5939   /* rotate right with carry */
5940   left = IC_LEFT(ic);
5941   result=IC_RESULT(ic);
5942   aopOp (left,ic,FALSE);
5943   aopOp (result,ic,FALSE);
5944
5945   DEBUGpic14_AopType(__LINE__,left,NULL,result);
5946
5947   same = pic14_sameRegs(AOP(result),AOP(left));
5948
5949   /* move it to the result */
5950   size = AOP_SIZE(result);    
5951
5952   /* get the msb and put it into the carry */
5953   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5954
5955   offset = 0 ;
5956
5957   while(size--) {
5958
5959     if(same) {
5960       emitpcode(POC_RLF, popGet(AOP(left),offset));
5961     } else {
5962       emitpcode(POC_RLFW, popGet(AOP(left),offset));
5963       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5964     }
5965
5966     offset++;
5967   }
5968
5969
5970   freeAsmop(left,NULL,ic,TRUE);
5971   freeAsmop(result,NULL,ic,TRUE);
5972 }
5973
5974 /*-----------------------------------------------------------------*/
5975 /* genGetHbit - generates code get highest order bit               */
5976 /*-----------------------------------------------------------------*/
5977 static void genGetHbit (iCode *ic)
5978 {
5979     operand *left, *result;
5980     left = IC_LEFT(ic);
5981     result=IC_RESULT(ic);
5982     aopOp (left,ic,FALSE);
5983     aopOp (result,ic,FALSE);
5984
5985     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5986     /* get the highest order byte into a */
5987     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5988     if(AOP_TYPE(result) == AOP_CRY){
5989         pic14_emitcode("rlc","a");
5990         pic14_outBitC(result);
5991     }
5992     else{
5993         pic14_emitcode("rl","a");
5994         pic14_emitcode("anl","a,#0x01");
5995         pic14_outAcc(result);
5996     }
5997
5998
5999     freeAsmop(left,NULL,ic,TRUE);
6000     freeAsmop(result,NULL,ic,TRUE);
6001 }
6002
6003 /*-----------------------------------------------------------------*/
6004 /* AccRol - rotate left accumulator by known count                 */
6005 /*-----------------------------------------------------------------*/
6006 static void AccRol (int shCount)
6007 {
6008     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6009     shCount &= 0x0007;              // shCount : 0..7
6010     switch(shCount){
6011         case 0 :
6012             break;
6013         case 1 :
6014             pic14_emitcode("rl","a");
6015             break;
6016         case 2 :
6017             pic14_emitcode("rl","a");
6018             pic14_emitcode("rl","a");
6019             break;
6020         case 3 :
6021             pic14_emitcode("swap","a");
6022             pic14_emitcode("rr","a");
6023             break;
6024         case 4 :
6025             pic14_emitcode("swap","a");
6026             break;
6027         case 5 :
6028             pic14_emitcode("swap","a");
6029             pic14_emitcode("rl","a");
6030             break;
6031         case 6 :
6032             pic14_emitcode("rr","a");
6033             pic14_emitcode("rr","a");
6034             break;
6035         case 7 :
6036             pic14_emitcode("rr","a");
6037             break;
6038     }
6039 }
6040
6041 /*-----------------------------------------------------------------*/
6042 /* AccLsh - left shift accumulator by known count                  */
6043 /*-----------------------------------------------------------------*/
6044 static void AccLsh (int shCount)
6045 {
6046     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6047     if(shCount != 0){
6048         if(shCount == 1)
6049             pic14_emitcode("add","a,acc");
6050         else 
6051             if(shCount == 2) {
6052             pic14_emitcode("add","a,acc");
6053             pic14_emitcode("add","a,acc");
6054         } else {
6055             /* rotate left accumulator */
6056             AccRol(shCount);
6057             /* and kill the lower order bits */
6058             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6059         }
6060     }
6061 }
6062
6063 /*-----------------------------------------------------------------*/
6064 /* AccRsh - right shift accumulator by known count                 */
6065 /*-----------------------------------------------------------------*/
6066 static void AccRsh (int shCount)
6067 {
6068     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6069     if(shCount != 0){
6070         if(shCount == 1){
6071             CLRC;
6072             pic14_emitcode("rrc","a");
6073         } else {
6074             /* rotate right accumulator */
6075             AccRol(8 - shCount);
6076             /* and kill the higher order bits */
6077             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6078         }
6079     }
6080 }
6081
6082 #if 0
6083 /*-----------------------------------------------------------------*/
6084 /* AccSRsh - signed right shift accumulator by known count                 */
6085 /*-----------------------------------------------------------------*/
6086 static void AccSRsh (int shCount)
6087 {
6088     symbol *tlbl ;
6089     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6090     if(shCount != 0){
6091         if(shCount == 1){
6092             pic14_emitcode("mov","c,acc.7");
6093             pic14_emitcode("rrc","a");
6094         } else if(shCount == 2){
6095             pic14_emitcode("mov","c,acc.7");
6096             pic14_emitcode("rrc","a");
6097             pic14_emitcode("mov","c,acc.7");
6098             pic14_emitcode("rrc","a");
6099         } else {
6100             tlbl = newiTempLabel(NULL);
6101             /* rotate right accumulator */
6102             AccRol(8 - shCount);
6103             /* and kill the higher order bits */
6104             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6105             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6106             pic14_emitcode("orl","a,#0x%02x",
6107                      (unsigned char)~SRMask[shCount]);
6108             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6109         }
6110     }
6111 }
6112 #endif
6113 /*-----------------------------------------------------------------*/
6114 /* shiftR1Left2Result - shift right one byte from left to result   */
6115 /*-----------------------------------------------------------------*/
6116 static void shiftR1Left2ResultSigned (operand *left, int offl,
6117                                 operand *result, int offr,
6118                                 int shCount)
6119 {
6120   int same;
6121
6122   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6123
6124   same = (left == result) || (AOP(left) == AOP(result));
6125
6126   switch(shCount) {
6127   case 1:
6128     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6129     if(same) 
6130       emitpcode(POC_RRF, popGet(AOP(result),offr));
6131     else {
6132       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6133       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6134     }
6135
6136     break;
6137
6138   default:
6139     break;
6140   }
6141 }
6142
6143 /*-----------------------------------------------------------------*/
6144 /* shiftR1Left2Result - shift right one byte from left to result   */
6145 /*-----------------------------------------------------------------*/
6146 static void shiftR1Left2Result (operand *left, int offl,
6147                                 operand *result, int offr,
6148                                 int shCount, int sign)
6149 {
6150   int same;
6151
6152   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6153
6154   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6155
6156   /* Copy the msb into the carry if signed. */
6157   if(sign) {
6158     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6159     return;
6160   }
6161
6162
6163
6164   switch(shCount) {
6165   case 1:
6166     emitCLRC;
6167     if(same) 
6168       emitpcode(POC_RRF, popGet(AOP(result),offr));
6169     else {
6170       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6171       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6172     }
6173     break;
6174   case 2:
6175     emitCLRC;
6176     if(same) {
6177       emitpcode(POC_RRF, popGet(AOP(result),offr));
6178     } else {
6179       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6180       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6181     }
6182     emitCLRC;
6183     emitpcode(POC_RRF, popGet(AOP(result),offr));
6184
6185     break;
6186   case 3:
6187     if(same) 
6188       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6189     else {
6190       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6191       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6192     }
6193
6194     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6195     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6196     emitpcode(POC_ANDLW, popGetLit(0x1f));
6197     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6198     break;
6199       
6200   case 4:
6201     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6202     emitpcode(POC_ANDLW, popGetLit(0x0f));
6203     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6204     break;
6205
6206   case 5:
6207     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6208     emitpcode(POC_ANDLW, popGetLit(0x0f));
6209     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6210     emitCLRC;
6211     emitpcode(POC_RRF, popGet(AOP(result),offr));
6212
6213     break;
6214   case 6:
6215
6216     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6217     emitpcode(POC_ANDLW, popGetLit(0x80));
6218     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6219     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6220     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6221     break;
6222
6223   case 7:
6224
6225     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6226     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6227     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6228
6229     break;
6230
6231   default:
6232     break;
6233   }
6234
6235
6236 #if 0
6237     
6238   MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6239
6240   /* shift right accumulator */
6241   if(sign)
6242     AccSRsh(shCount);
6243   else
6244     AccRsh(shCount);
6245   aopPut(AOP(result),"a",offr);
6246 #endif
6247 }
6248
6249 /*-----------------------------------------------------------------*/
6250 /* shiftL1Left2Result - shift left one byte from left to result    */
6251 /*-----------------------------------------------------------------*/
6252 static void shiftL1Left2Result (operand *left, int offl,
6253                                 operand *result, int offr, int shCount)
6254 {
6255   int same;
6256
6257   //    char *l;
6258   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6259
6260   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6261   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6262     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6263     //    MOVA(l);
6264     /* shift left accumulator */
6265     //AccLsh(shCount); // don't comment out just yet...
6266   //    aopPut(AOP(result),"a",offr);
6267
6268   switch(shCount) {
6269   case 1:
6270     /* Shift left 1 bit position */
6271     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6272     if(same) {
6273       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6274     } else {
6275       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6276       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277     }
6278     break;
6279   case 2:
6280     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6281     emitpcode(POC_ANDLW,popGetLit(0x7e));
6282     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6283     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6284     break;
6285   case 3:
6286     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6287     emitpcode(POC_ANDLW,popGetLit(0x3e));
6288     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6289     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6290     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6291     break;
6292   case 4:
6293     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6294     emitpcode(POC_ANDLW, popGetLit(0xf0));
6295     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6296     break;
6297   case 5:
6298     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6299     emitpcode(POC_ANDLW, popGetLit(0xf0));
6300     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6301     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6302     break;
6303   case 6:
6304     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6305     emitpcode(POC_ANDLW, popGetLit(0x30));
6306     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6307     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6308     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6309     break;
6310   case 7:
6311     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6312     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6313     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6314     break;
6315
6316   default:
6317     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6318   }
6319
6320 }
6321
6322 /*-----------------------------------------------------------------*/
6323 /* movLeft2Result - move byte from left to result                  */
6324 /*-----------------------------------------------------------------*/
6325 static void movLeft2Result (operand *left, int offl,
6326                             operand *result, int offr, int sign)
6327 {
6328     char *l;
6329     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6330     if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6331         l = aopGet(AOP(left),offl,FALSE,FALSE);
6332
6333         if (*l == '@' && (IS_AOP_PREG(result))) {
6334             pic14_emitcode("mov","a,%s",l);
6335             aopPut(AOP(result),"a",offr);
6336         } else {
6337           if(!sign) {
6338             emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6339             emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6340
6341             //aopPut(AOP(result),l,offr);
6342           }else{
6343                 /* MSB sign in acc.7 ! */
6344                 if(pic14_getDataSize(left) == offl+1){
6345                     pic14_emitcode("mov","a,%s",l);
6346                     aopPut(AOP(result),"a",offr);
6347                 }
6348             }
6349         }
6350     }
6351 }
6352
6353 /*-----------------------------------------------------------------*/
6354 /* shiftL2Left2Result - shift left two bytes from left to result   */
6355 /*-----------------------------------------------------------------*/
6356 static void shiftL2Left2Result (operand *left, int offl,
6357                                 operand *result, int offr, int shCount)
6358 {
6359
6360
6361   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6362
6363   if(pic14_sameRegs(AOP(result), AOP(left))) {
6364     switch(shCount) {
6365     case 0:
6366       break;
6367     case 1:
6368     case 2:
6369     case 3:
6370
6371       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6372       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6373       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6374
6375       while(--shCount) {
6376         emitCLRC;
6377         emitpcode(POC_RLF, popGet(AOP(result),offr));
6378         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6379       }
6380
6381       break;
6382     case 4:
6383     case 5:
6384       emitpcode(POC_MOVLW, popGetLit(0x0f));
6385       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6386       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6387       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6388       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6389       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6390       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6391       if(shCount >=5) {
6392         emitpcode(POC_RLF, popGet(AOP(result),offr));
6393         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6394       }
6395       break;
6396     case 6:
6397       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6398       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6399       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6400       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6401       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6402       emitpcode(POC_ANDLW,popGetLit(0xc0));
6403       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6404       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6405       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6406       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6407       break;
6408     case 7:
6409       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6410       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6411       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6412       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6413       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6414     }
6415
6416   } else {
6417     switch(shCount) {
6418     case 0:
6419       break;
6420     case 1:
6421     case 2:
6422     case 3:
6423       /* note, use a mov/add for the shift since the mov has a
6424          chance of getting optimized out */
6425       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6426       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6428       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6429       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6430
6431       while(--shCount) {
6432         emitCLRC;
6433         emitpcode(POC_RLF, popGet(AOP(result),offr));
6434         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6435       }
6436       break;
6437
6438     case 4:
6439     case 5:
6440       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6441       emitpcode(POC_ANDLW, popGetLit(0xF0));
6442       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6443       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6444       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445       emitpcode(POC_ANDLW, popGetLit(0xF0));
6446       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6447       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6448
6449
6450       if(shCount == 5) {
6451         emitpcode(POC_RLF, popGet(AOP(result),offr));
6452         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6453       }
6454       break;
6455     case 6:
6456       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6457       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6458       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6459       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6460
6461       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6462       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6463       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6464       emitpcode(POC_ANDLW,popGetLit(0xc0));
6465       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6466       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6467       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6468       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6469       break;
6470     case 7:
6471       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6472       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6473       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6474       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6475       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6476     }
6477   }
6478
6479 }
6480 /*-----------------------------------------------------------------*/
6481 /* shiftR2Left2Result - shift right two bytes from left to result  */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftR2Left2Result (operand *left, int offl,
6484                                 operand *result, int offr,
6485                                 int shCount, int sign)
6486 {
6487   int same=0;
6488
6489   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6490   same = pic14_sameRegs(AOP(result), AOP(left));
6491
6492   if(same && ((offl + MSB16) == offr)){
6493     same=1;
6494     /* don't crash result[offr] */
6495     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6496     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6497   } else {
6498     movLeft2Result(left,offl, result, offr, 0);
6499     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6500   }
6501   /* a:x >> shCount (x = lsb(result))*/
6502 /*
6503   if(sign)
6504     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6505   else {
6506     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6507 */
6508   switch(shCount) {
6509   case 0:
6510     break;
6511   case 1:
6512   case 2:
6513   case 3:
6514     emitCLRC;
6515     if(same) {
6516       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6517       emitpcode(POC_RRF,popGet(AOP(result),offr));
6518     } else {
6519
6520       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6521       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6522       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6523       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6524     }
6525
6526     while(--shCount) {
6527       emitCLRC;
6528       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6529       emitpcode(POC_RRF,popGet(AOP(result),offr));
6530     }
6531     break;
6532   case 4:
6533   case 5:
6534     if(same) {
6535
6536       emitpcode(POC_MOVLW, popGetLit(0xf0));
6537       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6538       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6539
6540       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6541       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6542       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6543       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6544     } else {
6545       emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6546       emitpcode(POC_ANDLW, popGetLit(0x0f));
6547       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6548
6549       emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6550       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6551       emitpcode(POC_ANDLW, popGetLit(0xf0));
6552       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6553       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6554     }
6555
6556     if(shCount >=5) {
6557       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6558       emitpcode(POC_RRF, popGet(AOP(result),offr));
6559     }
6560
6561     break;
6562
6563   case 6:
6564     if(same) {
6565
6566       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6567       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6568
6569       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6570       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6571       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6572       emitpcode(POC_ANDLW,popGetLit(0x03));
6573       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6574       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6575       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6576       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6577     } else {
6578       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6580       emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6581       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6582       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6583       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6584       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6585       emitpcode(POC_ANDLW,popGetLit(0x03));
6586       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6587     }
6588
6589     break;
6590   case 7:
6591     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6592     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6593     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6594     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6595     emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6596   }
6597 }
6598
6599
6600 /*-----------------------------------------------------------------*/
6601 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6602 /*-----------------------------------------------------------------*/
6603 static void shiftLLeftOrResult (operand *left, int offl,
6604                                 operand *result, int offr, int shCount)
6605 {
6606     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6607     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6608     /* shift left accumulator */
6609     AccLsh(shCount);
6610     /* or with result */
6611     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6612     /* back to result */
6613     aopPut(AOP(result),"a",offr);
6614 }
6615
6616 /*-----------------------------------------------------------------*/
6617 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6618 /*-----------------------------------------------------------------*/
6619 static void shiftRLeftOrResult (operand *left, int offl,
6620                                 operand *result, int offr, int shCount)
6621 {
6622     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6623     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6624     /* shift right accumulator */
6625     AccRsh(shCount);
6626     /* or with result */
6627     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6628     /* back to result */
6629     aopPut(AOP(result),"a",offr);
6630 }
6631
6632 /*-----------------------------------------------------------------*/
6633 /* genlshOne - left shift a one byte quantity by known count       */
6634 /*-----------------------------------------------------------------*/
6635 static void genlshOne (operand *result, operand *left, int shCount)
6636 {       
6637     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6638     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6639 }
6640
6641 /*-----------------------------------------------------------------*/
6642 /* genlshTwo - left shift two bytes by known amount != 0           */
6643 /*-----------------------------------------------------------------*/
6644 static void genlshTwo (operand *result,operand *left, int shCount)
6645 {
6646     int size;
6647     
6648     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6649     size = pic14_getDataSize(result);
6650
6651     /* if shCount >= 8 */
6652     if (shCount >= 8) {
6653         shCount -= 8 ;
6654
6655         if (size > 1){
6656             if (shCount)
6657                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6658             else 
6659                 movLeft2Result(left, LSB, result, MSB16, 0);
6660         }
6661         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6662     }
6663
6664     /*  1 <= shCount <= 7 */
6665     else {  
6666         if(size == 1)
6667             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6668         else 
6669             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6670     }
6671 }
6672
6673 /*-----------------------------------------------------------------*/
6674 /* shiftLLong - shift left one long from left to result            */
6675 /* offl = LSB or MSB16                                             */
6676 /*-----------------------------------------------------------------*/
6677 static void shiftLLong (operand *left, operand *result, int offr )
6678 {
6679     char *l;
6680     int size = AOP_SIZE(result);
6681
6682     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6683     if(size >= LSB+offr){
6684         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6685         MOVA(l);
6686         pic14_emitcode("add","a,acc");
6687         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6688             size >= MSB16+offr && offr != LSB )
6689             pic14_emitcode("xch","a,%s",
6690                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6691         else        
6692             aopPut(AOP(result),"a",LSB+offr);
6693     }
6694
6695     if(size >= MSB16+offr){
6696         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6697             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6698             MOVA(l);
6699         }
6700         pic14_emitcode("rlc","a");
6701         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6702             size >= MSB24+offr && offr != LSB)
6703             pic14_emitcode("xch","a,%s",
6704                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6705         else        
6706             aopPut(AOP(result),"a",MSB16+offr);
6707     }
6708
6709     if(size >= MSB24+offr){
6710         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6711             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6712             MOVA(l);
6713         }
6714         pic14_emitcode("rlc","a");
6715         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6716             size >= MSB32+offr && offr != LSB )
6717             pic14_emitcode("xch","a,%s",
6718                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6719         else        
6720             aopPut(AOP(result),"a",MSB24+offr);
6721     }
6722
6723     if(size > MSB32+offr){
6724         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6725             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6726             MOVA(l);    
6727         }
6728         pic14_emitcode("rlc","a");
6729         aopPut(AOP(result),"a",MSB32+offr);
6730     }
6731     if(offr != LSB)
6732         aopPut(AOP(result),zero,LSB);       
6733 }
6734
6735 /*-----------------------------------------------------------------*/
6736 /* genlshFour - shift four byte by a known amount != 0             */
6737 /*-----------------------------------------------------------------*/
6738 static void genlshFour (operand *result, operand *left, int shCount)
6739 {
6740     int size;
6741
6742     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6743     size = AOP_SIZE(result);
6744
6745     /* if shifting more that 3 bytes */
6746     if (shCount >= 24 ) {
6747         shCount -= 24;
6748         if (shCount)
6749             /* lowest order of left goes to the highest
6750             order of the destination */
6751             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6752         else
6753             movLeft2Result(left, LSB, result, MSB32, 0);
6754         aopPut(AOP(result),zero,LSB);
6755         aopPut(AOP(result),zero,MSB16);
6756         aopPut(AOP(result),zero,MSB32);
6757         return;
6758     }
6759
6760     /* more than two bytes */
6761     else if ( shCount >= 16 ) {
6762         /* lower order two bytes goes to higher order two bytes */
6763         shCount -= 16;
6764         /* if some more remaining */
6765         if (shCount)
6766             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6767         else {
6768             movLeft2Result(left, MSB16, result, MSB32, 0);
6769             movLeft2Result(left, LSB, result, MSB24, 0);
6770         }
6771         aopPut(AOP(result),zero,MSB16);
6772         aopPut(AOP(result),zero,LSB);
6773         return;
6774     }    
6775
6776     /* if more than 1 byte */
6777     else if ( shCount >= 8 ) {
6778         /* lower order three bytes goes to higher order  three bytes */
6779         shCount -= 8;
6780         if(size == 2){
6781             if(shCount)
6782                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6783             else
6784                 movLeft2Result(left, LSB, result, MSB16, 0);
6785         }
6786         else{   /* size = 4 */
6787             if(shCount == 0){
6788                 movLeft2Result(left, MSB24, result, MSB32, 0);
6789                 movLeft2Result(left, MSB16, result, MSB24, 0);
6790                 movLeft2Result(left, LSB, result, MSB16, 0);
6791                 aopPut(AOP(result),zero,LSB);
6792             }
6793             else if(shCount == 1)
6794                 shiftLLong(left, result, MSB16);
6795             else{
6796                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6797                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6798                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6799                 aopPut(AOP(result),zero,LSB);
6800             }
6801         }
6802     }
6803
6804     /* 1 <= shCount <= 7 */
6805     else if(shCount <= 2){
6806         shiftLLong(left, result, LSB);
6807         if(shCount == 2)
6808             shiftLLong(result, result, LSB);
6809     }
6810     /* 3 <= shCount <= 7, optimize */
6811     else{
6812         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6813         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6814         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6815     }
6816 }
6817
6818 /*-----------------------------------------------------------------*/
6819 /* genLeftShiftLiteral - left shifting by known count              */
6820 /*-----------------------------------------------------------------*/
6821 static void genLeftShiftLiteral (operand *left,
6822                                  operand *right,
6823                                  operand *result,
6824                                  iCode *ic)
6825 {    
6826     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6827     int size;
6828
6829     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6830     freeAsmop(right,NULL,ic,TRUE);
6831
6832     aopOp(left,ic,FALSE);
6833     aopOp(result,ic,FALSE);
6834
6835     size = getSize(operandType(result));
6836
6837 #if VIEW_SIZE
6838     pic14_emitcode("; shift left ","result %d, left %d",size,
6839              AOP_SIZE(left));
6840 #endif
6841
6842     /* I suppose that the left size >= result size */
6843     if(shCount == 0){
6844         while(size--){
6845             movLeft2Result(left, size, result, size, 0);
6846         }
6847     }
6848
6849     else if(shCount >= (size * 8))
6850         while(size--)
6851             aopPut(AOP(result),zero,size);
6852     else{
6853         switch (size) {
6854             case 1:
6855                 genlshOne (result,left,shCount);
6856                 break;
6857
6858             case 2:
6859             case 3:
6860                 genlshTwo (result,left,shCount);
6861                 break;
6862
6863             case 4:
6864                 genlshFour (result,left,shCount);
6865                 break;
6866         }
6867     }
6868     freeAsmop(left,NULL,ic,TRUE);
6869     freeAsmop(result,NULL,ic,TRUE);
6870 }
6871
6872 /*-----------------------------------------------------------------*
6873  * genMultiAsm - repeat assembly instruction for size of register.
6874  * if endian == 1, then the high byte (i.e base address + size of 
6875  * register) is used first else the low byte is used first;
6876  *-----------------------------------------------------------------*/
6877 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6878 {
6879
6880   int offset = 0;
6881
6882   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6883
6884   if(!reg)
6885     return;
6886
6887   if(!endian) {
6888     endian = 1;
6889   } else {
6890     endian = -1;
6891     offset = size-1;
6892   }
6893
6894   while(size--) {
6895     emitpcode(poc,    popGet(AOP(reg),offset));
6896     offset += endian;
6897   }
6898
6899 }
6900 /*-----------------------------------------------------------------*/
6901 /* genLeftShift - generates code for left shifting                 */
6902 /*-----------------------------------------------------------------*/
6903 static void genLeftShift (iCode *ic)
6904 {
6905     operand *left,*right, *result;
6906     int size, offset;
6907     char *l;
6908     symbol *tlbl , *tlbl1;
6909
6910     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6911
6912     right = IC_RIGHT(ic);
6913     left  = IC_LEFT(ic);
6914     result = IC_RESULT(ic);
6915
6916     aopOp(right,ic,FALSE);
6917
6918     /* if the shift count is known then do it 
6919     as efficiently as possible */
6920     if (AOP_TYPE(right) == AOP_LIT) {
6921         genLeftShiftLiteral (left,right,result,ic);
6922         return ;
6923     }
6924
6925     /* shift count is unknown then we have to form 
6926     a loop get the loop count in B : Note: we take
6927     only the lower order byte since shifting
6928     more that 32 bits make no sense anyway, ( the
6929     largest size of an object can be only 32 bits ) */  
6930
6931     
6932     aopOp(left,ic,FALSE);
6933     aopOp(result,ic,FALSE);
6934
6935     /* now move the left to the result if they are not the
6936     same */
6937     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6938         AOP_SIZE(result) > 1) {
6939
6940         size = AOP_SIZE(result);
6941         offset=0;
6942         while (size--) {
6943             l = aopGet(AOP(left),offset,FALSE,TRUE);
6944             if (*l == '@' && (IS_AOP_PREG(result))) {
6945
6946                 pic14_emitcode("mov","a,%s",l);
6947                 aopPut(AOP(result),"a",offset);
6948             } else
6949                 aopPut(AOP(result),l,offset);
6950             offset++;
6951         }
6952     }
6953
6954     size = AOP_SIZE(result);
6955
6956     /* if it is only one byte then */
6957     if (size == 1) {
6958       if(optimized_for_speed) {
6959         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6960         emitpcode(POC_ANDLW,  popGetLit(0xf0));
6961         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6962         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
6963         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
6964         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6965         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
6966         emitpcode(POC_RLFW,   popGet(AOP(result),0));
6967         emitpcode(POC_ANDLW,  popGetLit(0xfe));
6968         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
6969         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6970         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
6971       } else {
6972
6973         tlbl = newiTempLabel(NULL);
6974         if (!pic14_sameRegs(AOP(left),AOP(result))) {
6975           emitpcode(POC_MOVFW,  popGet(AOP(left),0));
6976           emitpcode(POC_MOVWF,  popGet(AOP(result),0));
6977         }
6978
6979         emitpcode(POC_COMFW,  popGet(AOP(right),0));
6980         emitpcode(POC_RRF,    popGet(AOP(result),0));
6981         emitpLabel(tlbl->key);
6982         emitpcode(POC_RLF,    popGet(AOP(result),0));
6983         emitpcode(POC_ADDLW,  popGetLit(1));
6984         emitSKPC;
6985         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6986       }
6987       goto release ;
6988     }
6989     
6990     if (pic14_sameRegs(AOP(left),AOP(result))) {
6991
6992       tlbl = newiTempLabel(NULL);
6993       emitpcode(POC_COMFW,  popGet(AOP(right),0));
6994       genMultiAsm(POC_RRF, result, size,1);
6995       emitpLabel(tlbl->key);
6996       genMultiAsm(POC_RLF, result, size,0);
6997       emitpcode(POC_ADDLW,  popGetLit(1));
6998       emitSKPC;
6999       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7000       goto release;
7001     }
7002
7003     tlbl = newiTempLabel(NULL);
7004     offset = 0 ;   
7005     tlbl1 = newiTempLabel(NULL);
7006
7007     reAdjustPreg(AOP(result));    
7008     
7009     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7010     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7011     l = aopGet(AOP(result),offset,FALSE,FALSE);
7012     MOVA(l);
7013     pic14_emitcode("add","a,acc");         
7014     aopPut(AOP(result),"a",offset++);
7015     while (--size) {
7016         l = aopGet(AOP(result),offset,FALSE,FALSE);
7017         MOVA(l);
7018         pic14_emitcode("rlc","a");         
7019         aopPut(AOP(result),"a",offset++);
7020     }
7021     reAdjustPreg(AOP(result));
7022
7023     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7024     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7025 release:
7026     freeAsmop (right,NULL,ic,TRUE);
7027     freeAsmop(left,NULL,ic,TRUE);
7028     freeAsmop(result,NULL,ic,TRUE);
7029 }
7030
7031 /*-----------------------------------------------------------------*/
7032 /* genrshOne - right shift a one byte quantity by known count      */
7033 /*-----------------------------------------------------------------*/
7034 static void genrshOne (operand *result, operand *left,
7035                        int shCount, int sign)
7036 {
7037     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7038     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7039 }
7040
7041 /*-----------------------------------------------------------------*/
7042 /* genrshTwo - right shift two bytes by known amount != 0          */
7043 /*-----------------------------------------------------------------*/
7044 static void genrshTwo (operand *result,operand *left,
7045                        int shCount, int sign)
7046 {
7047     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7048     /* if shCount >= 8 */
7049     if (shCount >= 8) {
7050         shCount -= 8 ;
7051         if (shCount)
7052             shiftR1Left2Result(left, MSB16, result, LSB,
7053                                shCount, sign);
7054         else 
7055             movLeft2Result(left, MSB16, result, LSB, sign);
7056         if(sign)
7057           addSign(result, MSB16, sign);
7058         else
7059           emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7060
7061     }
7062
7063     /*  1 <= shCount <= 7 */
7064     else
7065         shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7066 }
7067
7068 /*-----------------------------------------------------------------*/
7069 /* shiftRLong - shift right one long from left to result           */
7070 /* offl = LSB or MSB16                                             */
7071 /*-----------------------------------------------------------------*/
7072 static void shiftRLong (operand *left, int offl,
7073                         operand *result, int sign)
7074 {
7075     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7076     if(!sign)
7077         pic14_emitcode("clr","c");
7078     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7079     if(sign)
7080         pic14_emitcode("mov","c,acc.7");
7081     pic14_emitcode("rrc","a");
7082     aopPut(AOP(result),"a",MSB32-offl);
7083     if(offl == MSB16)
7084         /* add sign of "a" */
7085         addSign(result, MSB32, sign);
7086
7087     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7088     pic14_emitcode("rrc","a");
7089     aopPut(AOP(result),"a",MSB24-offl);
7090
7091     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7092     pic14_emitcode("rrc","a");
7093     aopPut(AOP(result),"a",MSB16-offl);
7094
7095     if(offl == LSB){
7096         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7097         pic14_emitcode("rrc","a");
7098         aopPut(AOP(result),"a",LSB);
7099     }
7100 }
7101
7102 /*-----------------------------------------------------------------*/
7103 /* genrshFour - shift four byte by a known amount != 0             */
7104 /*-----------------------------------------------------------------*/
7105 static void genrshFour (operand *result, operand *left,
7106                         int shCount, int sign)
7107 {
7108     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7109     /* if shifting more that 3 bytes */
7110     if(shCount >= 24 ) {
7111         shCount -= 24;
7112         if(shCount)
7113             shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7114         else
7115             movLeft2Result(left, MSB32, result, LSB, sign);
7116         addSign(result, MSB16, sign);
7117     }
7118     else if(shCount >= 16){
7119         shCount -= 16;
7120         if(shCount)
7121             shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7122         else{
7123             movLeft2Result(left, MSB24, result, LSB, 0);
7124             movLeft2Result(left, MSB32, result, MSB16, sign);
7125         }
7126         addSign(result, MSB24, sign);
7127     }
7128     else if(shCount >= 8){
7129         shCount -= 8;
7130         if(shCount == 1)
7131             shiftRLong(left, MSB16, result, sign);
7132         else if(shCount == 0){
7133             movLeft2Result(left, MSB16, result, LSB, 0);
7134             movLeft2Result(left, MSB24, result, MSB16, 0);
7135             movLeft2Result(left, MSB32, result, MSB24, sign);
7136             addSign(result, MSB32, sign);
7137         }
7138         else{
7139             shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7140             shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7141             /* the last shift is signed */
7142             shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7143             addSign(result, MSB32, sign);
7144         }
7145     }
7146     else{   /* 1 <= shCount <= 7 */
7147         if(shCount <= 2){
7148             shiftRLong(left, LSB, result, sign);
7149             if(shCount == 2)
7150                 shiftRLong(result, LSB, result, sign);
7151         }
7152         else{
7153             shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7154             shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7155             shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7156         }
7157     }
7158 }
7159
7160 /*-----------------------------------------------------------------*/
7161 /* genRightShiftLiteral - right shifting by known count            */
7162 /*-----------------------------------------------------------------*/
7163 static void genRightShiftLiteral (operand *left,
7164                                   operand *right,
7165                                   operand *result,
7166                                   iCode *ic,
7167                                   int sign)
7168 {    
7169     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7170     int size;
7171
7172     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7173     freeAsmop(right,NULL,ic,TRUE);
7174
7175     aopOp(left,ic,FALSE);
7176     aopOp(result,ic,FALSE);
7177
7178 #if VIEW_SIZE
7179     pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7180              AOP_SIZE(left));
7181 #endif
7182
7183     size = pic14_getDataSize(left);
7184     /* test the LEFT size !!! */
7185
7186     /* I suppose that the left size >= result size */
7187     if(shCount == 0){
7188         size = pic14_getDataSize(result);
7189         while(size--)
7190             movLeft2Result(left, size, result, size, 0);
7191     }
7192
7193     else if(shCount >= (size * 8)){
7194         if(sign)
7195             /* get sign in acc.7 */
7196             MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7197         addSign(result, LSB, sign);
7198     } else{
7199         switch (size) {
7200             case 1:
7201                 genrshOne (result,left,shCount,sign);
7202                 break;
7203
7204             case 2:
7205                 genrshTwo (result,left,shCount,sign);
7206                 break;
7207
7208             case 4:
7209                 genrshFour (result,left,shCount,sign);
7210                 break;
7211             default :
7212                 break;
7213         }
7214
7215         freeAsmop(left,NULL,ic,TRUE);
7216         freeAsmop(result,NULL,ic,TRUE);
7217     }
7218 }
7219
7220 /*-----------------------------------------------------------------*/
7221 /* genSignedRightShift - right shift of signed number              */
7222 /*-----------------------------------------------------------------*/
7223 static void genSignedRightShift (iCode *ic)
7224 {
7225     operand *right, *left, *result;
7226     int size, offset;
7227     char *l;
7228     symbol *tlbl, *tlbl1 ;
7229
7230     /* we do it the hard way put the shift count in b
7231     and loop thru preserving the sign */
7232     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7233
7234     right = IC_RIGHT(ic);
7235     left  = IC_LEFT(ic);
7236     result = IC_RESULT(ic);
7237
7238     aopOp(right,ic,FALSE);  
7239
7240
7241     if ( AOP_TYPE(right) == AOP_LIT) {
7242         genRightShiftLiteral (left,right,result,ic,1);
7243         return ;
7244     }
7245         /* shift count is unknown then we have to form 
7246        a loop get the loop count in B : Note: we take
7247        only the lower order byte since shifting
7248        more that 32 bits make no sense anyway, ( the
7249        largest size of an object can be only 32 bits ) */  
7250
7251     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7252     pic14_emitcode("inc","b");
7253     freeAsmop (right,NULL,ic,TRUE);
7254     aopOp(left,ic,FALSE);
7255     aopOp(result,ic,FALSE);
7256
7257     /* now move the left to the result if they are not the
7258     same */
7259     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7260         AOP_SIZE(result) > 1) {
7261
7262         size = AOP_SIZE(result);
7263         offset=0;
7264         while (size--) {
7265             l = aopGet(AOP(left),offset,FALSE,TRUE);
7266             if (*l == '@' && IS_AOP_PREG(result)) {
7267
7268                 pic14_emitcode("mov","a,%s",l);
7269                 aopPut(AOP(result),"a",offset);
7270             } else
7271                 aopPut(AOP(result),l,offset);
7272             offset++;
7273         }
7274     }
7275
7276     /* mov the highest order bit to OVR */    
7277     tlbl = newiTempLabel(NULL);
7278     tlbl1= newiTempLabel(NULL);
7279
7280     size = AOP_SIZE(result);
7281     offset = size - 1;
7282     pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7283     pic14_emitcode("rlc","a");
7284     pic14_emitcode("mov","ov,c");
7285     /* if it is only one byte then */
7286     if (size == 1) {
7287         l = aopGet(AOP(left),0,FALSE,FALSE);
7288         MOVA(l);
7289         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7290         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7291         pic14_emitcode("mov","c,ov");
7292         pic14_emitcode("rrc","a");
7293         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7294         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7295         aopPut(AOP(result),"a",0);
7296         goto release ;
7297     }
7298
7299     reAdjustPreg(AOP(result));
7300     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7301     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7302     pic14_emitcode("mov","c,ov");
7303     while (size--) {
7304         l = aopGet(AOP(result),offset,FALSE,FALSE);
7305         MOVA(l);
7306         pic14_emitcode("rrc","a");         
7307         aopPut(AOP(result),"a",offset--);
7308     }
7309     reAdjustPreg(AOP(result));
7310     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7311     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7312
7313 release:
7314     freeAsmop(left,NULL,ic,TRUE);
7315     freeAsmop(result,NULL,ic,TRUE);
7316 }
7317
7318 /*-----------------------------------------------------------------*/
7319 /* genRightShift - generate code for right shifting                */
7320 /*-----------------------------------------------------------------*/
7321 static void genRightShift (iCode *ic)
7322 {
7323     operand *right, *left, *result;
7324     sym_link *retype ;
7325     int size, offset;
7326     char *l;
7327     symbol *tlbl, *tlbl1 ;
7328
7329     /* if signed then we do it the hard way preserve the
7330     sign bit moving it inwards */
7331     retype = getSpec(operandType(IC_RESULT(ic)));
7332     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7333
7334     if (!SPEC_USIGN(retype)) {
7335         genSignedRightShift (ic);
7336         return ;
7337     }
7338
7339     /* signed & unsigned types are treated the same : i.e. the
7340     signed is NOT propagated inwards : quoting from the
7341     ANSI - standard : "for E1 >> E2, is equivalent to division
7342     by 2**E2 if unsigned or if it has a non-negative value,
7343     otherwise the result is implementation defined ", MY definition
7344     is that the sign does not get propagated */
7345
7346     right = IC_RIGHT(ic);
7347     left  = IC_LEFT(ic);
7348     result = IC_RESULT(ic);
7349
7350     aopOp(right,ic,FALSE);
7351
7352     /* if the shift count is known then do it 
7353     as efficiently as possible */
7354     if (AOP_TYPE(right) == AOP_LIT) {
7355         genRightShiftLiteral (left,right,result,ic, 0);
7356         return ;
7357     }
7358
7359     /* shift count is unknown then we have to form 
7360     a loop get the loop count in B : Note: we take
7361     only the lower order byte since shifting
7362     more that 32 bits make no sense anyway, ( the
7363     largest size of an object can be only 32 bits ) */  
7364
7365     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7366     pic14_emitcode("inc","b");
7367     aopOp(left,ic,FALSE);
7368     aopOp(result,ic,FALSE);
7369
7370     /* now move the left to the result if they are not the
7371     same */
7372     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7373         AOP_SIZE(result) > 1) {
7374
7375         size = AOP_SIZE(result);
7376         offset=0;
7377         while (size--) {
7378             l = aopGet(AOP(left),offset,FALSE,TRUE);
7379             if (*l == '@' && IS_AOP_PREG(result)) {
7380
7381                 pic14_emitcode("mov","a,%s",l);
7382                 aopPut(AOP(result),"a",offset);
7383             } else
7384                 aopPut(AOP(result),l,offset);
7385             offset++;
7386         }
7387     }
7388
7389     tlbl = newiTempLabel(NULL);
7390     tlbl1= newiTempLabel(NULL);
7391     size = AOP_SIZE(result);
7392     offset = size - 1;
7393
7394     /* if it is only one byte then */
7395     if (size == 1) {
7396 /*
7397         l = aopGet(AOP(left),0,FALSE,FALSE);
7398         MOVA(l);
7399         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7400         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7401         CLRC;
7402         pic14_emitcode("rrc","a");
7403         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7404         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7405         aopPut(AOP(result),"a",0);
7406 */
7407         tlbl = newiTempLabel(NULL);
7408         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7409           emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7410           emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7411         }
7412
7413         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7414         emitpcode(POC_RLF,    popGet(AOP(result),0));
7415         emitpLabel(tlbl->key);
7416         emitpcode(POC_RRF,    popGet(AOP(result),0));
7417         emitpcode(POC_ADDLW,  popGetLit(1));
7418         emitSKPC;
7419         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7420
7421         goto release ;
7422     }
7423
7424     reAdjustPreg(AOP(result));
7425     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7426     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7427     CLRC;
7428     while (size--) {
7429         l = aopGet(AOP(result),offset,FALSE,FALSE);
7430         MOVA(l);
7431         pic14_emitcode("rrc","a");         
7432         aopPut(AOP(result),"a",offset--);
7433     }
7434     reAdjustPreg(AOP(result));
7435
7436     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7437     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7438
7439 release:
7440     freeAsmop(left,NULL,ic,TRUE);
7441     freeAsmop (right,NULL,ic,TRUE);
7442     freeAsmop(result,NULL,ic,TRUE);
7443 }
7444
7445 /*-----------------------------------------------------------------*/
7446 /* genUnpackBits - generates code for unpacking bits               */
7447 /*-----------------------------------------------------------------*/
7448 static void genUnpackBits (operand *result, char *rname, int ptype)
7449 {    
7450     int shCnt ;
7451     int rlen = 0 ;
7452     sym_link *etype;
7453     int offset = 0 ;
7454
7455     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7456     etype = getSpec(operandType(result));
7457
7458     /* read the first byte  */
7459     switch (ptype) {
7460
7461     case POINTER:
7462     case IPOINTER:
7463         pic14_emitcode("mov","a,@%s",rname);
7464         break;
7465         
7466     case PPOINTER:
7467         pic14_emitcode("movx","a,@%s",rname);
7468         break;
7469         
7470     case FPOINTER:
7471         pic14_emitcode("movx","a,@dptr");
7472         break;
7473
7474     case CPOINTER:
7475         pic14_emitcode("clr","a");
7476         pic14_emitcode("movc","a","@a+dptr");
7477         break;
7478
7479     case GPOINTER:
7480         pic14_emitcode("lcall","__gptrget");
7481         break;
7482     }
7483
7484     /* if we have bitdisplacement then it fits   */
7485     /* into this byte completely or if length is */
7486     /* less than a byte                          */
7487     if ((shCnt = SPEC_BSTR(etype)) || 
7488         (SPEC_BLEN(etype) <= 8))  {
7489
7490         /* shift right acc */
7491         AccRsh(shCnt);
7492
7493         pic14_emitcode("anl","a,#0x%02x",
7494                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7495         aopPut(AOP(result),"a",offset);
7496         return ;
7497     }
7498
7499     /* bit field did not fit in a byte  */
7500     rlen = SPEC_BLEN(etype) - 8;
7501     aopPut(AOP(result),"a",offset++);
7502
7503     while (1)  {
7504
7505         switch (ptype) {
7506         case POINTER:
7507         case IPOINTER:
7508             pic14_emitcode("inc","%s",rname);
7509             pic14_emitcode("mov","a,@%s",rname);
7510             break;
7511             
7512         case PPOINTER:
7513             pic14_emitcode("inc","%s",rname);
7514             pic14_emitcode("movx","a,@%s",rname);
7515             break;
7516
7517         case FPOINTER:
7518             pic14_emitcode("inc","dptr");
7519             pic14_emitcode("movx","a,@dptr");
7520             break;
7521             
7522         case CPOINTER:
7523             pic14_emitcode("clr","a");
7524             pic14_emitcode("inc","dptr");
7525             pic14_emitcode("movc","a","@a+dptr");
7526             break;
7527             
7528         case GPOINTER:
7529             pic14_emitcode("inc","dptr");
7530             pic14_emitcode("lcall","__gptrget");
7531             break;
7532         }
7533
7534         rlen -= 8;            
7535         /* if we are done */
7536         if ( rlen <= 0 )
7537             break ;
7538         
7539         aopPut(AOP(result),"a",offset++);
7540                               
7541     }
7542     
7543     if (rlen) {
7544         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7545         aopPut(AOP(result),"a",offset);        
7546     }
7547     
7548     return ;
7549 }
7550
7551
7552 /*-----------------------------------------------------------------*/
7553 /* genDataPointerGet - generates code when ptr offset is known     */
7554 /*-----------------------------------------------------------------*/
7555 static void genDataPointerGet (operand *left, 
7556                                operand *result, 
7557                                iCode *ic)
7558 {
7559   int size , offset = 0;
7560
7561
7562   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7563
7564
7565   /* optimization - most of the time, left and result are the same
7566    * address, but different types. for the pic code, we could omit
7567    * the following
7568    */
7569
7570   aopOp(result,ic,TRUE);
7571
7572   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7573
7574   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7575
7576   size = AOP_SIZE(result);
7577
7578   while (size--) {
7579     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7580     offset++;
7581   }
7582
7583   freeAsmop(left,NULL,ic,TRUE);
7584   freeAsmop(result,NULL,ic,TRUE);
7585 }
7586
7587 /*-----------------------------------------------------------------*/
7588 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7589 /*-----------------------------------------------------------------*/
7590 static void genNearPointerGet (operand *left, 
7591                                operand *result, 
7592                                iCode *ic)
7593 {
7594     asmop *aop = NULL;
7595     regs *preg = NULL ;
7596     char *rname ;
7597     sym_link *rtype, *retype;
7598     sym_link *ltype = operandType(left);    
7599     char buffer[80];
7600
7601     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7602
7603     rtype = operandType(result);
7604     retype= getSpec(rtype);
7605     
7606     aopOp(left,ic,FALSE);
7607     
7608     /* if left is rematerialisable and
7609        result is not bit variable type and
7610        the left is pointer to data space i.e
7611        lower 128 bytes of space */
7612     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7613         !IS_BITVAR(retype)         &&
7614         DCL_TYPE(ltype) == POINTER) {
7615       //genDataPointerGet (left,result,ic);
7616         return ;
7617     }
7618     
7619     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7620
7621         /* if the value is already in a pointer register
7622        then don't need anything more */
7623     if (!AOP_INPREG(AOP(left))) {
7624         /* otherwise get a free pointer register */
7625     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7626         aop = newAsmop(0);
7627         preg = getFreePtr(ic,&aop,FALSE);
7628         pic14_emitcode("mov","%s,%s",
7629                 preg->name,
7630                 aopGet(AOP(left),0,FALSE,TRUE));
7631         rname = preg->name ;
7632     } else
7633         rname = aopGet(AOP(left),0,FALSE,FALSE);
7634     
7635     freeAsmop(left,NULL,ic,TRUE);
7636     aopOp (result,ic,FALSE);
7637     
7638       /* if bitfield then unpack the bits */
7639     if (IS_BITVAR(retype)) 
7640         genUnpackBits (result,rname,POINTER);
7641     else {
7642         /* we have can just get the values */
7643         int size = AOP_SIZE(result);
7644         int offset = 0 ;        
7645         
7646     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7647         while (size--) {
7648             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7649
7650                 pic14_emitcode("mov","a,@%s",rname);
7651                 aopPut(AOP(result),"a",offset);
7652             } else {
7653                 sprintf(buffer,"@%s",rname);
7654                 aopPut(AOP(result),buffer,offset);
7655             }
7656             offset++ ;
7657             if (size)
7658                 pic14_emitcode("inc","%s",rname);
7659         }
7660     }
7661
7662     /* now some housekeeping stuff */
7663     if (aop) {
7664         /* we had to allocate for this iCode */
7665     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7666         freeAsmop(NULL,aop,ic,TRUE);
7667     } else { 
7668         /* we did not allocate which means left
7669            already in a pointer register, then
7670            if size > 0 && this could be used again
7671            we have to point it back to where it 
7672            belongs */
7673     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7674         if (AOP_SIZE(result) > 1 &&
7675             !OP_SYMBOL(left)->remat &&
7676             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7677               ic->depth )) {
7678             int size = AOP_SIZE(result) - 1;
7679             while (size--)
7680                 pic14_emitcode("dec","%s",rname);
7681         }
7682     }
7683
7684     /* done */
7685     freeAsmop(result,NULL,ic,TRUE);
7686      
7687 }
7688
7689 /*-----------------------------------------------------------------*/
7690 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7691 /*-----------------------------------------------------------------*/
7692 static void genPagedPointerGet (operand *left, 
7693                                operand *result, 
7694                                iCode *ic)
7695 {
7696     asmop *aop = NULL;
7697     regs *preg = NULL ;
7698     char *rname ;
7699     sym_link *rtype, *retype;    
7700
7701     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7702
7703     rtype = operandType(result);
7704     retype= getSpec(rtype);
7705     
7706     aopOp(left,ic,FALSE);
7707
7708   /* if the value is already in a pointer register
7709        then don't need anything more */
7710     if (!AOP_INPREG(AOP(left))) {
7711         /* otherwise get a free pointer register */
7712         aop = newAsmop(0);
7713         preg = getFreePtr(ic,&aop,FALSE);
7714         pic14_emitcode("mov","%s,%s",
7715                 preg->name,
7716                 aopGet(AOP(left),0,FALSE,TRUE));
7717         rname = preg->name ;
7718     } else
7719         rname = aopGet(AOP(left),0,FALSE,FALSE);
7720     
7721     freeAsmop(left,NULL,ic,TRUE);
7722     aopOp (result,ic,FALSE);
7723
7724     /* if bitfield then unpack the bits */
7725     if (IS_BITVAR(retype)) 
7726         genUnpackBits (result,rname,PPOINTER);
7727     else {
7728         /* we have can just get the values */
7729         int size = AOP_SIZE(result);
7730         int offset = 0 ;        
7731         
7732         while (size--) {
7733             
7734             pic14_emitcode("movx","a,@%s",rname);
7735             aopPut(AOP(result),"a",offset);
7736             
7737             offset++ ;
7738             
7739             if (size)
7740                 pic14_emitcode("inc","%s",rname);
7741         }
7742     }
7743
7744     /* now some housekeeping stuff */
7745     if (aop) {
7746         /* we had to allocate for this iCode */
7747         freeAsmop(NULL,aop,ic,TRUE);
7748     } else { 
7749         /* we did not allocate which means left
7750            already in a pointer register, then
7751            if size > 0 && this could be used again
7752            we have to point it back to where it 
7753            belongs */
7754         if (AOP_SIZE(result) > 1 &&
7755             !OP_SYMBOL(left)->remat &&
7756             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7757               ic->depth )) {
7758             int size = AOP_SIZE(result) - 1;
7759             while (size--)
7760                 pic14_emitcode("dec","%s",rname);
7761         }
7762     }
7763
7764     /* done */
7765     freeAsmop(result,NULL,ic,TRUE);
7766     
7767         
7768 }
7769
7770 /*-----------------------------------------------------------------*/
7771 /* genFarPointerGet - gget value from far space                    */
7772 /*-----------------------------------------------------------------*/
7773 static void genFarPointerGet (operand *left,
7774                               operand *result, iCode *ic)
7775 {
7776     int size, offset ;
7777     sym_link *retype = getSpec(operandType(result));
7778
7779     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7780
7781     aopOp(left,ic,FALSE);
7782
7783     /* if the operand is already in dptr 
7784     then we do nothing else we move the value to dptr */
7785     if (AOP_TYPE(left) != AOP_STR) {
7786         /* if this is remateriazable */
7787         if (AOP_TYPE(left) == AOP_IMMD)
7788             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7789         else { /* we need to get it byte by byte */
7790             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7791             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7792             if (options.model == MODEL_FLAT24)
7793             {
7794                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7795             }
7796         }
7797     }
7798     /* so dptr know contains the address */
7799     freeAsmop(left,NULL,ic,TRUE);
7800     aopOp(result,ic,FALSE);
7801
7802     /* if bit then unpack */
7803     if (IS_BITVAR(retype)) 
7804         genUnpackBits(result,"dptr",FPOINTER);
7805     else {
7806         size = AOP_SIZE(result);
7807         offset = 0 ;
7808
7809         while (size--) {
7810             pic14_emitcode("movx","a,@dptr");
7811             aopPut(AOP(result),"a",offset++);
7812             if (size)
7813                 pic14_emitcode("inc","dptr");
7814         }
7815     }
7816
7817     freeAsmop(result,NULL,ic,TRUE);
7818 }
7819 #if 0
7820 /*-----------------------------------------------------------------*/
7821 /* genCodePointerGet - get value from code space                  */
7822 /*-----------------------------------------------------------------*/
7823 static void genCodePointerGet (operand *left,
7824                                 operand *result, iCode *ic)
7825 {
7826     int size, offset ;
7827     sym_link *retype = getSpec(operandType(result));
7828
7829     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7830
7831     aopOp(left,ic,FALSE);
7832
7833     /* if the operand is already in dptr 
7834     then we do nothing else we move the value to dptr */
7835     if (AOP_TYPE(left) != AOP_STR) {
7836         /* if this is remateriazable */
7837         if (AOP_TYPE(left) == AOP_IMMD)
7838             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7839         else { /* we need to get it byte by byte */
7840             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7841             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7842             if (options.model == MODEL_FLAT24)
7843             {
7844                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7845             }
7846         }
7847     }
7848     /* so dptr know contains the address */
7849     freeAsmop(left,NULL,ic,TRUE);
7850     aopOp(result,ic,FALSE);
7851
7852     /* if bit then unpack */
7853     if (IS_BITVAR(retype)) 
7854         genUnpackBits(result,"dptr",CPOINTER);
7855     else {
7856         size = AOP_SIZE(result);
7857         offset = 0 ;
7858
7859         while (size--) {
7860             pic14_emitcode("clr","a");
7861             pic14_emitcode("movc","a,@a+dptr");
7862             aopPut(AOP(result),"a",offset++);
7863             if (size)
7864                 pic14_emitcode("inc","dptr");
7865         }
7866     }
7867
7868     freeAsmop(result,NULL,ic,TRUE);
7869 }
7870 #endif
7871 /*-----------------------------------------------------------------*/
7872 /* genGenPointerGet - gget value from generic pointer space        */
7873 /*-----------------------------------------------------------------*/
7874 static void genGenPointerGet (operand *left,
7875                               operand *result, iCode *ic)
7876 {
7877   int size, offset ;
7878   sym_link *retype = getSpec(operandType(result));
7879
7880   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7881   aopOp(left,ic,FALSE);
7882   aopOp(result,ic,FALSE);
7883
7884
7885   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7886
7887   /* if the operand is already in dptr 
7888      then we do nothing else we move the value to dptr */
7889   //  if (AOP_TYPE(left) != AOP_STR) {
7890     /* if this is remateriazable */
7891     if (AOP_TYPE(left) == AOP_IMMD) {
7892       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7893       pic14_emitcode("mov","b,#%d",pointerCode(retype));
7894     }
7895     else { /* we need to get it byte by byte */
7896
7897       emitpcode(POC_MOVFW,popGet(AOP(left),0));
7898       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7899
7900       size = AOP_SIZE(result);
7901       offset = 0 ;
7902
7903       while(size--) {
7904         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7905         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7906         if(size)
7907           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7908       }
7909       goto release;
7910     }
7911     //}
7912   /* so dptr know contains the address */
7913
7914   /* if bit then unpack */
7915   //if (IS_BITVAR(retype)) 
7916   //  genUnpackBits(result,"dptr",GPOINTER);
7917
7918  release:
7919   freeAsmop(left,NULL,ic,TRUE);
7920   freeAsmop(result,NULL,ic,TRUE);
7921
7922 }
7923
7924 /*-----------------------------------------------------------------*/
7925 /* genConstPointerGet - get value from const generic pointer space */
7926 /*-----------------------------------------------------------------*/
7927 static void genConstPointerGet (operand *left,
7928                                 operand *result, iCode *ic)
7929 {
7930   //sym_link *retype = getSpec(operandType(result));
7931   symbol *albl = newiTempLabel(NULL);
7932   symbol *blbl = newiTempLabel(NULL);
7933   PIC_OPCODE poc;
7934
7935   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7936   aopOp(left,ic,FALSE);
7937   aopOp(result,ic,FALSE);
7938
7939
7940   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7941
7942   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
7943
7944   emitpcode(POC_CALL,popGetLabel(albl->key));
7945   emitpcode(POC_GOTO,popGetLabel(blbl->key));
7946   emitpLabel(albl->key);
7947
7948   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
7949     
7950   emitpcode(poc,popGet(AOP(left),1));
7951   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
7952   emitpcode(poc,popGet(AOP(left),0));
7953   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
7954
7955   emitpLabel(blbl->key);
7956
7957   emitpcode(POC_MOVWF,popGet(AOP(result),0));
7958
7959
7960   freeAsmop(left,NULL,ic,TRUE);
7961   freeAsmop(result,NULL,ic,TRUE);
7962
7963 }
7964 /*-----------------------------------------------------------------*/
7965 /* genPointerGet - generate code for pointer get                   */
7966 /*-----------------------------------------------------------------*/
7967 static void genPointerGet (iCode *ic)
7968 {
7969     operand *left, *result ;
7970     sym_link *type, *etype;
7971     int p_type;
7972
7973     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7974
7975     left = IC_LEFT(ic);
7976     result = IC_RESULT(ic) ;
7977
7978     /* depending on the type of pointer we need to
7979     move it to the correct pointer register */
7980     type = operandType(left);
7981     etype = getSpec(type);
7982
7983     if (IS_PTR_CONST(type))
7984       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
7985
7986     /* if left is of type of pointer then it is simple */
7987     if (IS_PTR(type) && !IS_FUNC(type->next)) 
7988         p_type = DCL_TYPE(type);
7989     else {
7990         /* we have to go by the storage class */
7991         p_type = PTR_TYPE(SPEC_OCLS(etype));
7992
7993         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
7994
7995         if (SPEC_OCLS(etype)->codesp ) {
7996           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
7997           //p_type = CPOINTER ; 
7998         }
7999         else
8000             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8001               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8002                /*p_type = FPOINTER ;*/ 
8003             else
8004                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8005                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8006 /*                  p_type = PPOINTER; */
8007                 else
8008                     if (SPEC_OCLS(etype) == idata )
8009                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8010 /*                      p_type = IPOINTER; */
8011                     else
8012                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8013 /*                      p_type = POINTER ; */
8014     }
8015
8016     /* now that we have the pointer type we assign
8017     the pointer values */
8018     switch (p_type) {
8019
8020     case POINTER:       
8021     case IPOINTER:
8022         genNearPointerGet (left,result,ic);
8023         break;
8024
8025     case PPOINTER:
8026         genPagedPointerGet(left,result,ic);
8027         break;
8028
8029     case FPOINTER:
8030         genFarPointerGet (left,result,ic);
8031         break;
8032
8033     case CPOINTER:
8034         genConstPointerGet (left,result,ic);
8035         //pic14_emitcodePointerGet (left,result,ic);
8036         break;
8037
8038     case GPOINTER:
8039       if (IS_PTR_CONST(type))
8040         genConstPointerGet (left,result,ic);
8041       else
8042         genGenPointerGet (left,result,ic);
8043       break;
8044     }
8045
8046 }
8047
8048 /*-----------------------------------------------------------------*/
8049 /* genPackBits - generates code for packed bit storage             */
8050 /*-----------------------------------------------------------------*/
8051 static void genPackBits (sym_link    *etype ,
8052                          operand *right ,
8053                          char *rname, int p_type)
8054 {
8055     int shCount = 0 ;
8056     int offset = 0  ;
8057     int rLen = 0 ;
8058     int blen, bstr ;   
8059     char *l ;
8060
8061     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8062     blen = SPEC_BLEN(etype);
8063     bstr = SPEC_BSTR(etype);
8064
8065     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8066     MOVA(l);   
8067
8068     /* if the bit lenth is less than or    */
8069     /* it exactly fits a byte then         */
8070     if (SPEC_BLEN(etype) <= 8 )  {
8071         shCount = SPEC_BSTR(etype) ;
8072
8073         /* shift left acc */
8074         AccLsh(shCount);
8075
8076         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8077
8078
8079             switch (p_type) {
8080                 case POINTER:
8081                     pic14_emitcode ("mov","b,a");
8082                     pic14_emitcode("mov","a,@%s",rname);
8083                     break;
8084
8085                 case FPOINTER:
8086                     pic14_emitcode ("mov","b,a");
8087                     pic14_emitcode("movx","a,@dptr");
8088                     break;
8089
8090                 case GPOINTER:
8091                     pic14_emitcode ("push","b");
8092                     pic14_emitcode ("push","acc");
8093                     pic14_emitcode ("lcall","__gptrget");
8094                     pic14_emitcode ("pop","b");
8095                     break;
8096             }
8097
8098             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8099                       ((unsigned char)(0xFF << (blen+bstr)) | 
8100                        (unsigned char)(0xFF >> (8-bstr)) ) );
8101             pic14_emitcode ("orl","a,b");
8102             if (p_type == GPOINTER)
8103                 pic14_emitcode("pop","b");
8104         }
8105     }
8106
8107     switch (p_type) {
8108         case POINTER:
8109             pic14_emitcode("mov","@%s,a",rname);
8110             break;
8111
8112         case FPOINTER:
8113             pic14_emitcode("movx","@dptr,a");
8114             break;
8115
8116         case GPOINTER:
8117             DEBUGpic14_emitcode(";lcall","__gptrput");
8118             break;
8119     }
8120
8121     /* if we r done */
8122     if ( SPEC_BLEN(etype) <= 8 )
8123         return ;
8124
8125     pic14_emitcode("inc","%s",rname);
8126     rLen = SPEC_BLEN(etype) ;     
8127
8128     /* now generate for lengths greater than one byte */
8129     while (1) {
8130
8131         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8132
8133         rLen -= 8 ;
8134         if (rLen <= 0 )
8135             break ;
8136
8137         switch (p_type) {
8138             case POINTER:
8139                 if (*l == '@') {
8140                     MOVA(l);
8141                     pic14_emitcode("mov","@%s,a",rname);
8142                 } else
8143                     pic14_emitcode("mov","@%s,%s",rname,l);
8144                 break;
8145
8146             case FPOINTER:
8147                 MOVA(l);
8148                 pic14_emitcode("movx","@dptr,a");
8149                 break;
8150
8151             case GPOINTER:
8152                 MOVA(l);
8153                 DEBUGpic14_emitcode(";lcall","__gptrput");
8154                 break;  
8155         }   
8156         pic14_emitcode ("inc","%s",rname);
8157     }
8158
8159     MOVA(l);
8160
8161     /* last last was not complete */
8162     if (rLen)   {
8163         /* save the byte & read byte */
8164         switch (p_type) {
8165             case POINTER:
8166                 pic14_emitcode ("mov","b,a");
8167                 pic14_emitcode("mov","a,@%s",rname);
8168                 break;
8169
8170             case FPOINTER:
8171                 pic14_emitcode ("mov","b,a");
8172                 pic14_emitcode("movx","a,@dptr");
8173                 break;
8174
8175             case GPOINTER:
8176                 pic14_emitcode ("push","b");
8177                 pic14_emitcode ("push","acc");
8178                 pic14_emitcode ("lcall","__gptrget");
8179                 pic14_emitcode ("pop","b");
8180                 break;
8181         }
8182
8183         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8184         pic14_emitcode ("orl","a,b");
8185     }
8186
8187     if (p_type == GPOINTER)
8188         pic14_emitcode("pop","b");
8189
8190     switch (p_type) {
8191
8192     case POINTER:
8193         pic14_emitcode("mov","@%s,a",rname);
8194         break;
8195         
8196     case FPOINTER:
8197         pic14_emitcode("movx","@dptr,a");
8198         break;
8199         
8200     case GPOINTER:
8201         DEBUGpic14_emitcode(";lcall","__gptrput");
8202         break;                  
8203     }
8204 }
8205 /*-----------------------------------------------------------------*/
8206 /* genDataPointerSet - remat pointer to data space                 */
8207 /*-----------------------------------------------------------------*/
8208 static void genDataPointerSet(operand *right,
8209                               operand *result,
8210                               iCode *ic)
8211 {
8212     int size, offset = 0 ;
8213     char *l, buffer[256];
8214
8215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8216     aopOp(right,ic,FALSE);
8217     
8218     l = aopGet(AOP(result),0,FALSE,TRUE);
8219     size = AOP_SIZE(right);
8220     if ( AOP_TYPE(result) == AOP_PCODE) {
8221       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8222               AOP(result)->aopu.pcop->name,
8223               PCOI(AOP(result)->aopu.pcop)->offset);
8224     }
8225
8226     // tsd, was l+1 - the underline `_' prefix was being stripped
8227     while (size--) {
8228       if (offset) {
8229         sprintf(buffer,"(%s + %d)",l,offset);
8230         fprintf(stderr,"oops  %s\n",buffer);
8231       } else
8232         sprintf(buffer,"%s",l);
8233
8234         if (AOP_TYPE(right) == AOP_LIT) {
8235           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8236           lit = lit >> (8*offset);
8237           if(lit&0xff) {
8238             pic14_emitcode("movlw","%d",lit);
8239             pic14_emitcode("movwf","%s",buffer);
8240
8241             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8242             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8243             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8244
8245           } else {
8246             pic14_emitcode("clrf","%s",buffer);
8247             //emitpcode(POC_CLRF, popRegFromString(buffer));
8248             emitpcode(POC_CLRF, popGet(AOP(result),0));
8249           }
8250         }else {
8251           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8252           pic14_emitcode("movwf","%s",buffer);
8253
8254           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8255           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8256           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8257
8258         }
8259
8260         offset++;
8261     }
8262
8263     freeAsmop(right,NULL,ic,TRUE);
8264     freeAsmop(result,NULL,ic,TRUE);
8265 }
8266
8267 /*-----------------------------------------------------------------*/
8268 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8269 /*-----------------------------------------------------------------*/
8270 static void genNearPointerSet (operand *right,
8271                                operand *result, 
8272                                iCode *ic)
8273 {
8274     asmop *aop = NULL;
8275     char *l;
8276     sym_link *retype;
8277     sym_link *ptype = operandType(result);
8278
8279     
8280     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8281     retype= getSpec(operandType(right));
8282
8283     aopOp(result,ic,FALSE);
8284     
8285     /* if the result is rematerializable &
8286        in data space & not a bit variable */
8287     //if (AOP_TYPE(result) == AOP_IMMD &&
8288     if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8289         DCL_TYPE(ptype) == POINTER   &&
8290         !IS_BITVAR(retype)) {
8291         genDataPointerSet (right,result,ic);
8292         return;
8293     }
8294
8295     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8296
8297     /* if the value is already in a pointer register
8298     then don't need anything more */
8299     if (!AOP_INPREG(AOP(result))) {
8300         /* otherwise get a free pointer register */
8301         //aop = newAsmop(0);
8302         //preg = getFreePtr(ic,&aop,FALSE);
8303         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8304         //pic14_emitcode("mov","%s,%s",
8305         //         preg->name,
8306         //         aopGet(AOP(result),0,FALSE,TRUE));
8307         //rname = preg->name ;
8308         pic14_emitcode("movwf","fsr");
8309     }// else
8310     //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8311
8312     freeAsmop(result,NULL,ic,TRUE);
8313     aopOp (right,ic,FALSE);
8314     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8315
8316     /* if bitfield then unpack the bits */
8317     if (IS_BITVAR(retype)) {
8318       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8319              "The programmer is obviously confused");
8320       //genPackBits (retype,right,rname,POINTER);
8321       exit(1);
8322     }
8323     else {
8324         /* we have can just get the values */
8325         int size = AOP_SIZE(right);
8326         int offset = 0 ;    
8327
8328     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8329         while (size--) {
8330             l = aopGet(AOP(right),offset,FALSE,TRUE);
8331             if (*l == '@' ) {
8332               //MOVA(l);
8333               //pic14_emitcode("mov","@%s,a",rname);
8334               pic14_emitcode("movf","indf,w ;1");
8335             } else {
8336
8337               if (AOP_TYPE(right) == AOP_LIT) {
8338                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8339                 if(lit) {
8340                   pic14_emitcode("movlw","%s",l);
8341                   pic14_emitcode("movwf","indf ;2");
8342                 } else 
8343                   pic14_emitcode("clrf","indf");
8344               }else {
8345                 pic14_emitcode("movf","%s,w",l);
8346                 pic14_emitcode("movwf","indf ;2");
8347               }
8348             //pic14_emitcode("mov","@%s,%s",rname,l);
8349             }
8350             if (size)
8351               pic14_emitcode("incf","fsr,f ;3");
8352             //pic14_emitcode("inc","%s",rname);
8353             offset++;
8354         }
8355     }
8356
8357     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8358     /* now some housekeeping stuff */
8359     if (aop) {
8360         /* we had to allocate for this iCode */
8361         freeAsmop(NULL,aop,ic,TRUE);
8362     } else { 
8363         /* we did not allocate which means left
8364         already in a pointer register, then
8365         if size > 0 && this could be used again
8366         we have to point it back to where it 
8367         belongs */
8368     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8369         if (AOP_SIZE(right) > 1 &&
8370             !OP_SYMBOL(result)->remat &&
8371             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8372               ic->depth )) {
8373             int size = AOP_SIZE(right) - 1;
8374             while (size--)
8375               pic14_emitcode("decf","fsr,f");
8376               //pic14_emitcode("dec","%s",rname);
8377         }
8378     }
8379
8380     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8381     /* done */
8382     freeAsmop(right,NULL,ic,TRUE);
8383
8384
8385 }
8386
8387 /*-----------------------------------------------------------------*/
8388 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8389 /*-----------------------------------------------------------------*/
8390 static void genPagedPointerSet (operand *right,
8391                                operand *result, 
8392                                iCode *ic)
8393 {
8394     asmop *aop = NULL;
8395     regs *preg = NULL ;
8396     char *rname , *l;
8397     sym_link *retype;
8398        
8399     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8400
8401     retype= getSpec(operandType(right));
8402     
8403     aopOp(result,ic,FALSE);
8404     
8405     /* if the value is already in a pointer register
8406        then don't need anything more */
8407     if (!AOP_INPREG(AOP(result))) {
8408         /* otherwise get a free pointer register */
8409         aop = newAsmop(0);
8410         preg = getFreePtr(ic,&aop,FALSE);
8411         pic14_emitcode("mov","%s,%s",
8412                 preg->name,
8413                 aopGet(AOP(result),0,FALSE,TRUE));
8414         rname = preg->name ;
8415     } else
8416         rname = aopGet(AOP(result),0,FALSE,FALSE);
8417     
8418     freeAsmop(result,NULL,ic,TRUE);
8419     aopOp (right,ic,FALSE);
8420
8421     /* if bitfield then unpack the bits */
8422     if (IS_BITVAR(retype)) 
8423         genPackBits (retype,right,rname,PPOINTER);
8424     else {
8425         /* we have can just get the values */
8426         int size = AOP_SIZE(right);
8427         int offset = 0 ;        
8428         
8429         while (size--) {
8430             l = aopGet(AOP(right),offset,FALSE,TRUE);
8431             
8432             MOVA(l);
8433             pic14_emitcode("movx","@%s,a",rname);
8434
8435             if (size)
8436                 pic14_emitcode("inc","%s",rname);
8437
8438             offset++;
8439         }
8440     }
8441     
8442     /* now some housekeeping stuff */
8443     if (aop) {
8444         /* we had to allocate for this iCode */
8445         freeAsmop(NULL,aop,ic,TRUE);
8446     } else { 
8447         /* we did not allocate which means left
8448            already in a pointer register, then
8449            if size > 0 && this could be used again
8450            we have to point it back to where it 
8451            belongs */
8452         if (AOP_SIZE(right) > 1 &&
8453             !OP_SYMBOL(result)->remat &&
8454             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8455               ic->depth )) {
8456             int size = AOP_SIZE(right) - 1;
8457             while (size--)
8458                 pic14_emitcode("dec","%s",rname);
8459         }
8460     }
8461
8462     /* done */
8463     freeAsmop(right,NULL,ic,TRUE);
8464     
8465         
8466 }
8467
8468 /*-----------------------------------------------------------------*/
8469 /* genFarPointerSet - set value from far space                     */
8470 /*-----------------------------------------------------------------*/
8471 static void genFarPointerSet (operand *right,
8472                               operand *result, iCode *ic)
8473 {
8474     int size, offset ;
8475     sym_link *retype = getSpec(operandType(right));
8476
8477     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8478     aopOp(result,ic,FALSE);
8479
8480     /* if the operand is already in dptr 
8481     then we do nothing else we move the value to dptr */
8482     if (AOP_TYPE(result) != AOP_STR) {
8483         /* if this is remateriazable */
8484         if (AOP_TYPE(result) == AOP_IMMD)
8485             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8486         else { /* we need to get it byte by byte */
8487             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8488             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8489             if (options.model == MODEL_FLAT24)
8490             {
8491                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8492             }
8493         }
8494     }
8495     /* so dptr know contains the address */
8496     freeAsmop(result,NULL,ic,TRUE);
8497     aopOp(right,ic,FALSE);
8498
8499     /* if bit then unpack */
8500     if (IS_BITVAR(retype)) 
8501         genPackBits(retype,right,"dptr",FPOINTER);
8502     else {
8503         size = AOP_SIZE(right);
8504         offset = 0 ;
8505
8506         while (size--) {
8507             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8508             MOVA(l);
8509             pic14_emitcode("movx","@dptr,a");
8510             if (size)
8511                 pic14_emitcode("inc","dptr");
8512         }
8513     }
8514
8515     freeAsmop(right,NULL,ic,TRUE);
8516 }
8517
8518 /*-----------------------------------------------------------------*/
8519 /* genGenPointerSet - set value from generic pointer space         */
8520 /*-----------------------------------------------------------------*/
8521 static void genGenPointerSet (operand *right,
8522                               operand *result, iCode *ic)
8523 {
8524   int size, offset ;
8525   sym_link *retype = getSpec(operandType(right));
8526
8527   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8528
8529   aopOp(result,ic,FALSE);
8530   aopOp(right,ic,FALSE);
8531   size = AOP_SIZE(right);
8532
8533   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8534
8535   /* if the operand is already in dptr 
8536      then we do nothing else we move the value to dptr */
8537   if (AOP_TYPE(result) != AOP_STR) {
8538     /* if this is remateriazable */
8539     if (AOP_TYPE(result) == AOP_IMMD) {
8540       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8541       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8542     }
8543     else { /* we need to get it byte by byte */
8544       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8545       size = AOP_SIZE(right);
8546       offset = 0 ;
8547
8548       /* hack hack! see if this the FSR. If so don't load W */
8549       if(AOP_TYPE(right) != AOP_ACC) {
8550
8551         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8552         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8553
8554         //if(size==2)
8555         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8556         //if(size==4) {
8557         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8558         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8559         //}
8560
8561         while(size--) {
8562           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8563           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8564           
8565           if(size)
8566             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8567         }
8568
8569
8570         goto release;
8571       } 
8572
8573       if(aopIdx(AOP(result),0) != 4) {
8574
8575         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8576         goto release;
8577       }
8578
8579       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8580       goto release;
8581
8582     }
8583   }
8584   /* so dptr know contains the address */
8585
8586
8587   /* if bit then unpack */
8588   if (IS_BITVAR(retype)) 
8589     genPackBits(retype,right,"dptr",GPOINTER);
8590   else {
8591     size = AOP_SIZE(right);
8592     offset = 0 ;
8593
8594     while (--size) {
8595       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8596       if(size)
8597         pic14_emitcode("incf","fsr,f");
8598       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8599       pic14_emitcode("movwf","indf");
8600       //MOVA(l);
8601       //DEBUGpic14_emitcode(";lcall","__gptrput");
8602       //if (size)
8603       //    pic14_emitcode("inc","dptr");
8604     }
8605   }
8606
8607  release:
8608   freeAsmop(right,NULL,ic,TRUE);
8609   freeAsmop(result,NULL,ic,TRUE);
8610 }
8611
8612 /*-----------------------------------------------------------------*/
8613 /* genPointerSet - stores the value into a pointer location        */
8614 /*-----------------------------------------------------------------*/
8615 static void genPointerSet (iCode *ic)
8616 {    
8617     operand *right, *result ;
8618     sym_link *type, *etype;
8619     int p_type;
8620
8621     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8622
8623     right = IC_RIGHT(ic);
8624     result = IC_RESULT(ic) ;
8625
8626     /* depending on the type of pointer we need to
8627     move it to the correct pointer register */
8628     type = operandType(result);
8629     etype = getSpec(type);
8630     /* if left is of type of pointer then it is simple */
8631     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8632         p_type = DCL_TYPE(type);
8633     }
8634     else {
8635         /* we have to go by the storage class */
8636         p_type = PTR_TYPE(SPEC_OCLS(etype));
8637
8638 /*      if (SPEC_OCLS(etype)->codesp ) { */
8639 /*          p_type = CPOINTER ;  */
8640 /*      } */
8641 /*      else */
8642 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8643 /*              p_type = FPOINTER ; */
8644 /*          else */
8645 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8646 /*                  p_type = PPOINTER ; */
8647 /*              else */
8648 /*                  if (SPEC_OCLS(etype) == idata ) */
8649 /*                      p_type = IPOINTER ; */
8650 /*                  else */
8651 /*                      p_type = POINTER ; */
8652     }
8653
8654     /* now that we have the pointer type we assign
8655     the pointer values */
8656     switch (p_type) {
8657
8658     case POINTER:
8659     case IPOINTER:
8660         genNearPointerSet (right,result,ic);
8661         break;
8662
8663     case PPOINTER:
8664         genPagedPointerSet (right,result,ic);
8665         break;
8666
8667     case FPOINTER:
8668         genFarPointerSet (right,result,ic);
8669         break;
8670
8671     case GPOINTER:
8672         genGenPointerSet (right,result,ic);
8673         break;
8674
8675     default:
8676       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
8677               "genPointerSet: illegal pointer type");
8678     }
8679 }
8680
8681 /*-----------------------------------------------------------------*/
8682 /* genIfx - generate code for Ifx statement                        */
8683 /*-----------------------------------------------------------------*/
8684 static void genIfx (iCode *ic, iCode *popIc)
8685 {
8686   operand *cond = IC_COND(ic);
8687   int isbit =0;
8688
8689   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8690
8691   aopOp(cond,ic,FALSE);
8692
8693   /* get the value into acc */
8694   if (AOP_TYPE(cond) != AOP_CRY)
8695     pic14_toBoolean(cond);
8696   else
8697     isbit = 1;
8698   /* the result is now in the accumulator */
8699   freeAsmop(cond,NULL,ic,TRUE);
8700
8701   /* if there was something to be popped then do it */
8702   if (popIc)
8703     genIpop(popIc);
8704
8705   /* if the condition is  a bit variable */
8706   if (isbit && IS_ITEMP(cond) && 
8707       SPIL_LOC(cond)) {
8708     genIfxJump(ic,SPIL_LOC(cond)->rname);
8709     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8710   }
8711   else {
8712     if (isbit && !IS_ITEMP(cond))
8713       genIfxJump(ic,OP_SYMBOL(cond)->rname);
8714     else
8715       genIfxJump(ic,"a");
8716   }
8717   ic->generated = 1;
8718
8719 }
8720
8721 /*-----------------------------------------------------------------*/
8722 /* genAddrOf - generates code for address of                       */
8723 /*-----------------------------------------------------------------*/
8724 static void genAddrOf (iCode *ic)
8725 {
8726   operand *right, *result, *left;
8727   int size, offset ;
8728
8729   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8730
8731
8732   //aopOp(IC_RESULT(ic),ic,FALSE);
8733
8734   aopOp((left=IC_LEFT(ic)),ic,FALSE);
8735   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8736   aopOp((result=IC_RESULT(ic)),ic,TRUE);
8737
8738   DEBUGpic14_AopType(__LINE__,left,right,result);
8739
8740   size = AOP_SIZE(IC_RESULT(ic));
8741   offset = 0;
8742
8743   while (size--) {
8744     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
8745     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8746     offset++;
8747   }
8748
8749   freeAsmop(left,NULL,ic,FALSE);
8750   freeAsmop(result,NULL,ic,TRUE);
8751
8752 }
8753
8754 #if 0
8755 /*-----------------------------------------------------------------*/
8756 /* genFarFarAssign - assignment when both are in far space         */
8757 /*-----------------------------------------------------------------*/
8758 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8759 {
8760     int size = AOP_SIZE(right);
8761     int offset = 0;
8762     char *l ;
8763     /* first push the right side on to the stack */
8764     while (size--) {
8765         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8766         MOVA(l);
8767         pic14_emitcode ("push","acc");
8768     }
8769     
8770     freeAsmop(right,NULL,ic,FALSE);
8771     /* now assign DPTR to result */
8772     aopOp(result,ic,FALSE);
8773     size = AOP_SIZE(result);
8774     while (size--) {
8775         pic14_emitcode ("pop","acc");
8776         aopPut(AOP(result),"a",--offset);
8777     }
8778     freeAsmop(result,NULL,ic,FALSE);
8779         
8780 }
8781 #endif
8782
8783 /*-----------------------------------------------------------------*/
8784 /* genAssign - generate code for assignment                        */
8785 /*-----------------------------------------------------------------*/
8786 static void genAssign (iCode *ic)
8787 {
8788   operand *result, *right;
8789   int size, offset,know_W;
8790   unsigned long lit = 0L;
8791
8792   result = IC_RESULT(ic);
8793   right  = IC_RIGHT(ic) ;
8794
8795   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8796
8797   /* if they are the same */
8798   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8799     return ;
8800
8801   aopOp(right,ic,FALSE);
8802   aopOp(result,ic,TRUE);
8803
8804   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8805
8806   /* if they are the same registers */
8807   if (pic14_sameRegs(AOP(right),AOP(result)))
8808     goto release;
8809
8810   /* if the result is a bit */
8811   if (AOP_TYPE(result) == AOP_CRY) {
8812
8813     /* if the right size is a literal then
8814        we know what the value is */
8815     if (AOP_TYPE(right) == AOP_LIT) {
8816           
8817       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8818                   popGet(AOP(result),0));
8819
8820       if (((int) operandLitValue(right))) 
8821         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8822                        AOP(result)->aopu.aop_dir,
8823                        AOP(result)->aopu.aop_dir);
8824       else
8825         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8826                        AOP(result)->aopu.aop_dir,
8827                        AOP(result)->aopu.aop_dir);
8828       goto release;
8829     }
8830
8831     /* the right is also a bit variable */
8832     if (AOP_TYPE(right) == AOP_CRY) {
8833       emitpcode(POC_BCF,    popGet(AOP(result),0));
8834       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
8835       emitpcode(POC_BSF,    popGet(AOP(result),0));
8836
8837       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8838                      AOP(result)->aopu.aop_dir,
8839                      AOP(result)->aopu.aop_dir);
8840       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8841                      AOP(right)->aopu.aop_dir,
8842                      AOP(right)->aopu.aop_dir);
8843       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8844                      AOP(result)->aopu.aop_dir,
8845                      AOP(result)->aopu.aop_dir);
8846       goto release ;
8847     }
8848
8849     /* we need to or */
8850     emitpcode(POC_BCF,    popGet(AOP(result),0));
8851     pic14_toBoolean(right);
8852     emitSKPZ;
8853     emitpcode(POC_BSF,    popGet(AOP(result),0));
8854     //aopPut(AOP(result),"a",0);
8855     goto release ;
8856   }
8857
8858   /* bit variables done */
8859   /* general case */
8860   size = AOP_SIZE(result);
8861   offset = 0 ;
8862   if(AOP_TYPE(right) == AOP_LIT)
8863     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8864
8865   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
8866   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8867     if(aopIdx(AOP(result),0) == 4) {
8868   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8869       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8870       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8871       goto release;
8872     } else
8873       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
8874   }
8875
8876   know_W=-1;
8877   while (size--) {
8878   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8879     if(AOP_TYPE(right) == AOP_LIT) {
8880       if(lit&0xff) {
8881         if(know_W != (lit&0xff))
8882           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8883         know_W = lit&0xff;
8884         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8885       } else
8886         emitpcode(POC_CLRF, popGet(AOP(result),offset));
8887
8888       lit >>= 8;
8889
8890     } else if (AOP_TYPE(right) == AOP_CRY) {
8891       emitpcode(POC_CLRF, popGet(AOP(result),offset));
8892       if(offset == 0) {
8893         emitpcode(POC_BTFSS, popGet(AOP(right),0));
8894         emitpcode(POC_INCF, popGet(AOP(result),0));
8895       }
8896     } else {
8897   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8898       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8899       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8900     }
8901             
8902     offset++;
8903   }
8904
8905     
8906  release:
8907   freeAsmop (right,NULL,ic,FALSE);
8908   freeAsmop (result,NULL,ic,TRUE);
8909 }   
8910
8911 /*-----------------------------------------------------------------*/
8912 /* genJumpTab - genrates code for jump table                       */
8913 /*-----------------------------------------------------------------*/
8914 static void genJumpTab (iCode *ic)
8915 {
8916     symbol *jtab;
8917     char *l;
8918
8919     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8920
8921     aopOp(IC_JTCOND(ic),ic,FALSE);
8922     /* get the condition into accumulator */
8923     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8924     MOVA(l);
8925     /* multiply by three */
8926     pic14_emitcode("add","a,acc");
8927     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8928
8929     jtab = newiTempLabel(NULL);
8930     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8931     pic14_emitcode("jmp","@a+dptr");
8932     pic14_emitcode("","%05d_DS_:",jtab->key+100);
8933
8934     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8935     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8936     emitSKPNC;
8937     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8938     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8939     emitpLabel(jtab->key);
8940
8941     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8942
8943     /* now generate the jump labels */
8944     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8945          jtab = setNextItem(IC_JTLABELS(ic))) {
8946         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8947         emitpcode(POC_GOTO,popGetLabel(jtab->key));
8948         
8949     }
8950
8951 }
8952
8953 /*-----------------------------------------------------------------*/
8954 /* genMixedOperation - gen code for operators between mixed types  */
8955 /*-----------------------------------------------------------------*/
8956 /*
8957   TSD - Written for the PIC port - but this unfortunately is buggy.
8958   This routine is good in that it is able to efficiently promote 
8959   types to different (larger) sizes. Unfortunately, the temporary
8960   variables that are optimized out by this routine are sometimes
8961   used in other places. So until I know how to really parse the 
8962   iCode tree, I'm going to not be using this routine :(.
8963 */
8964 static int genMixedOperation (iCode *ic)
8965 {
8966 #if 0
8967   operand *result = IC_RESULT(ic);
8968   sym_link *ctype = operandType(IC_LEFT(ic));
8969   operand *right = IC_RIGHT(ic);
8970   int ret = 0;
8971   int big,small;
8972   int offset;
8973
8974   iCode *nextic;
8975   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8976
8977   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8978
8979   nextic = ic->next;
8980   if(!nextic)
8981     return 0;
8982
8983   nextright = IC_RIGHT(nextic);
8984   nextleft  = IC_LEFT(nextic);
8985   nextresult = IC_RESULT(nextic);
8986
8987   aopOp(right,ic,FALSE);
8988   aopOp(result,ic,FALSE);
8989   aopOp(nextright,  nextic, FALSE);
8990   aopOp(nextleft,   nextic, FALSE);
8991   aopOp(nextresult, nextic, FALSE);
8992
8993   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8994
8995     operand *t = right;
8996     right = nextright;
8997     nextright = t; 
8998
8999     pic14_emitcode(";remove right +","");
9000
9001   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9002 /*
9003     operand *t = right;
9004     right = nextleft;
9005     nextleft = t; 
9006 */
9007     pic14_emitcode(";remove left +","");
9008   } else
9009     return 0;
9010
9011   big = AOP_SIZE(nextleft);
9012   small = AOP_SIZE(nextright);
9013
9014   switch(nextic->op) {
9015
9016   case '+':
9017     pic14_emitcode(";optimize a +","");
9018     /* if unsigned or not an integral type */
9019     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9020       pic14_emitcode(";add a bit to something","");
9021     } else {
9022
9023       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9024
9025       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9026         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9027         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9028       } else
9029         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9030
9031       offset = 0;
9032       while(--big) {
9033
9034         offset++;
9035
9036         if(--small) {
9037           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9038             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9039             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9040           }
9041
9042           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9043           emitSKPNC;
9044           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9045                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9046                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9047           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9048           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9049
9050         } else {
9051           pic14_emitcode("rlf","known_zero,w");
9052
9053           /*
9054             if right is signed
9055               btfsc  right,7
9056                addlw ff
9057           */
9058           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9059             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9060             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9061           } else {
9062             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9063           }
9064         }
9065       }
9066       ret = 1;
9067     }
9068   }
9069   ret = 1;
9070
9071 release:
9072   freeAsmop(right,NULL,ic,TRUE);
9073   freeAsmop(result,NULL,ic,TRUE);
9074   freeAsmop(nextright,NULL,ic,TRUE);
9075   freeAsmop(nextleft,NULL,ic,TRUE);
9076   if(ret)
9077     nextic->generated = 1;
9078
9079   return ret;
9080 #else
9081   return 0;
9082 #endif
9083 }
9084 /*-----------------------------------------------------------------*/
9085 /* genCast - gen code for casting                                  */
9086 /*-----------------------------------------------------------------*/
9087 static void genCast (iCode *ic)
9088 {
9089     operand *result = IC_RESULT(ic);
9090     sym_link *ctype = operandType(IC_LEFT(ic));
9091     sym_link *rtype = operandType(IC_RIGHT(ic));
9092     operand *right = IC_RIGHT(ic);
9093     int size, offset ;
9094
9095     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9096     /* if they are equivalent then do nothing */
9097     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9098         return ;
9099
9100     aopOp(right,ic,FALSE) ;
9101     aopOp(result,ic,FALSE);
9102
9103     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9104
9105     /* if the result is a bit */
9106     if (AOP_TYPE(result) == AOP_CRY) {
9107         /* if the right size is a literal then
9108         we know what the value is */
9109       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9110         if (AOP_TYPE(right) == AOP_LIT) {
9111
9112           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9113                       popGet(AOP(result),0));
9114
9115             if (((int) operandLitValue(right))) 
9116               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9117                        AOP(result)->aopu.aop_dir,
9118                        AOP(result)->aopu.aop_dir);
9119             else
9120               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9121                        AOP(result)->aopu.aop_dir,
9122                        AOP(result)->aopu.aop_dir);
9123
9124             goto release;
9125         }
9126
9127         /* the right is also a bit variable */
9128         if (AOP_TYPE(right) == AOP_CRY) {
9129
9130           emitCLRC;
9131           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9132
9133           pic14_emitcode("clrc","");
9134           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9135                    AOP(right)->aopu.aop_dir,
9136                    AOP(right)->aopu.aop_dir);
9137             aopPut(AOP(result),"c",0);
9138             goto release ;
9139         }
9140
9141         /* we need to or */
9142         if (AOP_TYPE(right) == AOP_REG) {
9143           emitpcode(POC_BCF,    popGet(AOP(result),0));
9144           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9145           emitpcode(POC_BSF,    popGet(AOP(result),0));
9146         }
9147         pic14_toBoolean(right);
9148         aopPut(AOP(result),"a",0);
9149         goto release ;
9150     }
9151
9152     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9153       int offset = 1;
9154       size = AOP_SIZE(result);
9155
9156       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9157
9158       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9159       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9160       emitpcode(POC_INCF,   popGet(AOP(result),0));
9161
9162       while (size--)
9163         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9164
9165       goto release;
9166     }
9167
9168     /* if they are the same size : or less */
9169     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9170
9171         /* if they are in the same place */
9172       if (pic14_sameRegs(AOP(right),AOP(result)))
9173         goto release;
9174
9175       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9176       if (IS_PTR_CONST(rtype))
9177         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9178       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9179         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9180
9181       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9182         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9183         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9184         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9185         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9186         if(AOP_SIZE(result) <2)
9187           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9188
9189       } else {
9190
9191         /* if they in different places then copy */
9192         size = AOP_SIZE(result);
9193         offset = 0 ;
9194         while (size--) {
9195           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9196           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9197
9198           //aopPut(AOP(result),
9199           // aopGet(AOP(right),offset,FALSE,FALSE),
9200           // offset);
9201
9202           offset++;
9203         }
9204       }
9205       goto release;
9206     }
9207
9208
9209     /* if the result is of type pointer */
9210     if (IS_PTR(ctype)) {
9211
9212         int p_type;
9213         sym_link *type = operandType(right);
9214         sym_link *etype = getSpec(type);
9215       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9216
9217         /* pointer to generic pointer */
9218         if (IS_GENPTR(ctype)) {
9219             char *l = zero;
9220             
9221             if (IS_PTR(type)) 
9222                 p_type = DCL_TYPE(type);
9223             else {
9224                 /* we have to go by the storage class */
9225                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9226
9227 /*              if (SPEC_OCLS(etype)->codesp )  */
9228 /*                  p_type = CPOINTER ;  */
9229 /*              else */
9230 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9231 /*                      p_type = FPOINTER ; */
9232 /*                  else */
9233 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9234 /*                          p_type = PPOINTER; */
9235 /*                      else */
9236 /*                          if (SPEC_OCLS(etype) == idata ) */
9237 /*                              p_type = IPOINTER ; */
9238 /*                          else */
9239 /*                              p_type = POINTER ; */
9240             }
9241                 
9242             /* the first two bytes are known */
9243             size = GPTRSIZE - 1; 
9244             offset = 0 ;
9245             while (size--) {
9246               if(offset < AOP_SIZE(right))
9247                 aopPut(AOP(result),
9248                        aopGet(AOP(right),offset,FALSE,FALSE),
9249                        offset);
9250               else
9251                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9252               offset++;
9253             }
9254             /* the last byte depending on type */
9255             switch (p_type) {
9256             case IPOINTER:
9257             case POINTER:
9258                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9259                 break;
9260             case FPOINTER:
9261               pic14_emitcode(";BUG!? ","%d",__LINE__);
9262                 l = one;
9263                 break;
9264             case CPOINTER:
9265               pic14_emitcode(";BUG!? ","%d",__LINE__);
9266                 l = "#0x02";
9267                 break;                          
9268             case PPOINTER:
9269               pic14_emitcode(";BUG!? ","%d",__LINE__);
9270                 l = "#0x03";
9271                 break;
9272                 
9273             default:
9274                 /* this should never happen */
9275                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9276                        "got unknown pointer type");
9277                 exit(1);
9278             }
9279             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9280             goto release ;
9281         }
9282         
9283         /* just copy the pointers */
9284         size = AOP_SIZE(result);
9285         offset = 0 ;
9286         while (size--) {
9287             aopPut(AOP(result),
9288                    aopGet(AOP(right),offset,FALSE,FALSE),
9289                    offset);
9290             offset++;
9291         }
9292         goto release ;
9293     }
9294     
9295
9296
9297     /* so we now know that the size of destination is greater
9298     than the size of the source.
9299     Now, if the next iCode is an operator then we might be
9300     able to optimize the operation without performing a cast.
9301     */
9302     if(genMixedOperation(ic))
9303       goto release;
9304
9305     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9306     
9307     /* we move to result for the size of source */
9308     size = AOP_SIZE(right);
9309     offset = 0 ;
9310     while (size--) {
9311       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9312       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9313       offset++;
9314     }
9315
9316     /* now depending on the sign of the destination */
9317     size = AOP_SIZE(result) - AOP_SIZE(right);
9318     /* if unsigned or not an integral type */
9319     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9320       while (size--)
9321         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9322     } else {
9323       /* we need to extend the sign :{ */
9324
9325       if(size == 1) {
9326         /* Save one instruction of casting char to int */
9327         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9328         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9329         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9330       } else {
9331         emitpcodeNULLop(POC_CLRW);
9332
9333         if(offset)
9334           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9335         else
9336           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9337         
9338         emitpcode(POC_MOVLW,   popGetLit(0xff));
9339
9340         while (size--)
9341           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9342       }
9343     }
9344
9345 release:
9346     freeAsmop(right,NULL,ic,TRUE);
9347     freeAsmop(result,NULL,ic,TRUE);
9348
9349 }
9350
9351 /*-----------------------------------------------------------------*/
9352 /* genDjnz - generate decrement & jump if not zero instrucion      */
9353 /*-----------------------------------------------------------------*/
9354 static int genDjnz (iCode *ic, iCode *ifx)
9355 {
9356     symbol *lbl, *lbl1;
9357     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9358
9359     if (!ifx)
9360         return 0;
9361     
9362     /* if the if condition has a false label
9363        then we cannot save */
9364     if (IC_FALSE(ifx))
9365         return 0;
9366
9367     /* if the minus is not of the form 
9368        a = a - 1 */
9369     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9370         !IS_OP_LITERAL(IC_RIGHT(ic)))
9371         return 0;
9372
9373     if (operandLitValue(IC_RIGHT(ic)) != 1)
9374         return 0;
9375
9376     /* if the size of this greater than one then no
9377        saving */
9378     if (getSize(operandType(IC_RESULT(ic))) > 1)
9379         return 0;
9380
9381     /* otherwise we can save BIG */
9382     lbl = newiTempLabel(NULL);
9383     lbl1= newiTempLabel(NULL);
9384
9385     aopOp(IC_RESULT(ic),ic,FALSE);
9386     
9387     if (IS_AOP_PREG(IC_RESULT(ic))) {
9388         pic14_emitcode("dec","%s",
9389                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9390         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9391         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9392     } else {    
9393
9394
9395       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9396       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9397
9398       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9399       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9400
9401     }
9402 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9403 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9404 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9405 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9406
9407     
9408     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9409     ifx->generated = 1;
9410     return 1;
9411 }
9412
9413 /*-----------------------------------------------------------------*/
9414 /* genReceive - generate code for a receive iCode                  */
9415 /*-----------------------------------------------------------------*/
9416 static void genReceive (iCode *ic)
9417 {    
9418   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9419
9420   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9421       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9422         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9423
9424     int size = getSize(operandType(IC_RESULT(ic)));
9425     int offset =  fReturnSizePic - size;
9426     while (size--) {
9427       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9428                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9429       offset++;
9430     }
9431     aopOp(IC_RESULT(ic),ic,FALSE);  
9432     size = AOP_SIZE(IC_RESULT(ic));
9433     offset = 0;
9434     while (size--) {
9435       pic14_emitcode ("pop","acc");
9436       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9437     }
9438         
9439   } else {
9440     _G.accInUse++;
9441     aopOp(IC_RESULT(ic),ic,FALSE);  
9442     _G.accInUse--;
9443     assignResultValue(IC_RESULT(ic));   
9444   }
9445
9446   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9447 }
9448
9449 /*-----------------------------------------------------------------*/
9450 /* genpic14Code - generate code for pic14 based controllers        */
9451 /*-----------------------------------------------------------------*/
9452 /*
9453  * At this point, ralloc.c has gone through the iCode and attempted
9454  * to optimize in a way suitable for a PIC. Now we've got to generate
9455  * PIC instructions that correspond to the iCode.
9456  *
9457  * Once the instructions are generated, we'll pass through both the
9458  * peep hole optimizer and the pCode optimizer.
9459  *-----------------------------------------------------------------*/
9460
9461 void genpic14Code (iCode *lic)
9462 {
9463     iCode *ic;
9464     int cln = 0;
9465
9466     lineHead = lineCurr = NULL;
9467
9468     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9469     addpBlock(pb);
9470
9471     /* if debug information required */
9472     if (options.debug && currFunc) { 
9473       if (currFunc) {
9474         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9475         _G.debugLine = 1;
9476         if (IS_STATIC(currFunc->etype)) {
9477           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9478           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9479         } else {
9480           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9481           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9482         }
9483         _G.debugLine = 0;
9484       }
9485     }
9486
9487
9488     for (ic = lic ; ic ; ic = ic->next ) {
9489
9490       DEBUGpic14_emitcode(";ic","");
9491         if ( cln != ic->lineno ) {
9492             if ( options.debug ) {
9493                 _G.debugLine = 1;
9494                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9495                          FileBaseName(ic->filename),ic->lineno,
9496                          ic->level,ic->block);
9497                 _G.debugLine = 0;
9498             }
9499             pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9500             pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9501                             printCLine(ic->filename, ic->lineno));
9502
9503             cln = ic->lineno ;
9504         }
9505         /* if the result is marked as
9506            spilt and rematerializable or code for
9507            this has already been generated then
9508            do nothing */
9509         if (resultRemat(ic) || ic->generated ) 
9510             continue ;
9511         
9512         /* depending on the operation */
9513         switch (ic->op) {
9514         case '!' :
9515             genNot(ic);
9516             break;
9517             
9518         case '~' :
9519             genCpl(ic);
9520             break;
9521             
9522         case UNARYMINUS:
9523             genUminus (ic);
9524             break;
9525             
9526         case IPUSH:
9527             genIpush (ic);
9528             break;
9529             
9530         case IPOP:
9531             /* IPOP happens only when trying to restore a 
9532                spilt live range, if there is an ifx statement
9533                following this pop then the if statement might
9534                be using some of the registers being popped which
9535                would destory the contents of the register so
9536                we need to check for this condition and handle it */
9537             if (ic->next            && 
9538                 ic->next->op == IFX &&
9539                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9540                 genIfx (ic->next,ic);
9541             else
9542                 genIpop (ic);
9543             break; 
9544             
9545         case CALL:
9546             genCall (ic);
9547             break;
9548             
9549         case PCALL:
9550             genPcall (ic);
9551             break;
9552             
9553         case FUNCTION:
9554             genFunction (ic);
9555             break;
9556             
9557         case ENDFUNCTION:
9558             genEndFunction (ic);
9559             break;
9560             
9561         case RETURN:
9562             genRet (ic);
9563             break;
9564             
9565         case LABEL:
9566             genLabel (ic);
9567             break;
9568             
9569         case GOTO:
9570             genGoto (ic);
9571             break;
9572             
9573         case '+' :
9574             genPlus (ic) ;
9575             break;
9576             
9577         case '-' :
9578             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9579                 genMinus (ic);
9580             break;
9581             
9582         case '*' :
9583             genMult (ic);
9584             break;
9585             
9586         case '/' :
9587             genDiv (ic) ;
9588             break;
9589             
9590         case '%' :
9591             genMod (ic);
9592             break;
9593             
9594         case '>' :
9595             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9596             break;
9597             
9598         case '<' :
9599             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9600             break;
9601             
9602         case LE_OP:
9603         case GE_OP:
9604         case NE_OP:
9605             
9606             /* note these two are xlated by algebraic equivalence
9607                during parsing SDCC.y */
9608             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9609                    "got '>=' or '<=' shouldn't have come here");
9610             break;      
9611             
9612         case EQ_OP:
9613             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9614             break;          
9615             
9616         case AND_OP:
9617             genAndOp (ic);
9618             break;
9619             
9620         case OR_OP:
9621             genOrOp (ic);
9622             break;
9623             
9624         case '^' :
9625             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9626             break;
9627             
9628         case '|' :
9629                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9630             break;
9631             
9632         case BITWISEAND:
9633             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9634             break;
9635             
9636         case INLINEASM:
9637             genInline (ic);
9638             break;
9639             
9640         case RRC:
9641             genRRC (ic);
9642             break;
9643             
9644         case RLC:
9645             genRLC (ic);
9646             break;
9647             
9648         case GETHBIT:
9649             genGetHbit (ic);
9650             break;
9651             
9652         case LEFT_OP:
9653             genLeftShift (ic);
9654             break;
9655             
9656         case RIGHT_OP:
9657             genRightShift (ic);
9658             break;
9659             
9660         case GET_VALUE_AT_ADDRESS:
9661             genPointerGet(ic);
9662             break;
9663             
9664         case '=' :
9665             if (POINTER_SET(ic))
9666                 genPointerSet(ic);
9667             else
9668                 genAssign(ic);
9669             break;
9670             
9671         case IFX:
9672             genIfx (ic,NULL);
9673             break;
9674             
9675         case ADDRESS_OF:
9676             genAddrOf (ic);
9677             break;
9678             
9679         case JUMPTABLE:
9680             genJumpTab (ic);
9681             break;
9682             
9683         case CAST:
9684             genCast (ic);
9685             break;
9686             
9687         case RECEIVE:
9688             genReceive(ic);
9689             break;
9690             
9691         case SEND:
9692             addSet(&_G.sendSet,ic);
9693             break;
9694
9695         default :
9696             ic = ic;
9697         }
9698     }
9699     
9700
9701     /* now we are ready to call the 
9702        peep hole optimizer */
9703     if (!options.nopeep) {
9704       peepHole (&lineHead);
9705     }
9706     /* now do the actual printing */
9707     printLine (lineHead,codeOutFile);
9708
9709 #ifdef PCODE_DEBUG
9710     DFPRINTF((stderr,"printing pBlock\n\n"));
9711     printpBlock(stdout,pb);
9712 #endif
9713
9714     return;
9715 }