Fixed shifts by varaibles. Added rotate test code to src/regression
[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
3716       symbol *lbl  = newiTempLabel(NULL);
3717
3718       if(AOP_TYPE(right) == AOP_LIT) {
3719
3720         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3721
3722         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3723
3724         /* special cases */
3725
3726         if(lit == 0) {
3727
3728           if(sign != 0) 
3729             genSkipCond(&rFalseIfx,left,size-1,7);
3730           else 
3731             /* no need to compare to 0...*/
3732             /* NOTE: this is a de-generate compare that most certainly 
3733              *       creates some dead code. */
3734             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3735
3736           if(ifx) ifx->generated = 1;
3737           return;
3738
3739         }
3740         size--;
3741
3742         if(size == 0) {
3743           //i = (lit >> (size*8)) & 0xff;
3744           DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3745         
3746           emitpcode(POC_MOVFW, popGet(AOP(left),size));
3747
3748           i = ((0-lit) & 0xff);
3749           if(sign) {
3750             if( i == 0x81) { 
3751               /* lit is 0x7f, all signed chars are less than
3752                * this except for 0x7f itself */
3753               emitpcode(POC_XORLW, popGetLit(0x7f));
3754               genSkipz2(&rFalseIfx);
3755             } else {
3756               emitpcode(POC_ADDLW, popGetLit(0x80));
3757               emitpcode(POC_ADDLW, popGetLit(i^0x80));
3758               genSkipc(&rFalseIfx);
3759             }
3760
3761           } else {
3762             emitpcode(POC_ADDLW, popGetLit(i));
3763             genSkipc(&rFalseIfx);
3764
3765           }
3766
3767           if(ifx) ifx->generated = 1;
3768           return;
3769         }
3770
3771         /* chars are out of the way. now do ints and longs */
3772
3773
3774         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3775         
3776         /* special cases */
3777
3778         if(sign) {
3779
3780           if(lit == 0) {
3781             genSkipCond(&rFalseIfx,left,size,7);
3782             if(ifx) ifx->generated = 1;
3783             return;
3784           }
3785
3786           if(lit <0x100) {
3787             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3788
3789             //rFalseIfx.condition ^= 1;
3790             //genSkipCond(&rFalseIfx,left,size,7);
3791             //rFalseIfx.condition ^= 1;
3792
3793             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3794             if(rFalseIfx.condition)
3795               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3796             else
3797               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3798
3799             emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3800             emitpcode(POC_ADDFW, popGet(AOP(left),0));
3801             emitpcode(POC_MOVFW, popGet(AOP(left),1));
3802
3803             while(size > 1)
3804               emitpcode(POC_IORFW, popGet(AOP(left),size--));
3805
3806             if(rFalseIfx.condition) {
3807               emitSKPZ;
3808               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3809
3810             } else {
3811               emitSKPNZ;
3812             }
3813
3814             genSkipc(&rFalseIfx);
3815             emitpLabel(truelbl->key);
3816             if(ifx) ifx->generated = 1;
3817             return;
3818
3819           }
3820
3821           if(size == 1) {
3822
3823             if( (lit & 0xff) == 0) {
3824               /* lower byte is zero */
3825               DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3826               i = ((lit >> 8) & 0xff) ^0x80;
3827               emitpcode(POC_MOVFW, popGet(AOP(left),size));
3828               emitpcode(POC_ADDLW, popGetLit( 0x80));
3829               emitpcode(POC_ADDLW, popGetLit(0x100-i));
3830               genSkipc(&rFalseIfx);
3831
3832
3833               if(ifx) ifx->generated = 1;
3834               return;
3835
3836             }
3837           } else {
3838             /* Special cases for signed longs */
3839             if( (lit & 0xffffff) == 0) {
3840               /* lower byte is zero */
3841               DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3842               i = ((lit >> 8*3) & 0xff) ^0x80;
3843               emitpcode(POC_MOVFW, popGet(AOP(left),size));
3844               emitpcode(POC_ADDLW, popGetLit( 0x80));
3845               emitpcode(POC_ADDLW, popGetLit(0x100-i));
3846               genSkipc(&rFalseIfx);
3847
3848
3849               if(ifx) ifx->generated = 1;
3850               return;
3851
3852             }
3853
3854           }
3855
3856
3857           if(lit & (0x80 << (size*8))) {
3858             /* lit is negative */
3859             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3860
3861             //genSkipCond(&rFalseIfx,left,size,7);
3862
3863             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3864
3865             if(rFalseIfx.condition)
3866               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3867             else
3868               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3869
3870
3871           } else {
3872             /* lit is positive */
3873             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3874             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3875             if(rFalseIfx.condition)
3876               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3877             else
3878               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3879
3880             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3881             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3882             //rFalseIfx.condition ^= 1;
3883             //genSkipCond(&rFalseIfx,left,size,7);
3884             //rFalseIfx.condition ^= 1;
3885           }
3886
3887           /*
3888             This works, but is only good for ints.
3889             It also requires a "known zero" register.
3890             emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3891             emitpcode(POC_ADDFW, popGet(AOP(left),0));
3892             emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3893             emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3894             emitpcode(POC_ADDFW, popGet(AOP(left),1));
3895             genSkipc(&rFalseIfx);
3896
3897             emitpLabel(truelbl->key);
3898             if(ifx) ifx->generated = 1;
3899             return;
3900           **/
3901           
3902           /* There are no more special cases, so perform a general compare */
3903   
3904           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3905           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3906
3907           while(size--) {
3908
3909             emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3910             emitSKPNZ;
3911             emitpcode(POC_SUBFW, popGet(AOP(left),size));
3912           }
3913           //rFalseIfx.condition ^= 1;
3914           genSkipc(&rFalseIfx);
3915
3916           emitpLabel(truelbl->key);
3917
3918           if(ifx) ifx->generated = 1;
3919           return;
3920
3921
3922         }
3923
3924
3925         /* sign is out of the way. So now do an unsigned compare */
3926         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3927
3928
3929         //genChkZeroes(left)
3930
3931         /* General case - compare to an unsigned literal on the right.*/
3932
3933         i = (lit >> (size*8)) & 0xff;
3934         emitpcode(POC_MOVLW, popGetLit(i));
3935         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3936         while(size--) {
3937           i = (lit >> (size*8)) & 0xff;
3938
3939           if(i) {
3940             emitpcode(POC_MOVLW, popGetLit(i));
3941             emitSKPNZ;
3942             emitpcode(POC_SUBFW, popGet(AOP(left),size));
3943           } else {
3944             /* this byte of the lit is zero, 
3945              *if it's not the last then OR in the variable */
3946             if(size)
3947               emitpcode(POC_IORFW, popGet(AOP(left),size));
3948           }
3949         }
3950
3951
3952         emitpLabel(lbl->key);
3953         //if(emitFinalCheck)
3954           genSkipc(&rFalseIfx);
3955         if(sign)
3956           emitpLabel(truelbl->key);
3957
3958         if(ifx) ifx->generated = 1;
3959         return;
3960
3961
3962       }
3963
3964       if(AOP_TYPE(left) == AOP_LIT) {
3965         //symbol *lbl = newiTempLabel(NULL);
3966
3967         lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3968
3969
3970         DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3971
3972         /* Special cases */
3973         if((lit == 0) && (sign == 0)){
3974
3975           size--;
3976           emitpcode(POC_MOVFW, popGet(AOP(right),size));
3977           while(size) 
3978             emitpcode(POC_IORFW, popGet(AOP(right),--size));
3979
3980           //rFalseIfx.condition ^= 1;
3981           genSkipz2(&rFalseIfx);
3982           if(ifx) ifx->generated = 1;
3983           return;
3984         }
3985
3986         if(size==1) {
3987           /* Special cases */
3988           lit &= 0xff;
3989           if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3990             /* degenerate compare can never be true */
3991             if(rFalseIfx.condition == 0)
3992               emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3993
3994             if(ifx) ifx->generated = 1;
3995             return;
3996           }
3997
3998           if(sign) {
3999             if((lit+1)&0xff) {
4000               emitpcode(POC_MOVFW, popGet(AOP(right),0));
4001               emitpcode(POC_ADDLW, popGetLit(0x80));
4002               emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4003               rFalseIfx.condition ^= 1;
4004               genSkipc(&rFalseIfx);
4005             } else {
4006               rFalseIfx.condition ^= 1;
4007               genSkipCond(&rFalseIfx,right,0,7);
4008             }
4009             
4010           } else {
4011             if(lit & 0xff) {
4012               emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4013               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4014               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4015               rFalseIfx.condition ^= 1;
4016               genSkipc(&rFalseIfx);
4017             } else { 
4018               emitpcode(POC_MOVFW, popGet(AOP(right),0));
4019               genSkipz2(&rFalseIfx);
4020             }
4021           }
4022
4023           if(ifx) ifx->generated = 1;
4024           return;
4025
4026         } else {
4027
4028           /* Size is greater than 1 */
4029
4030
4031
4032           if(sign) {
4033             int lp1 = lit+1;
4034
4035             size--;
4036
4037             if(lp1 == 0) {
4038               /* this means lit = 0xffffffff, or -1 */
4039
4040
4041               DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4042               rFalseIfx.condition ^= 1;
4043               genSkipCond(&rFalseIfx,right,size,7);
4044               if(ifx) ifx->generated = 1;
4045               return;
4046             }
4047
4048             if(lit == 0) {
4049               int s = size;
4050
4051               if(rFalseIfx.condition) {
4052                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4053                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4054               }
4055
4056               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4057               while(size--)
4058                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4059
4060
4061               emitSKPZ;
4062               if(rFalseIfx.condition) {
4063                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4064                 emitpLabel(truelbl->key);
4065               }else {
4066                 rFalseIfx.condition ^= 1;
4067                 genSkipCond(&rFalseIfx,right,s,7);
4068               }
4069
4070               if(ifx) ifx->generated = 1;
4071               return;
4072             }
4073
4074
4075             if(lit & (0x80 << (size*8))) {
4076               /* Lit is less than zero */
4077               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4078               //rFalseIfx.condition ^= 1;
4079               //genSkipCond(&rFalseIfx,left,size,7);
4080               //rFalseIfx.condition ^= 1;
4081               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4082               //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4083
4084               if(rFalseIfx.condition)
4085                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4086               else
4087                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4088
4089
4090             } else {
4091               /* Lit is greater than or equal to zero */
4092               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4093               //rFalseIfx.condition ^= 1;
4094               //genSkipCond(&rFalseIfx,right,size,7);
4095               //rFalseIfx.condition ^= 1;
4096
4097               //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4098               //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4099
4100               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4101               if(rFalseIfx.condition)
4102                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4103               else
4104                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4105
4106             }
4107             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4108             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4109
4110             while(size--) {
4111
4112               emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4113               emitSKPNZ;
4114               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4115             }
4116             rFalseIfx.condition ^= 1;
4117             //rFalseIfx.condition = 1;
4118             genSkipc(&rFalseIfx);
4119
4120             emitpLabel(truelbl->key);
4121
4122             if(ifx) ifx->generated = 1;
4123             return;
4124
4125           } else {
4126             /* Unsigned compare for sizes greater than 1 */
4127
4128             while(size--) {
4129               i = (lit >> (size*8)) & 0xff;
4130
4131
4132               if(size) {
4133                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4134                 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4135                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4136                 emitSKPZ;
4137                 emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4138               } else {
4139                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4140                 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4141                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4142
4143               }
4144             }
4145
4146             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4147
4148             emitpLabel(lbl->key);
4149
4150             rFalseIfx.condition ^= 1;
4151             genSkipc(&rFalseIfx);
4152
4153           }
4154         if(sign)
4155           emitpLabel(truelbl->key);
4156         if(ifx) ifx->generated = 1;
4157         return;
4158         }
4159       }
4160       /* Compare two variables */
4161
4162       DEBUGpic14_emitcode(";sign","%d",sign);
4163
4164       size--;
4165       if(sign) {
4166         /* Sigh. thus sucks... */
4167         if(size) {
4168           emitpcode(POC_MOVFW, popGet(AOP(left),size));
4169           emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4170           emitpcode(POC_MOVLW, popGetLit(0x80));
4171           emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4172           emitpcode(POC_XORFW, popGet(AOP(right),size));
4173           emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4174         } else {
4175           /* Signed char comparison */
4176           /* Special thanks to Nikolai Golovchenko for this snippet */
4177           emitpcode(POC_MOVFW, popGet(AOP(right),0));
4178           emitpcode(POC_SUBFW, popGet(AOP(left),0));
4179           emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4180           emitpcode(POC_XORFW, popGet(AOP(left),0));
4181           emitpcode(POC_XORFW, popGet(AOP(right),0));
4182           emitpcode(POC_ADDLW, popGetLit(0x80));
4183
4184           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4185           genSkipc(&rFalseIfx);
4186           
4187           if(ifx) ifx->generated = 1;
4188           return;
4189         }
4190
4191       } else {
4192
4193         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4194         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4195       }
4196
4197
4198       /* The rest of the bytes of a multi-byte compare */
4199       while (size) {
4200
4201         emitSKPZ;
4202         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4203         size--;
4204
4205         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4206         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4207
4208
4209       }
4210
4211       emitpLabel(lbl->key);
4212
4213       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4214       genSkipc(&rFalseIfx);
4215       if(ifx) ifx->generated = 1;
4216       return;
4217
4218     }
4219   }
4220
4221   //release:
4222   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4223     pic14_outBitC(result);
4224   } else {
4225     /* if the result is used in the next
4226        ifx conditional branch then generate
4227        code a little differently */
4228     if (ifx )
4229       genIfxJump (ifx,"c");
4230     else
4231       pic14_outBitC(result);
4232     /* leave the result in acc */
4233   }
4234
4235 }
4236
4237 /*-----------------------------------------------------------------*/
4238 /* genCmpGt :- greater than comparison                             */
4239 /*-----------------------------------------------------------------*/
4240 static void genCmpGt (iCode *ic, iCode *ifx)
4241 {
4242     operand *left, *right, *result;
4243     sym_link *letype , *retype;
4244     int sign ;
4245
4246     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4247     left = IC_LEFT(ic);
4248     right= IC_RIGHT(ic);
4249     result = IC_RESULT(ic);
4250
4251     letype = getSpec(operandType(left));
4252     retype =getSpec(operandType(right));
4253     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4254     /* assign the amsops */
4255     aopOp (left,ic,FALSE);
4256     aopOp (right,ic,FALSE);
4257     aopOp (result,ic,TRUE);
4258
4259     genCmp(right, left, result, ifx, sign);
4260
4261     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4262     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4263     freeAsmop(result,NULL,ic,TRUE); 
4264 }
4265
4266 /*-----------------------------------------------------------------*/
4267 /* genCmpLt - less than comparisons                                */
4268 /*-----------------------------------------------------------------*/
4269 static void genCmpLt (iCode *ic, iCode *ifx)
4270 {
4271     operand *left, *right, *result;
4272     sym_link *letype , *retype;
4273     int sign ;
4274
4275     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4276     left = IC_LEFT(ic);
4277     right= IC_RIGHT(ic);
4278     result = IC_RESULT(ic);
4279
4280     letype = getSpec(operandType(left));
4281     retype =getSpec(operandType(right));
4282     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4283
4284     /* assign the amsops */
4285     aopOp (left,ic,FALSE);
4286     aopOp (right,ic,FALSE);
4287     aopOp (result,ic,TRUE);
4288
4289     genCmp(left, right, result, ifx, sign);
4290
4291     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4292     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4293     freeAsmop(result,NULL,ic,TRUE); 
4294 }
4295
4296 /*-----------------------------------------------------------------*/
4297 /* genc16bit2lit - compare a 16 bit value to a literal             */
4298 /*-----------------------------------------------------------------*/
4299 static void genc16bit2lit(operand *op, int lit, int offset)
4300 {
4301   int i;
4302
4303   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4304   if( (lit&0xff) == 0) 
4305     i=1;
4306   else
4307     i=0;
4308
4309   switch( BYTEofLONG(lit,i)) { 
4310   case 0:
4311     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4312     break;
4313   case 1:
4314     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4315     break;
4316   case 0xff:
4317     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4318     break;
4319   default:
4320     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4321     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4322   }
4323
4324   i ^= 1;
4325
4326   switch( BYTEofLONG(lit,i)) { 
4327   case 0:
4328     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4329     break;
4330   case 1:
4331     emitSKPNZ;
4332     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4333     break;
4334   case 0xff:
4335     emitSKPNZ;
4336     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4337     break;
4338   default:
4339     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4340     emitSKPNZ;
4341     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4342
4343   }
4344
4345 }
4346
4347 /*-----------------------------------------------------------------*/
4348 /* gencjneshort - compare and jump if not equal                    */
4349 /*-----------------------------------------------------------------*/
4350 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4351 {
4352   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4353   int offset = 0;
4354   resolvedIfx rIfx;
4355   symbol *lbl;
4356
4357   unsigned long lit = 0L;
4358   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4359   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4360
4361   resolveIfx(&rIfx,ifx);
4362   lbl =  newiTempLabel(NULL);
4363
4364
4365   /* if the left side is a literal or 
4366      if the right is in a pointer register and left 
4367      is not */
4368   if ((AOP_TYPE(left) == AOP_LIT) || 
4369       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4370     operand *t = right;
4371     right = left;
4372     left = t;
4373   }
4374   if(AOP_TYPE(right) == AOP_LIT)
4375     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4376
4377   /* if the right side is a literal then anything goes */
4378   if (AOP_TYPE(right) == AOP_LIT &&
4379       AOP_TYPE(left) != AOP_DIR ) {
4380     switch(size) {
4381     case 2:
4382       genc16bit2lit(left, lit, 0);
4383       emitSKPNZ;
4384       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4385       break;
4386     default:
4387       while (size--) {
4388         if(lit & 0xff) {
4389           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4390           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4391         } else {
4392           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4393         }
4394
4395         emitSKPNZ;
4396         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4397         offset++;
4398         lit >>= 8;
4399       }
4400       break;
4401     }
4402   }
4403
4404   /* if the right side is in a register or in direct space or
4405      if the left is a pointer register & right is not */    
4406   else if (AOP_TYPE(right) == AOP_REG ||
4407            AOP_TYPE(right) == AOP_DIR || 
4408            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4409            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4410     switch(size) {
4411     case 2:
4412       genc16bit2lit(left, lit, 0);
4413       emitSKPNZ;
4414       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4415       break;
4416     default:
4417       while (size--) {
4418         int emit_skip=1;
4419         if((AOP_TYPE(left) == AOP_DIR) && 
4420            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4421
4422           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4423           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4424
4425         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4426             
4427           switch (lit & 0xff) {
4428           case 0:
4429             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4430             break;
4431           case 1:
4432             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4433             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4434             emit_skip=0;
4435             break;
4436           case 0xff:
4437             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4438             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4439             emit_skip=0;
4440             break;
4441           default:
4442             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4443             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4444           }
4445           lit >>= 8;
4446
4447         } else {
4448           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4449         }
4450         if(emit_skip) {
4451           if(AOP_TYPE(result) == AOP_CRY) {
4452             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4453             if(rIfx.condition)
4454               emitSKPNZ;
4455             else
4456               emitSKPZ;
4457             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4458           } else {
4459             /* fix me. probably need to check result size too */
4460             emitpcode(POC_CLRF,popGet(AOP(result),0));
4461             if(rIfx.condition)
4462               emitSKPNZ;
4463             else
4464               emitSKPZ;
4465             emitpcode(POC_INCF,popGet(AOP(result),0));
4466           }
4467           if(ifx)
4468             ifx->generated=1;
4469         }
4470         emit_skip++;
4471         offset++;
4472       }
4473       break;
4474     }
4475   } else if(AOP_TYPE(right) == AOP_REG &&
4476             AOP_TYPE(left) != AOP_DIR){
4477
4478     while(size--) {
4479       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4480       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4481       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4482       if(rIfx.condition)
4483         emitSKPNZ;
4484       else
4485         emitSKPZ;
4486       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4487       offset++;
4488     }
4489       
4490   }else{
4491     /* right is a pointer reg need both a & b */
4492     while(size--) {
4493       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4494       if(strcmp(l,"b"))
4495         pic14_emitcode("mov","b,%s",l);
4496       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4497       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4498       offset++;
4499     }
4500   }
4501   emitpLabel(lbl->key);
4502
4503   if(ifx)
4504     ifx->generated = 1;
4505 }
4506
4507 #if 0
4508 /*-----------------------------------------------------------------*/
4509 /* gencjne - compare and jump if not equal                         */
4510 /*-----------------------------------------------------------------*/
4511 static void gencjne(operand *left, operand *right, iCode *ifx)
4512 {
4513     symbol *tlbl  = newiTempLabel(NULL);
4514
4515     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4516     gencjneshort(left, right, lbl);
4517
4518     pic14_emitcode("mov","a,%s",one);
4519     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4520     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4521     pic14_emitcode("clr","a");
4522     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4523
4524     emitpLabel(lbl->key);
4525     emitpLabel(tlbl->key);
4526
4527 }
4528 #endif
4529
4530 /*-----------------------------------------------------------------*/
4531 /* genCmpEq - generates code for equal to                          */
4532 /*-----------------------------------------------------------------*/
4533 static void genCmpEq (iCode *ic, iCode *ifx)
4534 {
4535     operand *left, *right, *result;
4536     unsigned long lit = 0L;
4537     int size,offset=0;
4538
4539     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4540
4541     if(ifx)
4542       DEBUGpic14_emitcode ("; ifx is non-null","");
4543     else
4544       DEBUGpic14_emitcode ("; ifx is null","");
4545
4546     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4547     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4548     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4549
4550     size = max(AOP_SIZE(left),AOP_SIZE(right));
4551
4552     DEBUGpic14_AopType(__LINE__,left,right,result);
4553
4554     /* if literal, literal on the right or 
4555     if the right is in a pointer register and left 
4556     is not */
4557     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4558         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4559       operand *tmp = right ;
4560       right = left;
4561       left = tmp;
4562     }
4563
4564
4565     if(ifx && !AOP_SIZE(result)){
4566         symbol *tlbl;
4567         /* if they are both bit variables */
4568         if (AOP_TYPE(left) == AOP_CRY &&
4569             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4570             if(AOP_TYPE(right) == AOP_LIT){
4571                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4572                 if(lit == 0L){
4573                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4574                     pic14_emitcode("cpl","c");
4575                 } else if(lit == 1L) {
4576                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4577                 } else {
4578                     pic14_emitcode("clr","c");
4579                 }
4580                 /* AOP_TYPE(right) == AOP_CRY */
4581             } else {
4582                 symbol *lbl = newiTempLabel(NULL);
4583                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4584                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4585                 pic14_emitcode("cpl","c");
4586                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4587             }
4588             /* if true label then we jump if condition
4589             supplied is true */
4590             tlbl = newiTempLabel(NULL);
4591             if ( IC_TRUE(ifx) ) {
4592                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4593                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4594             } else {
4595                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4596                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4597             }
4598             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4599
4600             {
4601               /* left and right are both bit variables, result is carry */
4602               resolvedIfx rIfx;
4603               
4604               resolveIfx(&rIfx,ifx);
4605
4606               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4607               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4608               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4609               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4610               genSkipz2(&rIfx);
4611             }
4612         } else {
4613
4614           /* They're not both bit variables. Is the right a literal? */
4615           if(AOP_TYPE(right) == AOP_LIT) {
4616             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4617             
4618             switch(size) {
4619
4620             case 1:
4621               switch(lit & 0xff) {
4622               case 1:
4623                 if ( IC_TRUE(ifx) ) {
4624                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4625                   emitSKPNZ;
4626                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4627                 } else {
4628                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4630                 }
4631                 break;
4632               case 0xff:
4633                 if ( IC_TRUE(ifx) ) {
4634                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4635                   emitSKPNZ;
4636                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4637                 } else {
4638                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4639                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4640                 }
4641                 break;
4642               default:
4643                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4644                 if(lit)
4645                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4646                 genSkip(ifx,'z');
4647               }
4648
4649
4650               /* end of size == 1 */
4651               break;
4652               
4653             case 2:
4654               genc16bit2lit(left,lit,offset);
4655               genSkip(ifx,'z');
4656               break;
4657               /* end of size == 2 */
4658
4659             default:
4660               /* size is 4 */
4661               if(lit==0) {
4662                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4663                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4664                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4665                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4666
4667               } else {
4668
4669                 /* search for patterns that can be optimized */
4670
4671                 genc16bit2lit(left,lit,0);
4672                 lit >>= 16;
4673                 if(lit) {
4674                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4675                   //genSkip(ifx,'z');
4676                   genc16bit2lit(left,lit,2);
4677                 } else {
4678                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4679                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4680
4681                 }
4682                 
4683               }
4684
4685               genSkip(ifx,'z');
4686             }
4687           
4688             ifx->generated = 1;
4689             goto release ;
4690             
4691
4692           } else if(AOP_TYPE(right) == AOP_CRY ) {
4693             /* we know the left is not a bit, but that the right is */
4694             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4695             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4696                       popGet(AOP(right),offset));
4697             emitpcode(POC_XORLW,popGetLit(1));
4698
4699             /* if the two are equal, then W will be 0 and the Z bit is set
4700              * we could test Z now, or go ahead and check the high order bytes if
4701              * the variable we're comparing is larger than a byte. */
4702
4703             while(--size)
4704               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4705
4706             if ( IC_TRUE(ifx) ) {
4707               emitSKPNZ;
4708               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4709               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4710             } else {
4711               emitSKPZ;
4712               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4713               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4714             }
4715
4716           } else {
4717             /* They're both variables that are larger than bits */
4718             int s = size;
4719
4720             tlbl = newiTempLabel(NULL);
4721
4722             while(size--) {
4723               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4724               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4725
4726               if ( IC_TRUE(ifx) ) {
4727                 if(size) {
4728                   emitSKPZ;
4729                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4730                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4731                 } else {
4732                   emitSKPNZ;
4733                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4734                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4735                 }
4736               } else {
4737                 emitSKPZ;
4738                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4739                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4740               }
4741               offset++;
4742             }
4743             if(s>1 && IC_TRUE(ifx)) {
4744               emitpLabel(tlbl->key);
4745               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4746             }
4747           }
4748         }
4749         /* mark the icode as generated */
4750         ifx->generated = 1;
4751         goto release ;
4752     }
4753
4754     /* if they are both bit variables */
4755     if (AOP_TYPE(left) == AOP_CRY &&
4756         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4757         if(AOP_TYPE(right) == AOP_LIT){
4758             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4759             if(lit == 0L){
4760                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4761                 pic14_emitcode("cpl","c");
4762             } else if(lit == 1L) {
4763                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4764             } else {
4765                 pic14_emitcode("clr","c");
4766             }
4767             /* AOP_TYPE(right) == AOP_CRY */
4768         } else {
4769             symbol *lbl = newiTempLabel(NULL);
4770             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4771             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4772             pic14_emitcode("cpl","c");
4773             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4774         }
4775         /* c = 1 if egal */
4776         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4777             pic14_outBitC(result);
4778             goto release ;
4779         }
4780         if (ifx) {
4781             genIfxJump (ifx,"c");
4782             goto release ;
4783         }
4784         /* if the result is used in an arithmetic operation
4785         then put the result in place */
4786         pic14_outBitC(result);
4787     } else {
4788       
4789       gencjne(left,right,result,ifx);
4790 /*
4791       if(ifx) 
4792         gencjne(left,right,newiTempLabel(NULL));
4793       else {
4794         if(IC_TRUE(ifx)->key)
4795           gencjne(left,right,IC_TRUE(ifx)->key);
4796         else
4797           gencjne(left,right,IC_FALSE(ifx)->key);
4798         ifx->generated = 1;
4799         goto release ;
4800       }
4801       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4802         aopPut(AOP(result),"a",0);
4803         goto release ;
4804       }
4805
4806       if (ifx) {
4807         genIfxJump (ifx,"a");
4808         goto release ;
4809       }
4810 */
4811       /* if the result is used in an arithmetic operation
4812          then put the result in place */
4813 /*
4814       if (AOP_TYPE(result) != AOP_CRY) 
4815         pic14_outAcc(result);
4816 */
4817       /* leave the result in acc */
4818     }
4819
4820 release:
4821     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4822     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4823     freeAsmop(result,NULL,ic,TRUE);
4824 }
4825
4826 /*-----------------------------------------------------------------*/
4827 /* ifxForOp - returns the icode containing the ifx for operand     */
4828 /*-----------------------------------------------------------------*/
4829 static iCode *ifxForOp ( operand *op, iCode *ic )
4830 {
4831     /* if true symbol then needs to be assigned */
4832     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4833     if (IS_TRUE_SYMOP(op))
4834         return NULL ;
4835
4836     /* if this has register type condition and
4837     the next instruction is ifx with the same operand
4838     and live to of the operand is upto the ifx only then */
4839     if (ic->next &&
4840         ic->next->op == IFX &&
4841         IC_COND(ic->next)->key == op->key &&
4842         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4843         return ic->next;
4844
4845     if (ic->next &&
4846         ic->next->op == IFX &&
4847         IC_COND(ic->next)->key == op->key) {
4848       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4849       return ic->next;
4850     }
4851
4852     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4853     if (ic->next &&
4854         ic->next->op == IFX)
4855       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4856
4857     if (ic->next &&
4858         ic->next->op == IFX &&
4859         IC_COND(ic->next)->key == op->key) {
4860       DEBUGpic14_emitcode ("; "," key is okay");
4861       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4862                            OP_SYMBOL(op)->liveTo,
4863                            ic->next->seq);
4864     }
4865
4866
4867     return NULL;
4868 }
4869 /*-----------------------------------------------------------------*/
4870 /* genAndOp - for && operation                                     */
4871 /*-----------------------------------------------------------------*/
4872 static void genAndOp (iCode *ic)
4873 {
4874     operand *left,*right, *result;
4875     symbol *tlbl;
4876
4877     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4878     /* note here that && operations that are in an
4879     if statement are taken away by backPatchLabels
4880     only those used in arthmetic operations remain */
4881     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4882     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4883     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4884
4885     /* if both are bit variables */
4886     if (AOP_TYPE(left) == AOP_CRY &&
4887         AOP_TYPE(right) == AOP_CRY ) {
4888         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4889         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4890         pic14_outBitC(result);
4891     } else {
4892         tlbl = newiTempLabel(NULL);
4893         pic14_toBoolean(left);    
4894         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4895         pic14_toBoolean(right);
4896         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4897         pic14_outBitAcc(result);
4898     }
4899
4900     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4901     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4902     freeAsmop(result,NULL,ic,TRUE);
4903 }
4904
4905
4906 /*-----------------------------------------------------------------*/
4907 /* genOrOp - for || operation                                      */
4908 /*-----------------------------------------------------------------*/
4909 /*
4910   tsd pic port -
4911   modified this code, but it doesn't appear to ever get called
4912 */
4913
4914 static void genOrOp (iCode *ic)
4915 {
4916     operand *left,*right, *result;
4917     symbol *tlbl;
4918
4919     /* note here that || operations that are in an
4920     if statement are taken away by backPatchLabels
4921     only those used in arthmetic operations remain */
4922     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4923     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4924     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4925     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4926
4927     DEBUGpic14_AopType(__LINE__,left,right,result);
4928
4929     /* if both are bit variables */
4930     if (AOP_TYPE(left) == AOP_CRY &&
4931         AOP_TYPE(right) == AOP_CRY ) {
4932       pic14_emitcode("clrc","");
4933       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4934                AOP(left)->aopu.aop_dir,
4935                AOP(left)->aopu.aop_dir);
4936       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4937                AOP(right)->aopu.aop_dir,
4938                AOP(right)->aopu.aop_dir);
4939       pic14_emitcode("setc","");
4940
4941     } else {
4942         tlbl = newiTempLabel(NULL);
4943         pic14_toBoolean(left);
4944         emitSKPZ;
4945         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4946         pic14_toBoolean(right);
4947         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4948
4949         pic14_outBitAcc(result);
4950     }
4951
4952     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4953     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4954     freeAsmop(result,NULL,ic,TRUE);            
4955 }
4956
4957 /*-----------------------------------------------------------------*/
4958 /* isLiteralBit - test if lit == 2^n                               */
4959 /*-----------------------------------------------------------------*/
4960 static int isLiteralBit(unsigned long lit)
4961 {
4962     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4963     0x100L,0x200L,0x400L,0x800L,
4964     0x1000L,0x2000L,0x4000L,0x8000L,
4965     0x10000L,0x20000L,0x40000L,0x80000L,
4966     0x100000L,0x200000L,0x400000L,0x800000L,
4967     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4968     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4969     int idx;
4970     
4971     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4972     for(idx = 0; idx < 32; idx++)
4973         if(lit == pw[idx])
4974             return idx+1;
4975     return 0;
4976 }
4977
4978 /*-----------------------------------------------------------------*/
4979 /* continueIfTrue -                                                */
4980 /*-----------------------------------------------------------------*/
4981 static void continueIfTrue (iCode *ic)
4982 {
4983     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4984     if(IC_TRUE(ic))
4985         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4986     ic->generated = 1;
4987 }
4988
4989 /*-----------------------------------------------------------------*/
4990 /* jmpIfTrue -                                                     */
4991 /*-----------------------------------------------------------------*/
4992 static void jumpIfTrue (iCode *ic)
4993 {
4994     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4995     if(!IC_TRUE(ic))
4996         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4997     ic->generated = 1;
4998 }
4999
5000 /*-----------------------------------------------------------------*/
5001 /* jmpTrueOrFalse -                                                */
5002 /*-----------------------------------------------------------------*/
5003 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5004 {
5005     // ugly but optimized by peephole
5006     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5007     if(IC_TRUE(ic)){
5008         symbol *nlbl = newiTempLabel(NULL);
5009         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5010         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5011         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5012         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5013     }
5014     else{
5015         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5016         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5017     }
5018     ic->generated = 1;
5019 }
5020
5021 /*-----------------------------------------------------------------*/
5022 /* genAnd  - code for and                                          */
5023 /*-----------------------------------------------------------------*/
5024 static void genAnd (iCode *ic, iCode *ifx)
5025 {
5026   operand *left, *right, *result;
5027   int size, offset=0;  
5028   unsigned long lit = 0L;
5029   int bytelit = 0;
5030   resolvedIfx rIfx;
5031
5032
5033   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5034   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5035   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5036   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5037
5038   resolveIfx(&rIfx,ifx);
5039
5040   /* if left is a literal & right is not then exchange them */
5041   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5042       AOP_NEEDSACC(left)) {
5043     operand *tmp = right ;
5044     right = left;
5045     left = tmp;
5046   }
5047
5048   /* if result = right then exchange them */
5049   if(pic14_sameRegs(AOP(result),AOP(right))){
5050     operand *tmp = right ;
5051     right = left;
5052     left = tmp;
5053   }
5054
5055   /* if right is bit then exchange them */
5056   if (AOP_TYPE(right) == AOP_CRY &&
5057       AOP_TYPE(left) != AOP_CRY){
5058     operand *tmp = right ;
5059     right = left;
5060     left = tmp;
5061   }
5062   if(AOP_TYPE(right) == AOP_LIT)
5063     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5064
5065   size = AOP_SIZE(result);
5066
5067   DEBUGpic14_AopType(__LINE__,left,right,result);
5068
5069   // if(bit & yy)
5070   // result = bit & yy;
5071   if (AOP_TYPE(left) == AOP_CRY){
5072     // c = bit & literal;
5073     if(AOP_TYPE(right) == AOP_LIT){
5074       if(lit & 1) {
5075         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5076           // no change
5077           goto release;
5078         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5079       } else {
5080         // bit(result) = 0;
5081         if(size && (AOP_TYPE(result) == AOP_CRY)){
5082           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5083           goto release;
5084         }
5085         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5086           jumpIfTrue(ifx);
5087           goto release;
5088         }
5089         pic14_emitcode("clr","c");
5090       }
5091     } else {
5092       if (AOP_TYPE(right) == AOP_CRY){
5093         // c = bit & bit;
5094         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5095         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5096       } else {
5097         // c = bit & val;
5098         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5099         // c = lsb
5100         pic14_emitcode("rrc","a");
5101         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5102       }
5103     }
5104     // bit = c
5105     // val = c
5106     if(size)
5107       pic14_outBitC(result);
5108     // if(bit & ...)
5109     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5110       genIfxJump(ifx, "c");           
5111     goto release ;
5112   }
5113
5114   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5115   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5116   if((AOP_TYPE(right) == AOP_LIT) &&
5117      (AOP_TYPE(result) == AOP_CRY) &&
5118      (AOP_TYPE(left) != AOP_CRY)){
5119     int posbit = isLiteralBit(lit);
5120     /* left &  2^n */
5121     if(posbit){
5122       posbit--;
5123       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5124       // bit = left & 2^n
5125       if(size)
5126         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5127       // if(left &  2^n)
5128       else{
5129         if(ifx){
5130 /*
5131           if(IC_TRUE(ifx)) {
5132             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5133             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5134           } else {
5135             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5136             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5137           }
5138 */
5139           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5140                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5141           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5142           
5143           ifx->generated = 1;
5144         }
5145         goto release;
5146       }
5147     } else {
5148       symbol *tlbl = newiTempLabel(NULL);
5149       int sizel = AOP_SIZE(left);
5150       if(size)
5151         pic14_emitcode("setb","c");
5152       while(sizel--){
5153         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5154           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5155           // byte ==  2^n ?
5156           if((posbit = isLiteralBit(bytelit)) != 0)
5157             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5158           else{
5159             if(bytelit != 0x0FFL)
5160               pic14_emitcode("anl","a,%s",
5161                              aopGet(AOP(right),offset,FALSE,TRUE));
5162             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5163           }
5164         }
5165         offset++;
5166       }
5167       // bit = left & literal
5168       if(size){
5169         pic14_emitcode("clr","c");
5170         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5171       }
5172       // if(left & literal)
5173       else{
5174         if(ifx)
5175           jmpTrueOrFalse(ifx, tlbl);
5176         goto release ;
5177       }
5178     }
5179     pic14_outBitC(result);
5180     goto release ;
5181   }
5182
5183   /* if left is same as result */
5184   if(pic14_sameRegs(AOP(result),AOP(left))){
5185     int know_W = -1;
5186     for(;size--; offset++,lit>>=8) {
5187       if(AOP_TYPE(right) == AOP_LIT){
5188         switch(lit & 0xff) {
5189         case 0x00:
5190           /*  and'ing with 0 has clears the result */
5191           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5192           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5193           break;
5194         case 0xff:
5195           /* and'ing with 0xff is a nop when the result and left are the same */
5196           break;
5197
5198         default:
5199           {
5200             int p = my_powof2( (~lit) & 0xff );
5201             if(p>=0) {
5202               /* only one bit is set in the literal, so use a bcf instruction */
5203               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5204               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5205
5206             } else {
5207               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5208               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5209               if(know_W != (lit&0xff))
5210                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5211               know_W = lit &0xff;
5212               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5213             }
5214           }    
5215         }
5216       } else {
5217         if (AOP_TYPE(left) == AOP_ACC) {
5218           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5219         } else {                    
5220           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5221           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5222
5223         }
5224       }
5225     }
5226
5227   } else {
5228     // left & result in different registers
5229     if(AOP_TYPE(result) == AOP_CRY){
5230       // result = bit
5231       // if(size), result in bit
5232       // if(!size && ifx), conditional oper: if(left & right)
5233       symbol *tlbl = newiTempLabel(NULL);
5234       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5235       if(size)
5236         pic14_emitcode("setb","c");
5237       while(sizer--){
5238         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5239         pic14_emitcode("anl","a,%s",
5240                        aopGet(AOP(left),offset,FALSE,FALSE));
5241         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5242         offset++;
5243       }
5244       if(size){
5245         CLRC;
5246         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5247         pic14_outBitC(result);
5248       } else if(ifx)
5249         jmpTrueOrFalse(ifx, tlbl);
5250     } else {
5251       for(;(size--);offset++) {
5252         // normal case
5253         // result = left & right
5254         if(AOP_TYPE(right) == AOP_LIT){
5255           int t = (lit >> (offset*8)) & 0x0FFL;
5256           switch(t) { 
5257           case 0x00:
5258             pic14_emitcode("clrf","%s",
5259                            aopGet(AOP(result),offset,FALSE,FALSE));
5260             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5261             break;
5262           case 0xff:
5263             pic14_emitcode("movf","%s,w",
5264                            aopGet(AOP(left),offset,FALSE,FALSE));
5265             pic14_emitcode("movwf","%s",
5266                            aopGet(AOP(result),offset,FALSE,FALSE));
5267             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5268             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5269             break;
5270           default:
5271             pic14_emitcode("movlw","0x%x",t);
5272             pic14_emitcode("andwf","%s,w",
5273                            aopGet(AOP(left),offset,FALSE,FALSE));
5274             pic14_emitcode("movwf","%s",
5275                            aopGet(AOP(result),offset,FALSE,FALSE));
5276               
5277             emitpcode(POC_MOVLW, popGetLit(t));
5278             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5279             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5280           }
5281           continue;
5282         }
5283
5284         if (AOP_TYPE(left) == AOP_ACC) {
5285           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5286           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5287         } else {
5288           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5289           pic14_emitcode("andwf","%s,w",
5290                          aopGet(AOP(left),offset,FALSE,FALSE));
5291           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5292           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5293         }
5294         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5295         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5296       }
5297     }
5298   }
5299
5300   release :
5301     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5302   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5303   freeAsmop(result,NULL,ic,TRUE);     
5304 }
5305
5306 /*-----------------------------------------------------------------*/
5307 /* genOr  - code for or                                            */
5308 /*-----------------------------------------------------------------*/
5309 static void genOr (iCode *ic, iCode *ifx)
5310 {
5311     operand *left, *right, *result;
5312     int size, offset=0;
5313     unsigned long lit = 0L;
5314
5315     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5316
5317     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5318     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5319     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5320
5321     DEBUGpic14_AopType(__LINE__,left,right,result);
5322
5323     /* if left is a literal & right is not then exchange them */
5324     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5325         AOP_NEEDSACC(left)) {
5326         operand *tmp = right ;
5327         right = left;
5328         left = tmp;
5329     }
5330
5331     /* if result = right then exchange them */
5332     if(pic14_sameRegs(AOP(result),AOP(right))){
5333         operand *tmp = right ;
5334         right = left;
5335         left = tmp;
5336     }
5337
5338     /* if right is bit then exchange them */
5339     if (AOP_TYPE(right) == AOP_CRY &&
5340         AOP_TYPE(left) != AOP_CRY){
5341         operand *tmp = right ;
5342         right = left;
5343         left = tmp;
5344     }
5345
5346     DEBUGpic14_AopType(__LINE__,left,right,result);
5347
5348     if(AOP_TYPE(right) == AOP_LIT)
5349         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5350
5351     size = AOP_SIZE(result);
5352
5353     // if(bit | yy)
5354     // xx = bit | yy;
5355     if (AOP_TYPE(left) == AOP_CRY){
5356         if(AOP_TYPE(right) == AOP_LIT){
5357             // c = bit & literal;
5358             if(lit){
5359                 // lit != 0 => result = 1
5360                 if(AOP_TYPE(result) == AOP_CRY){
5361                   if(size)
5362                     emitpcode(POC_BSF, popGet(AOP(result),0));
5363                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5364                   //     AOP(result)->aopu.aop_dir,
5365                   //     AOP(result)->aopu.aop_dir);
5366                     else if(ifx)
5367                         continueIfTrue(ifx);
5368                     goto release;
5369                 }
5370             } else {
5371                 // lit == 0 => result = left
5372                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5373                     goto release;
5374                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5375             }
5376         } else {
5377             if (AOP_TYPE(right) == AOP_CRY){
5378               if(pic14_sameRegs(AOP(result),AOP(left))){
5379                 // c = bit | bit;
5380                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5381                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5382                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5383
5384                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5385                          AOP(result)->aopu.aop_dir,
5386                          AOP(result)->aopu.aop_dir);
5387                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5388                          AOP(right)->aopu.aop_dir,
5389                          AOP(right)->aopu.aop_dir);
5390                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5391                          AOP(result)->aopu.aop_dir,
5392                          AOP(result)->aopu.aop_dir);
5393               } else {
5394                 if( AOP_TYPE(result) == AOP_ACC) {
5395                   emitpcode(POC_MOVLW, popGetLit(0));
5396                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5397                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5398                   emitpcode(POC_MOVLW, popGetLit(1));
5399
5400                 } else {
5401
5402                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5403                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5404                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5405                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5406
5407                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5408                                  AOP(result)->aopu.aop_dir,
5409                                  AOP(result)->aopu.aop_dir);
5410                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5411                                  AOP(right)->aopu.aop_dir,
5412                                  AOP(right)->aopu.aop_dir);
5413                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5414                                  AOP(left)->aopu.aop_dir,
5415                                  AOP(left)->aopu.aop_dir);
5416                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5417                                  AOP(result)->aopu.aop_dir,
5418                                  AOP(result)->aopu.aop_dir);
5419                 }
5420               }
5421             } else {
5422                 // c = bit | val;
5423                 symbol *tlbl = newiTempLabel(NULL);
5424                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5425
5426
5427                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5428                 if( AOP_TYPE(right) == AOP_ACC) {
5429                   emitpcode(POC_IORLW, popGetLit(0));
5430                   emitSKPNZ;
5431                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5432                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5433                 }
5434
5435
5436
5437                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5438                     pic14_emitcode(";XXX setb","c");
5439                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5440                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5441                 pic14_toBoolean(right);
5442                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5443                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5444                     jmpTrueOrFalse(ifx, tlbl);
5445                     goto release;
5446                 } else {
5447                     CLRC;
5448                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5449                 }
5450             }
5451         }
5452         // bit = c
5453         // val = c
5454         if(size)
5455             pic14_outBitC(result);
5456         // if(bit | ...)
5457         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5458             genIfxJump(ifx, "c");           
5459         goto release ;
5460     }
5461
5462     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5463     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5464     if((AOP_TYPE(right) == AOP_LIT) &&
5465        (AOP_TYPE(result) == AOP_CRY) &&
5466        (AOP_TYPE(left) != AOP_CRY)){
5467         if(lit){
5468           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5469             // result = 1
5470             if(size)
5471                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5472             else 
5473                 continueIfTrue(ifx);
5474             goto release;
5475         } else {
5476           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5477             // lit = 0, result = boolean(left)
5478             if(size)
5479                 pic14_emitcode(";XXX setb","c");
5480             pic14_toBoolean(right);
5481             if(size){
5482                 symbol *tlbl = newiTempLabel(NULL);
5483                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5484                 CLRC;
5485                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5486             } else {
5487                 genIfxJump (ifx,"a");
5488                 goto release;
5489             }
5490         }
5491         pic14_outBitC(result);
5492         goto release ;
5493     }
5494
5495     /* if left is same as result */
5496     if(pic14_sameRegs(AOP(result),AOP(left))){
5497       int know_W = -1;
5498       for(;size--; offset++,lit>>=8) {
5499         if(AOP_TYPE(right) == AOP_LIT){
5500           if((lit & 0xff) == 0)
5501             /*  or'ing with 0 has no effect */
5502             continue;
5503           else {
5504             int p = my_powof2(lit & 0xff);
5505             if(p>=0) {
5506               /* only one bit is set in the literal, so use a bsf instruction */
5507               emitpcode(POC_BSF,
5508                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5509             } else {
5510               if(know_W != (lit & 0xff))
5511                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5512               know_W = lit & 0xff;
5513               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5514             }
5515                     
5516           }
5517         } else {
5518           if (AOP_TYPE(left) == AOP_ACC) {
5519             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5520             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5521           } else {                  
5522             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5523             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5524
5525             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5526             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5527
5528           }
5529         }
5530       }
5531     } else {
5532         // left & result in different registers
5533         if(AOP_TYPE(result) == AOP_CRY){
5534             // result = bit
5535             // if(size), result in bit
5536             // if(!size && ifx), conditional oper: if(left | right)
5537             symbol *tlbl = newiTempLabel(NULL);
5538             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5539             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5540
5541
5542             if(size)
5543                 pic14_emitcode(";XXX setb","c");
5544             while(sizer--){
5545                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5546                 pic14_emitcode(";XXX orl","a,%s",
5547                          aopGet(AOP(left),offset,FALSE,FALSE));
5548                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5549                 offset++;
5550             }
5551             if(size){
5552                 CLRC;
5553                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5554                 pic14_outBitC(result);
5555             } else if(ifx)
5556                 jmpTrueOrFalse(ifx, tlbl);
5557         } else for(;(size--);offset++){
5558           // normal case
5559           // result = left & right
5560           if(AOP_TYPE(right) == AOP_LIT){
5561             int t = (lit >> (offset*8)) & 0x0FFL;
5562             switch(t) { 
5563             case 0x00:
5564               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5565               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5566
5567               pic14_emitcode("movf","%s,w",
5568                        aopGet(AOP(left),offset,FALSE,FALSE));
5569               pic14_emitcode("movwf","%s",
5570                        aopGet(AOP(result),offset,FALSE,FALSE));
5571               break;
5572             default:
5573               emitpcode(POC_MOVLW,  popGetLit(t));
5574               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5575               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5576
5577               pic14_emitcode("movlw","0x%x",t);
5578               pic14_emitcode("iorwf","%s,w",
5579                        aopGet(AOP(left),offset,FALSE,FALSE));
5580               pic14_emitcode("movwf","%s",
5581                        aopGet(AOP(result),offset,FALSE,FALSE));
5582               
5583             }
5584             continue;
5585           }
5586
5587           // faster than result <- left, anl result,right
5588           // and better if result is SFR
5589           if (AOP_TYPE(left) == AOP_ACC) {
5590             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5591             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5592           } else {
5593             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5594             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5595
5596             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5597             pic14_emitcode("iorwf","%s,w",
5598                      aopGet(AOP(left),offset,FALSE,FALSE));
5599           }
5600           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5601           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5602         }
5603     }
5604
5605 release :
5606     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5607     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5608     freeAsmop(result,NULL,ic,TRUE);     
5609 }
5610
5611 /*-----------------------------------------------------------------*/
5612 /* genXor - code for xclusive or                                   */
5613 /*-----------------------------------------------------------------*/
5614 static void genXor (iCode *ic, iCode *ifx)
5615 {
5616   operand *left, *right, *result;
5617   int size, offset=0;
5618   unsigned long lit = 0L;
5619
5620   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5621
5622   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5623   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5624   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5625
5626   /* if left is a literal & right is not ||
5627      if left needs acc & right does not */
5628   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5629       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5630     operand *tmp = right ;
5631     right = left;
5632     left = tmp;
5633   }
5634
5635   /* if result = right then exchange them */
5636   if(pic14_sameRegs(AOP(result),AOP(right))){
5637     operand *tmp = right ;
5638     right = left;
5639     left = tmp;
5640   }
5641
5642   /* if right is bit then exchange them */
5643   if (AOP_TYPE(right) == AOP_CRY &&
5644       AOP_TYPE(left) != AOP_CRY){
5645     operand *tmp = right ;
5646     right = left;
5647     left = tmp;
5648   }
5649   if(AOP_TYPE(right) == AOP_LIT)
5650     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5651
5652   size = AOP_SIZE(result);
5653
5654   // if(bit ^ yy)
5655   // xx = bit ^ yy;
5656   if (AOP_TYPE(left) == AOP_CRY){
5657     if(AOP_TYPE(right) == AOP_LIT){
5658       // c = bit & literal;
5659       if(lit>>1){
5660         // lit>>1  != 0 => result = 1
5661         if(AOP_TYPE(result) == AOP_CRY){
5662           if(size)
5663             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5664             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5665           else if(ifx)
5666             continueIfTrue(ifx);
5667           goto release;
5668         }
5669         pic14_emitcode("setb","c");
5670       } else{
5671         // lit == (0 or 1)
5672         if(lit == 0){
5673           // lit == 0, result = left
5674           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5675             goto release;
5676           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5677         } else{
5678           // lit == 1, result = not(left)
5679           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5680             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5681             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5682             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5683             goto release;
5684           } else {
5685             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5686             pic14_emitcode("cpl","c");
5687           }
5688         }
5689       }
5690
5691     } else {
5692       // right != literal
5693       symbol *tlbl = newiTempLabel(NULL);
5694       if (AOP_TYPE(right) == AOP_CRY){
5695         // c = bit ^ bit;
5696         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5697       }
5698       else{
5699         int sizer = AOP_SIZE(right);
5700         // c = bit ^ val
5701         // if val>>1 != 0, result = 1
5702         pic14_emitcode("setb","c");
5703         while(sizer){
5704           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5705           if(sizer == 1)
5706             // test the msb of the lsb
5707             pic14_emitcode("anl","a,#0xfe");
5708           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5709           sizer--;
5710         }
5711         // val = (0,1)
5712         pic14_emitcode("rrc","a");
5713       }
5714       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5715       pic14_emitcode("cpl","c");
5716       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5717     }
5718     // bit = c
5719     // val = c
5720     if(size)
5721       pic14_outBitC(result);
5722     // if(bit | ...)
5723     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5724       genIfxJump(ifx, "c");           
5725     goto release ;
5726   }
5727
5728   if(pic14_sameRegs(AOP(result),AOP(left))){
5729     /* if left is same as result */
5730     for(;size--; offset++) {
5731       if(AOP_TYPE(right) == AOP_LIT){
5732         int t  = (lit >> (offset*8)) & 0x0FFL;
5733         if(t == 0x00L)
5734           continue;
5735         else
5736           if (IS_AOP_PREG(left)) {
5737             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5738             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5739             aopPut(AOP(result),"a",offset);
5740           } else {
5741             emitpcode(POC_MOVLW, popGetLit(t));
5742             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5743             pic14_emitcode("xrl","%s,%s",
5744                            aopGet(AOP(left),offset,FALSE,TRUE),
5745                            aopGet(AOP(right),offset,FALSE,FALSE));
5746           }
5747       } else {
5748         if (AOP_TYPE(left) == AOP_ACC)
5749           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5750         else {
5751           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5752           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5753 /*
5754           if (IS_AOP_PREG(left)) {
5755             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5756             aopPut(AOP(result),"a",offset);
5757           } else
5758             pic14_emitcode("xrl","%s,a",
5759                            aopGet(AOP(left),offset,FALSE,TRUE));
5760 */
5761         }
5762       }
5763     }
5764   } else {
5765     // left & result in different registers
5766     if(AOP_TYPE(result) == AOP_CRY){
5767       // result = bit
5768       // if(size), result in bit
5769       // if(!size && ifx), conditional oper: if(left ^ right)
5770       symbol *tlbl = newiTempLabel(NULL);
5771       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5772       if(size)
5773         pic14_emitcode("setb","c");
5774       while(sizer--){
5775         if((AOP_TYPE(right) == AOP_LIT) &&
5776            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5777           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5778         } else {
5779           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5780           pic14_emitcode("xrl","a,%s",
5781                          aopGet(AOP(left),offset,FALSE,FALSE));
5782         }
5783         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5784         offset++;
5785       }
5786       if(size){
5787         CLRC;
5788         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5789         pic14_outBitC(result);
5790       } else if(ifx)
5791         jmpTrueOrFalse(ifx, tlbl);
5792     } else for(;(size--);offset++){
5793       // normal case
5794       // result = left & right
5795       if(AOP_TYPE(right) == AOP_LIT){
5796         int t = (lit >> (offset*8)) & 0x0FFL;
5797         switch(t) { 
5798         case 0x00:
5799           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5800           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5801           pic14_emitcode("movf","%s,w",
5802                          aopGet(AOP(left),offset,FALSE,FALSE));
5803           pic14_emitcode("movwf","%s",
5804                          aopGet(AOP(result),offset,FALSE,FALSE));
5805           break;
5806         case 0xff:
5807           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5808           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5809           pic14_emitcode("comf","%s,w",
5810                          aopGet(AOP(left),offset,FALSE,FALSE));
5811           pic14_emitcode("movwf","%s",
5812                          aopGet(AOP(result),offset,FALSE,FALSE));
5813           break;
5814         default:
5815           emitpcode(POC_MOVLW, popGetLit(t));
5816           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5817           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5818           pic14_emitcode("movlw","0x%x",t);
5819           pic14_emitcode("xorwf","%s,w",
5820                          aopGet(AOP(left),offset,FALSE,FALSE));
5821           pic14_emitcode("movwf","%s",
5822                          aopGet(AOP(result),offset,FALSE,FALSE));
5823
5824         }
5825         continue;
5826       }
5827
5828       // faster than result <- left, anl result,right
5829       // and better if result is SFR
5830       if (AOP_TYPE(left) == AOP_ACC) {
5831         emitpcode(POC_XORFW,popGet(AOP(right),offset));
5832         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5833       } else {
5834         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5835         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5836         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5837         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5838       }
5839       if ( AOP_TYPE(result) != AOP_ACC){
5840         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5841         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5842       }
5843     }
5844   }
5845
5846   release :
5847     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5848   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5849   freeAsmop(result,NULL,ic,TRUE);     
5850 }
5851
5852 /*-----------------------------------------------------------------*/
5853 /* genInline - write the inline code out                           */
5854 /*-----------------------------------------------------------------*/
5855 static void genInline (iCode *ic)
5856 {
5857     char *buffer, *bp, *bp1;
5858     
5859     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5860
5861     _G.inLine += (!options.asmpeep);
5862
5863     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5864     strcpy(buffer,IC_INLINE(ic));
5865
5866     /* emit each line as a code */
5867     while (*bp) {
5868         if (*bp == '\n') {
5869             *bp++ = '\0';
5870             pic14_emitcode(bp1,"");
5871             addpCode2pBlock(pb,newpCodeInlineP(bp1));
5872             bp1 = bp;
5873         } else {
5874             if (*bp == ':') {
5875                 bp++;
5876                 *bp = '\0';
5877                 bp++;
5878                 pic14_emitcode(bp1,"");
5879                 bp1 = bp;
5880             } else
5881                 bp++;
5882         }
5883     }
5884     if (bp1 != bp) {
5885         pic14_emitcode(bp1,"");
5886         addpCode2pBlock(pb,newpCodeInlineP(bp1));
5887     }
5888     /*     pic14_emitcode("",buffer); */
5889     _G.inLine -= (!options.asmpeep);
5890 }
5891
5892 /*-----------------------------------------------------------------*/
5893 /* genRRC - rotate right with carry                                */
5894 /*-----------------------------------------------------------------*/
5895 static void genRRC (iCode *ic)
5896 {
5897   operand *left , *result ;
5898   int size, offset = 0, same;
5899
5900   /* rotate right with carry */
5901   left = IC_LEFT(ic);
5902   result=IC_RESULT(ic);
5903   aopOp (left,ic,FALSE);
5904   aopOp (result,ic,FALSE);
5905
5906   DEBUGpic14_AopType(__LINE__,left,NULL,result);
5907
5908   same = pic14_sameRegs(AOP(result),AOP(left));
5909
5910   size = AOP_SIZE(result);    
5911
5912   /* get the lsb and put it into the carry */
5913   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5914
5915   offset = 0 ;
5916
5917   while(size--) {
5918
5919     if(same) {
5920       emitpcode(POC_RRF, popGet(AOP(left),offset));
5921     } else {
5922       emitpcode(POC_RRFW, popGet(AOP(left),offset));
5923       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5924     }
5925
5926     offset++;
5927   }
5928
5929   freeAsmop(left,NULL,ic,TRUE);
5930   freeAsmop(result,NULL,ic,TRUE);
5931 }
5932
5933 /*-----------------------------------------------------------------*/
5934 /* genRLC - generate code for rotate left with carry               */
5935 /*-----------------------------------------------------------------*/
5936 static void genRLC (iCode *ic)
5937 {    
5938   operand *left , *result ;
5939   int size, offset = 0;
5940   int same;
5941
5942   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5943   /* rotate right with carry */
5944   left = IC_LEFT(ic);
5945   result=IC_RESULT(ic);
5946   aopOp (left,ic,FALSE);
5947   aopOp (result,ic,FALSE);
5948
5949   DEBUGpic14_AopType(__LINE__,left,NULL,result);
5950
5951   same = pic14_sameRegs(AOP(result),AOP(left));
5952
5953   /* move it to the result */
5954   size = AOP_SIZE(result);    
5955
5956   /* get the msb and put it into the carry */
5957   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5958
5959   offset = 0 ;
5960
5961   while(size--) {
5962
5963     if(same) {
5964       emitpcode(POC_RLF, popGet(AOP(left),offset));
5965     } else {
5966       emitpcode(POC_RLFW, popGet(AOP(left),offset));
5967       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5968     }
5969
5970     offset++;
5971   }
5972
5973
5974   freeAsmop(left,NULL,ic,TRUE);
5975   freeAsmop(result,NULL,ic,TRUE);
5976 }
5977
5978 /*-----------------------------------------------------------------*/
5979 /* genGetHbit - generates code get highest order bit               */
5980 /*-----------------------------------------------------------------*/
5981 static void genGetHbit (iCode *ic)
5982 {
5983     operand *left, *result;
5984     left = IC_LEFT(ic);
5985     result=IC_RESULT(ic);
5986     aopOp (left,ic,FALSE);
5987     aopOp (result,ic,FALSE);
5988
5989     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5990     /* get the highest order byte into a */
5991     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5992     if(AOP_TYPE(result) == AOP_CRY){
5993         pic14_emitcode("rlc","a");
5994         pic14_outBitC(result);
5995     }
5996     else{
5997         pic14_emitcode("rl","a");
5998         pic14_emitcode("anl","a,#0x01");
5999         pic14_outAcc(result);
6000     }
6001
6002
6003     freeAsmop(left,NULL,ic,TRUE);
6004     freeAsmop(result,NULL,ic,TRUE);
6005 }
6006
6007 /*-----------------------------------------------------------------*/
6008 /* AccRol - rotate left accumulator by known count                 */
6009 /*-----------------------------------------------------------------*/
6010 static void AccRol (int shCount)
6011 {
6012     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6013     shCount &= 0x0007;              // shCount : 0..7
6014     switch(shCount){
6015         case 0 :
6016             break;
6017         case 1 :
6018             pic14_emitcode("rl","a");
6019             break;
6020         case 2 :
6021             pic14_emitcode("rl","a");
6022             pic14_emitcode("rl","a");
6023             break;
6024         case 3 :
6025             pic14_emitcode("swap","a");
6026             pic14_emitcode("rr","a");
6027             break;
6028         case 4 :
6029             pic14_emitcode("swap","a");
6030             break;
6031         case 5 :
6032             pic14_emitcode("swap","a");
6033             pic14_emitcode("rl","a");
6034             break;
6035         case 6 :
6036             pic14_emitcode("rr","a");
6037             pic14_emitcode("rr","a");
6038             break;
6039         case 7 :
6040             pic14_emitcode("rr","a");
6041             break;
6042     }
6043 }
6044
6045 /*-----------------------------------------------------------------*/
6046 /* AccLsh - left shift accumulator by known count                  */
6047 /*-----------------------------------------------------------------*/
6048 static void AccLsh (int shCount)
6049 {
6050     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6051     if(shCount != 0){
6052         if(shCount == 1)
6053             pic14_emitcode("add","a,acc");
6054         else 
6055             if(shCount == 2) {
6056             pic14_emitcode("add","a,acc");
6057             pic14_emitcode("add","a,acc");
6058         } else {
6059             /* rotate left accumulator */
6060             AccRol(shCount);
6061             /* and kill the lower order bits */
6062             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6063         }
6064     }
6065 }
6066
6067 /*-----------------------------------------------------------------*/
6068 /* AccRsh - right shift accumulator by known count                 */
6069 /*-----------------------------------------------------------------*/
6070 static void AccRsh (int shCount)
6071 {
6072     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6073     if(shCount != 0){
6074         if(shCount == 1){
6075             CLRC;
6076             pic14_emitcode("rrc","a");
6077         } else {
6078             /* rotate right accumulator */
6079             AccRol(8 - shCount);
6080             /* and kill the higher order bits */
6081             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6082         }
6083     }
6084 }
6085
6086 #if 0
6087 /*-----------------------------------------------------------------*/
6088 /* AccSRsh - signed right shift accumulator by known count                 */
6089 /*-----------------------------------------------------------------*/
6090 static void AccSRsh (int shCount)
6091 {
6092     symbol *tlbl ;
6093     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6094     if(shCount != 0){
6095         if(shCount == 1){
6096             pic14_emitcode("mov","c,acc.7");
6097             pic14_emitcode("rrc","a");
6098         } else if(shCount == 2){
6099             pic14_emitcode("mov","c,acc.7");
6100             pic14_emitcode("rrc","a");
6101             pic14_emitcode("mov","c,acc.7");
6102             pic14_emitcode("rrc","a");
6103         } else {
6104             tlbl = newiTempLabel(NULL);
6105             /* rotate right accumulator */
6106             AccRol(8 - shCount);
6107             /* and kill the higher order bits */
6108             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6109             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6110             pic14_emitcode("orl","a,#0x%02x",
6111                      (unsigned char)~SRMask[shCount]);
6112             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6113         }
6114     }
6115 }
6116 #endif
6117 /*-----------------------------------------------------------------*/
6118 /* shiftR1Left2Result - shift right one byte from left to result   */
6119 /*-----------------------------------------------------------------*/
6120 static void shiftR1Left2ResultSigned (operand *left, int offl,
6121                                 operand *result, int offr,
6122                                 int shCount)
6123 {
6124   int same;
6125
6126   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6127
6128   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6129
6130   switch(shCount) {
6131   case 1:
6132     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6133     if(same) 
6134       emitpcode(POC_RRF, popGet(AOP(result),offr));
6135     else {
6136       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6137       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6138     }
6139
6140     break;
6141   case 2:
6142
6143     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6144     if(same) 
6145       emitpcode(POC_RRF, popGet(AOP(result),offr));
6146     else {
6147       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6148       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6149     }
6150     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6151     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6152
6153     break;
6154
6155   case 3:
6156     if(same)
6157       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6158     else {
6159       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6160       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6161     }
6162
6163     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6164     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6165     emitpcode(POC_ANDLW, popGetLit(0x1f));
6166
6167     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6168     emitpcode(POC_IORLW, popGetLit(0xe0));
6169
6170     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6171     break;
6172
6173   case 4:
6174     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6175     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6176     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6177     emitpcode(POC_IORLW,  popGetLit(0xf0));
6178     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6179     break;
6180   case 5:
6181     if(same) {
6182       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6183     } else {
6184       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6185       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6186     }
6187     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6188     emitpcode(POC_ANDLW,  popGetLit(0x07));
6189     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6190     emitpcode(POC_IORLW,  popGetLit(0xf8));
6191     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6192     break;
6193
6194   case 6:
6195     if(same) {
6196       emitpcode(POC_MOVLW, popGetLit(0x00));
6197       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6198       emitpcode(POC_MOVLW, popGetLit(0xfe));
6199       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6200       emitpcode(POC_IORLW, popGetLit(0x01));
6201       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6202     } else {
6203       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6204       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6205       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6206       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6207       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6208     }
6209     break;
6210
6211   case 7:
6212     if(same) {
6213       emitpcode(POC_MOVLW, popGetLit(0x00));
6214       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6215       emitpcode(POC_MOVLW, popGetLit(0xff));
6216       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6217     } else {
6218       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6219       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6220       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6221     }
6222
6223   default:
6224     break;
6225   }
6226 }
6227
6228 /*-----------------------------------------------------------------*/
6229 /* shiftR1Left2Result - shift right one byte from left to result   */
6230 /*-----------------------------------------------------------------*/
6231 static void shiftR1Left2Result (operand *left, int offl,
6232                                 operand *result, int offr,
6233                                 int shCount, int sign)
6234 {
6235   int same;
6236
6237   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6238
6239   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6240
6241   /* Copy the msb into the carry if signed. */
6242   if(sign) {
6243     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6244     return;
6245   }
6246
6247
6248
6249   switch(shCount) {
6250   case 1:
6251     emitCLRC;
6252     if(same) 
6253       emitpcode(POC_RRF, popGet(AOP(result),offr));
6254     else {
6255       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6256       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6257     }
6258     break;
6259   case 2:
6260     emitCLRC;
6261     if(same) {
6262       emitpcode(POC_RRF, popGet(AOP(result),offr));
6263     } else {
6264       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6265       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6266     }
6267     emitCLRC;
6268     emitpcode(POC_RRF, popGet(AOP(result),offr));
6269
6270     break;
6271   case 3:
6272     if(same)
6273       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6274     else {
6275       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6276       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277     }
6278
6279     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6280     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6281     emitpcode(POC_ANDLW, popGetLit(0x1f));
6282     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6283     break;
6284       
6285   case 4:
6286     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6287     emitpcode(POC_ANDLW, popGetLit(0x0f));
6288     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6289     break;
6290
6291   case 5:
6292     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6293     emitpcode(POC_ANDLW, popGetLit(0x0f));
6294     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6295     emitCLRC;
6296     emitpcode(POC_RRF, popGet(AOP(result),offr));
6297
6298     break;
6299   case 6:
6300
6301     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6302     emitpcode(POC_ANDLW, popGetLit(0x80));
6303     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6304     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6305     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6306     break;
6307
6308   case 7:
6309
6310     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6311     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6312     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6313
6314     break;
6315
6316   default:
6317     break;
6318   }
6319 }
6320
6321 /*-----------------------------------------------------------------*/
6322 /* shiftL1Left2Result - shift left one byte from left to result    */
6323 /*-----------------------------------------------------------------*/
6324 static void shiftL1Left2Result (operand *left, int offl,
6325                                 operand *result, int offr, int shCount)
6326 {
6327   int same;
6328
6329   //    char *l;
6330   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6331
6332   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6333   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6334     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6335     //    MOVA(l);
6336     /* shift left accumulator */
6337     //AccLsh(shCount); // don't comment out just yet...
6338   //    aopPut(AOP(result),"a",offr);
6339
6340   switch(shCount) {
6341   case 1:
6342     /* Shift left 1 bit position */
6343     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6344     if(same) {
6345       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6346     } else {
6347       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6348       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6349     }
6350     break;
6351   case 2:
6352     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6353     emitpcode(POC_ANDLW,popGetLit(0x7e));
6354     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6355     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6356     break;
6357   case 3:
6358     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6359     emitpcode(POC_ANDLW,popGetLit(0x3e));
6360     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6361     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6362     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6363     break;
6364   case 4:
6365     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6366     emitpcode(POC_ANDLW, popGetLit(0xf0));
6367     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6368     break;
6369   case 5:
6370     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6371     emitpcode(POC_ANDLW, popGetLit(0xf0));
6372     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6373     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6374     break;
6375   case 6:
6376     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6377     emitpcode(POC_ANDLW, popGetLit(0x30));
6378     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6379     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6380     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6381     break;
6382   case 7:
6383     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6384     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6385     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6386     break;
6387
6388   default:
6389     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6390   }
6391
6392 }
6393
6394 /*-----------------------------------------------------------------*/
6395 /* movLeft2Result - move byte from left to result                  */
6396 /*-----------------------------------------------------------------*/
6397 static void movLeft2Result (operand *left, int offl,
6398                             operand *result, int offr)
6399 {
6400   char *l;
6401   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6402   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6403     l = aopGet(AOP(left),offl,FALSE,FALSE);
6404
6405     if (*l == '@' && (IS_AOP_PREG(result))) {
6406       pic14_emitcode("mov","a,%s",l);
6407       aopPut(AOP(result),"a",offr);
6408     } else {
6409       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6410       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6411     }
6412   }
6413 }
6414
6415 /*-----------------------------------------------------------------*/
6416 /* shiftL2Left2Result - shift left two bytes from left to result   */
6417 /*-----------------------------------------------------------------*/
6418 static void shiftL2Left2Result (operand *left, int offl,
6419                                 operand *result, int offr, int shCount)
6420 {
6421
6422
6423   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6424
6425   if(pic14_sameRegs(AOP(result), AOP(left))) {
6426     switch(shCount) {
6427     case 0:
6428       break;
6429     case 1:
6430     case 2:
6431     case 3:
6432
6433       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6434       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6435       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6436
6437       while(--shCount) {
6438         emitCLRC;
6439         emitpcode(POC_RLF, popGet(AOP(result),offr));
6440         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6441       }
6442
6443       break;
6444     case 4:
6445     case 5:
6446       emitpcode(POC_MOVLW, popGetLit(0x0f));
6447       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6448       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6449       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6450       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6451       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6452       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6453       if(shCount >=5) {
6454         emitpcode(POC_RLF, popGet(AOP(result),offr));
6455         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6456       }
6457       break;
6458     case 6:
6459       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6460       emitpcode(POC_RRF,  popGet(AOP(result),offr));
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(result),offr+MSB16));
6472       emitpcode(POC_RRFW, popGet(AOP(result),offr));
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   } else {
6479     switch(shCount) {
6480     case 0:
6481       break;
6482     case 1:
6483     case 2:
6484     case 3:
6485       /* note, use a mov/add for the shift since the mov has a
6486          chance of getting optimized out */
6487       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6488       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6490       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6491       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6492
6493       while(--shCount) {
6494         emitCLRC;
6495         emitpcode(POC_RLF, popGet(AOP(result),offr));
6496         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6497       }
6498       break;
6499
6500     case 4:
6501     case 5:
6502       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6503       emitpcode(POC_ANDLW, popGetLit(0xF0));
6504       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6505       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6506       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6507       emitpcode(POC_ANDLW, popGetLit(0xF0));
6508       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6509       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6510
6511
6512       if(shCount == 5) {
6513         emitpcode(POC_RLF, popGet(AOP(result),offr));
6514         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6515       }
6516       break;
6517     case 6:
6518       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6519       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6520       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6521       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6522
6523       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6524       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6525       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6526       emitpcode(POC_ANDLW,popGetLit(0xc0));
6527       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6528       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6529       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6530       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6531       break;
6532     case 7:
6533       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6534       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6535       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6536       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6537       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6538     }
6539   }
6540
6541 }
6542 /*-----------------------------------------------------------------*/
6543 /* shiftR2Left2Result - shift right two bytes from left to result  */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftR2Left2Result (operand *left, int offl,
6546                                 operand *result, int offr,
6547                                 int shCount, int sign)
6548 {
6549   int same=0;
6550
6551   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6552   same = pic14_sameRegs(AOP(result), AOP(left));
6553
6554   if(same && ((offl + MSB16) == offr)){
6555     same=1;
6556     /* don't crash result[offr] */
6557     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6558     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6559   } else {
6560     movLeft2Result(left,offl, result, offr);
6561     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6562   }
6563   /* a:x >> shCount (x = lsb(result))*/
6564 /*
6565   if(sign)
6566     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6567   else {
6568     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6569 */
6570   switch(shCount) {
6571   case 0:
6572     break;
6573   case 1:
6574   case 2:
6575   case 3:
6576     if(sign)
6577       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6578     else
6579       emitCLRC;
6580
6581     if(same) {
6582       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6583       emitpcode(POC_RRF,popGet(AOP(result),offr));
6584     } else {
6585       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6586       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6587       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6588       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589     }
6590
6591     while(--shCount) {
6592       if(sign)
6593         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6594       else
6595         emitCLRC;
6596       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6597       emitpcode(POC_RRF,popGet(AOP(result),offr));
6598     }
6599     break;
6600   case 4:
6601   case 5:
6602     if(same) {
6603
6604       emitpcode(POC_MOVLW, popGetLit(0xf0));
6605       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6606       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6607
6608       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6609       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6610       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6611       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6612     } else {
6613       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6614       emitpcode(POC_ANDLW, popGetLit(0x0f));
6615       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6616
6617       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6618       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6619       emitpcode(POC_ANDLW, popGetLit(0xf0));
6620       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6621       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6622     }
6623
6624     if(shCount >=5) {
6625       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6626       emitpcode(POC_RRF, popGet(AOP(result),offr));
6627     }
6628
6629     if(sign) {
6630       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6631       emitpcode(POC_BTFSC, 
6632                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6633       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6634     }
6635
6636     break;
6637
6638   case 6:
6639     if(same) {
6640
6641       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6642       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6643
6644       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6645       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6646       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6647       emitpcode(POC_ANDLW,popGetLit(0x03));
6648       if(sign) {
6649         emitpcode(POC_BTFSC, 
6650                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6651         emitpcode(POC_IORLW,popGetLit(0xfc));
6652       }
6653       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6654       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6655       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6656       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6657     } else {
6658       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6659       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6660       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6661       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6662       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6663       emitpcode(POC_ANDLW,popGetLit(0x03));
6664       if(sign) {
6665         emitpcode(POC_BTFSC, 
6666                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6667         emitpcode(POC_IORLW,popGetLit(0xfc));
6668       }
6669       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6670       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6671
6672         
6673     }
6674
6675     break;
6676   case 7:
6677     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6678     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6679     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6680     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6681     if(sign) {
6682       emitSKPNC;
6683       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6684     } else 
6685       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6686   }
6687 }
6688
6689
6690 /*-----------------------------------------------------------------*/
6691 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6692 /*-----------------------------------------------------------------*/
6693 static void shiftLLeftOrResult (operand *left, int offl,
6694                                 operand *result, int offr, int shCount)
6695 {
6696     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6697     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6698     /* shift left accumulator */
6699     AccLsh(shCount);
6700     /* or with result */
6701     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6702     /* back to result */
6703     aopPut(AOP(result),"a",offr);
6704 }
6705
6706 /*-----------------------------------------------------------------*/
6707 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6708 /*-----------------------------------------------------------------*/
6709 static void shiftRLeftOrResult (operand *left, int offl,
6710                                 operand *result, int offr, int shCount)
6711 {
6712     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6713     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6714     /* shift right accumulator */
6715     AccRsh(shCount);
6716     /* or with result */
6717     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6718     /* back to result */
6719     aopPut(AOP(result),"a",offr);
6720 }
6721
6722 /*-----------------------------------------------------------------*/
6723 /* genlshOne - left shift a one byte quantity by known count       */
6724 /*-----------------------------------------------------------------*/
6725 static void genlshOne (operand *result, operand *left, int shCount)
6726 {       
6727     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6728     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6729 }
6730
6731 /*-----------------------------------------------------------------*/
6732 /* genlshTwo - left shift two bytes by known amount != 0           */
6733 /*-----------------------------------------------------------------*/
6734 static void genlshTwo (operand *result,operand *left, int shCount)
6735 {
6736     int size;
6737     
6738     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6739     size = pic14_getDataSize(result);
6740
6741     /* if shCount >= 8 */
6742     if (shCount >= 8) {
6743         shCount -= 8 ;
6744
6745         if (size > 1){
6746             if (shCount)
6747                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6748             else 
6749                 movLeft2Result(left, LSB, result, MSB16);
6750         }
6751         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6752     }
6753
6754     /*  1 <= shCount <= 7 */
6755     else {  
6756         if(size == 1)
6757             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6758         else 
6759             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6760     }
6761 }
6762
6763 /*-----------------------------------------------------------------*/
6764 /* shiftLLong - shift left one long from left to result            */
6765 /* offl = LSB or MSB16                                             */
6766 /*-----------------------------------------------------------------*/
6767 static void shiftLLong (operand *left, operand *result, int offr )
6768 {
6769     char *l;
6770     int size = AOP_SIZE(result);
6771
6772     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6773     if(size >= LSB+offr){
6774         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6775         MOVA(l);
6776         pic14_emitcode("add","a,acc");
6777         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6778             size >= MSB16+offr && offr != LSB )
6779             pic14_emitcode("xch","a,%s",
6780                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6781         else        
6782             aopPut(AOP(result),"a",LSB+offr);
6783     }
6784
6785     if(size >= MSB16+offr){
6786         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6787             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6788             MOVA(l);
6789         }
6790         pic14_emitcode("rlc","a");
6791         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6792             size >= MSB24+offr && offr != LSB)
6793             pic14_emitcode("xch","a,%s",
6794                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6795         else        
6796             aopPut(AOP(result),"a",MSB16+offr);
6797     }
6798
6799     if(size >= MSB24+offr){
6800         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6801             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6802             MOVA(l);
6803         }
6804         pic14_emitcode("rlc","a");
6805         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6806             size >= MSB32+offr && offr != LSB )
6807             pic14_emitcode("xch","a,%s",
6808                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6809         else        
6810             aopPut(AOP(result),"a",MSB24+offr);
6811     }
6812
6813     if(size > MSB32+offr){
6814         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6815             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6816             MOVA(l);    
6817         }
6818         pic14_emitcode("rlc","a");
6819         aopPut(AOP(result),"a",MSB32+offr);
6820     }
6821     if(offr != LSB)
6822         aopPut(AOP(result),zero,LSB);       
6823 }
6824
6825 /*-----------------------------------------------------------------*/
6826 /* genlshFour - shift four byte by a known amount != 0             */
6827 /*-----------------------------------------------------------------*/
6828 static void genlshFour (operand *result, operand *left, int shCount)
6829 {
6830     int size;
6831
6832     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6833     size = AOP_SIZE(result);
6834
6835     /* if shifting more that 3 bytes */
6836     if (shCount >= 24 ) {
6837         shCount -= 24;
6838         if (shCount)
6839             /* lowest order of left goes to the highest
6840             order of the destination */
6841             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6842         else
6843             movLeft2Result(left, LSB, result, MSB32);
6844         aopPut(AOP(result),zero,LSB);
6845         aopPut(AOP(result),zero,MSB16);
6846         aopPut(AOP(result),zero,MSB32);
6847         return;
6848     }
6849
6850     /* more than two bytes */
6851     else if ( shCount >= 16 ) {
6852         /* lower order two bytes goes to higher order two bytes */
6853         shCount -= 16;
6854         /* if some more remaining */
6855         if (shCount)
6856             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6857         else {
6858             movLeft2Result(left, MSB16, result, MSB32);
6859             movLeft2Result(left, LSB, result, MSB24);
6860         }
6861         aopPut(AOP(result),zero,MSB16);
6862         aopPut(AOP(result),zero,LSB);
6863         return;
6864     }    
6865
6866     /* if more than 1 byte */
6867     else if ( shCount >= 8 ) {
6868         /* lower order three bytes goes to higher order  three bytes */
6869         shCount -= 8;
6870         if(size == 2){
6871             if(shCount)
6872                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6873             else
6874                 movLeft2Result(left, LSB, result, MSB16);
6875         }
6876         else{   /* size = 4 */
6877             if(shCount == 0){
6878                 movLeft2Result(left, MSB24, result, MSB32);
6879                 movLeft2Result(left, MSB16, result, MSB24);
6880                 movLeft2Result(left, LSB, result, MSB16);
6881                 aopPut(AOP(result),zero,LSB);
6882             }
6883             else if(shCount == 1)
6884                 shiftLLong(left, result, MSB16);
6885             else{
6886                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6887                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6888                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6889                 aopPut(AOP(result),zero,LSB);
6890             }
6891         }
6892     }
6893
6894     /* 1 <= shCount <= 7 */
6895     else if(shCount <= 2){
6896         shiftLLong(left, result, LSB);
6897         if(shCount == 2)
6898             shiftLLong(result, result, LSB);
6899     }
6900     /* 3 <= shCount <= 7, optimize */
6901     else{
6902         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6903         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6904         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6905     }
6906 }
6907
6908 /*-----------------------------------------------------------------*/
6909 /* genLeftShiftLiteral - left shifting by known count              */
6910 /*-----------------------------------------------------------------*/
6911 static void genLeftShiftLiteral (operand *left,
6912                                  operand *right,
6913                                  operand *result,
6914                                  iCode *ic)
6915 {    
6916     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6917     int size;
6918
6919     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6920     freeAsmop(right,NULL,ic,TRUE);
6921
6922     aopOp(left,ic,FALSE);
6923     aopOp(result,ic,FALSE);
6924
6925     size = getSize(operandType(result));
6926
6927 #if VIEW_SIZE
6928     pic14_emitcode("; shift left ","result %d, left %d",size,
6929              AOP_SIZE(left));
6930 #endif
6931
6932     /* I suppose that the left size >= result size */
6933     if(shCount == 0){
6934         while(size--){
6935             movLeft2Result(left, size, result, size);
6936         }
6937     }
6938
6939     else if(shCount >= (size * 8))
6940         while(size--)
6941             aopPut(AOP(result),zero,size);
6942     else{
6943         switch (size) {
6944             case 1:
6945                 genlshOne (result,left,shCount);
6946                 break;
6947
6948             case 2:
6949             case 3:
6950                 genlshTwo (result,left,shCount);
6951                 break;
6952
6953             case 4:
6954                 genlshFour (result,left,shCount);
6955                 break;
6956         }
6957     }
6958     freeAsmop(left,NULL,ic,TRUE);
6959     freeAsmop(result,NULL,ic,TRUE);
6960 }
6961
6962 /*-----------------------------------------------------------------*
6963  * genMultiAsm - repeat assembly instruction for size of register.
6964  * if endian == 1, then the high byte (i.e base address + size of 
6965  * register) is used first else the low byte is used first;
6966  *-----------------------------------------------------------------*/
6967 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6968 {
6969
6970   int offset = 0;
6971
6972   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6973
6974   if(!reg)
6975     return;
6976
6977   if(!endian) {
6978     endian = 1;
6979   } else {
6980     endian = -1;
6981     offset = size-1;
6982   }
6983
6984   while(size--) {
6985     emitpcode(poc,    popGet(AOP(reg),offset));
6986     offset += endian;
6987   }
6988
6989 }
6990 /*-----------------------------------------------------------------*/
6991 /* genLeftShift - generates code for left shifting                 */
6992 /*-----------------------------------------------------------------*/
6993 static void genLeftShift (iCode *ic)
6994 {
6995   operand *left,*right, *result;
6996   int size, offset;
6997   char *l;
6998   symbol *tlbl , *tlbl1;
6999   pCodeOp *pctemp;
7000
7001   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7002
7003   right = IC_RIGHT(ic);
7004   left  = IC_LEFT(ic);
7005   result = IC_RESULT(ic);
7006
7007   aopOp(right,ic,FALSE);
7008
7009   /* if the shift count is known then do it 
7010      as efficiently as possible */
7011   if (AOP_TYPE(right) == AOP_LIT) {
7012     genLeftShiftLiteral (left,right,result,ic);
7013     return ;
7014   }
7015
7016   /* shift count is unknown then we have to form 
7017      a loop get the loop count in B : Note: we take
7018      only the lower order byte since shifting
7019      more that 32 bits make no sense anyway, ( the
7020      largest size of an object can be only 32 bits ) */  
7021
7022     
7023   aopOp(left,ic,FALSE);
7024   aopOp(result,ic,FALSE);
7025
7026   /* now move the left to the result if they are not the
7027      same */
7028   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7029       AOP_SIZE(result) > 1) {
7030
7031     size = AOP_SIZE(result);
7032     offset=0;
7033     while (size--) {
7034       l = aopGet(AOP(left),offset,FALSE,TRUE);
7035       if (*l == '@' && (IS_AOP_PREG(result))) {
7036
7037         pic14_emitcode("mov","a,%s",l);
7038         aopPut(AOP(result),"a",offset);
7039       } else {
7040         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7041         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7042         //aopPut(AOP(result),l,offset);
7043       }
7044       offset++;
7045     }
7046   }
7047
7048   size = AOP_SIZE(result);
7049
7050   /* if it is only one byte then */
7051   if (size == 1) {
7052     if(optimized_for_speed) {
7053       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7054       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7055       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7056       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7057       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7058       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7059       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7060       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7061       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7062       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7063       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7064       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7065     } else {
7066
7067       tlbl = newiTempLabel(NULL);
7068       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7069         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7070         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7071       }
7072
7073       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7074       emitpcode(POC_RRF,    popGet(AOP(result),0));
7075       emitpLabel(tlbl->key);
7076       emitpcode(POC_RLF,    popGet(AOP(result),0));
7077       emitpcode(POC_ADDLW,  popGetLit(1));
7078       emitSKPC;
7079       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7080     }
7081     goto release ;
7082   }
7083     
7084   if (pic14_sameRegs(AOP(left),AOP(result))) {
7085
7086     tlbl = newiTempLabel(NULL);
7087     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7088     genMultiAsm(POC_RRF, result, size,1);
7089     emitpLabel(tlbl->key);
7090     genMultiAsm(POC_RLF, result, size,0);
7091     emitpcode(POC_ADDLW,  popGetLit(1));
7092     emitSKPC;
7093     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7094     goto release;
7095   }
7096
7097   //tlbl = newiTempLabel(NULL);
7098   //offset = 0 ;   
7099   //tlbl1 = newiTempLabel(NULL);
7100
7101   //reAdjustPreg(AOP(result));    
7102     
7103   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7104   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7105   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7106   //MOVA(l);
7107   //pic14_emitcode("add","a,acc");         
7108   //aopPut(AOP(result),"a",offset++);
7109   //while (--size) {
7110   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7111   //  MOVA(l);
7112   //  pic14_emitcode("rlc","a");         
7113   //  aopPut(AOP(result),"a",offset++);
7114   //}
7115   //reAdjustPreg(AOP(result));
7116
7117   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7118   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7119
7120
7121   tlbl = newiTempLabel(NULL);
7122   tlbl1= newiTempLabel(NULL);
7123
7124   size = AOP_SIZE(result);
7125   offset = 1;
7126
7127   pctemp = popGetTempReg();  /* grab a temporary working register. */
7128
7129   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7130
7131   /* offset should be 0, 1 or 3 */
7132   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7133   emitSKPNZ;
7134   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7135
7136   emitpcode(POC_MOVWF, pctemp);
7137
7138
7139   emitpLabel(tlbl->key);
7140
7141   emitCLRC;
7142   emitpcode(POC_RLF,  popGet(AOP(result),0));
7143   while(--size)
7144     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7145
7146   emitpcode(POC_DECFSZ,  pctemp);
7147   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7148   emitpLabel(tlbl1->key);
7149
7150   popReleaseTempReg(pctemp);
7151
7152
7153  release:
7154   freeAsmop (right,NULL,ic,TRUE);
7155   freeAsmop(left,NULL,ic,TRUE);
7156   freeAsmop(result,NULL,ic,TRUE);
7157 }
7158
7159 /*-----------------------------------------------------------------*/
7160 /* genrshOne - right shift a one byte quantity by known count      */
7161 /*-----------------------------------------------------------------*/
7162 static void genrshOne (operand *result, operand *left,
7163                        int shCount, int sign)
7164 {
7165     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7166     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7167 }
7168
7169 /*-----------------------------------------------------------------*/
7170 /* genrshTwo - right shift two bytes by known amount != 0          */
7171 /*-----------------------------------------------------------------*/
7172 static void genrshTwo (operand *result,operand *left,
7173                        int shCount, int sign)
7174 {
7175   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7176   /* if shCount >= 8 */
7177   if (shCount >= 8) {
7178     shCount -= 8 ;
7179     if (shCount)
7180       shiftR1Left2Result(left, MSB16, result, LSB,
7181                          shCount, sign);
7182     else
7183       movLeft2Result(left, MSB16, result, LSB);
7184
7185     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7186
7187     if(sign) {
7188       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7189       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7190     }
7191   }
7192
7193   /*  1 <= shCount <= 7 */
7194   else
7195     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7196 }
7197
7198 /*-----------------------------------------------------------------*/
7199 /* shiftRLong - shift right one long from left to result           */
7200 /* offl = LSB or MSB16                                             */
7201 /*-----------------------------------------------------------------*/
7202 static void shiftRLong (operand *left, int offl,
7203                         operand *result, int sign)
7204 {
7205     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7206     if(!sign)
7207         pic14_emitcode("clr","c");
7208     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7209     if(sign)
7210         pic14_emitcode("mov","c,acc.7");
7211     pic14_emitcode("rrc","a");
7212     aopPut(AOP(result),"a",MSB32-offl);
7213     if(offl == MSB16)
7214         /* add sign of "a" */
7215         addSign(result, MSB32, sign);
7216
7217     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7218     pic14_emitcode("rrc","a");
7219     aopPut(AOP(result),"a",MSB24-offl);
7220
7221     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7222     pic14_emitcode("rrc","a");
7223     aopPut(AOP(result),"a",MSB16-offl);
7224
7225     if(offl == LSB){
7226         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7227         pic14_emitcode("rrc","a");
7228         aopPut(AOP(result),"a",LSB);
7229     }
7230 }
7231
7232 /*-----------------------------------------------------------------*/
7233 /* genrshFour - shift four byte by a known amount != 0             */
7234 /*-----------------------------------------------------------------*/
7235 static void genrshFour (operand *result, operand *left,
7236                         int shCount, int sign)
7237 {
7238   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7239   /* if shifting more that 3 bytes */
7240   if(shCount >= 24 ) {
7241     shCount -= 24;
7242     if(shCount)
7243       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7244     else
7245       movLeft2Result(left, MSB32, result, LSB);
7246
7247     addSign(result, MSB16, sign);
7248   }
7249   else if(shCount >= 16){
7250     shCount -= 16;
7251     if(shCount)
7252       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7253     else{
7254       movLeft2Result(left, MSB24, result, LSB);
7255       movLeft2Result(left, MSB32, result, MSB16);
7256     }
7257     addSign(result, MSB24, sign);
7258   }
7259   else if(shCount >= 8){
7260     shCount -= 8;
7261     if(shCount == 1)
7262       shiftRLong(left, MSB16, result, sign);
7263     else if(shCount == 0){
7264       movLeft2Result(left, MSB16, result, LSB);
7265       movLeft2Result(left, MSB24, result, MSB16);
7266       movLeft2Result(left, MSB32, result, MSB24);
7267       addSign(result, MSB32, sign);
7268     }
7269     else{
7270       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7271       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7272       /* the last shift is signed */
7273       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7274       addSign(result, MSB32, sign);
7275     }
7276   }
7277   else{   /* 1 <= shCount <= 7 */
7278     if(shCount <= 2){
7279       shiftRLong(left, LSB, result, sign);
7280       if(shCount == 2)
7281         shiftRLong(result, LSB, result, sign);
7282     }
7283     else{
7284       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7285       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7286       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7287     }
7288   }
7289 }
7290
7291 /*-----------------------------------------------------------------*/
7292 /* genRightShiftLiteral - right shifting by known count            */
7293 /*-----------------------------------------------------------------*/
7294 static void genRightShiftLiteral (operand *left,
7295                                   operand *right,
7296                                   operand *result,
7297                                   iCode *ic,
7298                                   int sign)
7299 {    
7300   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7301   int lsize,res_size;
7302
7303   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7304   freeAsmop(right,NULL,ic,TRUE);
7305
7306   aopOp(left,ic,FALSE);
7307   aopOp(result,ic,FALSE);
7308
7309 #if VIEW_SIZE
7310   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7311                  AOP_SIZE(left));
7312 #endif
7313
7314   lsize = pic14_getDataSize(left);
7315   res_size = pic14_getDataSize(result);
7316   /* test the LEFT size !!! */
7317
7318   /* I suppose that the left size >= result size */
7319   if(shCount == 0){
7320     while(res_size--)
7321       movLeft2Result(left, lsize, result, res_size);
7322   }
7323
7324   else if(shCount >= (lsize * 8)){
7325
7326     if(res_size == 1) {
7327       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7328       if(sign) {
7329         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7330         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7331       }
7332     } else {
7333
7334       if(sign) {
7335         emitpcode(POC_MOVLW, popGetLit(0));
7336         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7337         emitpcode(POC_MOVLW, popGetLit(0xff));
7338         while(res_size--)
7339           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7340
7341       } else {
7342
7343         while(res_size--)
7344           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7345       }
7346     }
7347   } else {
7348
7349     switch (res_size) {
7350     case 1:
7351       genrshOne (result,left,shCount,sign);
7352       break;
7353
7354     case 2:
7355       genrshTwo (result,left,shCount,sign);
7356       break;
7357
7358     case 4:
7359       genrshFour (result,left,shCount,sign);
7360       break;
7361     default :
7362       break;
7363     }
7364
7365   }
7366
7367   freeAsmop(left,NULL,ic,TRUE);
7368   freeAsmop(result,NULL,ic,TRUE);
7369 }
7370
7371 /*-----------------------------------------------------------------*/
7372 /* genSignedRightShift - right shift of signed number              */
7373 /*-----------------------------------------------------------------*/
7374 static void genSignedRightShift (iCode *ic)
7375 {
7376   operand *right, *left, *result;
7377   int size, offset;
7378   //  char *l;
7379   symbol *tlbl, *tlbl1 ;
7380   pCodeOp *pctemp;
7381
7382   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7383
7384   /* we do it the hard way put the shift count in b
7385      and loop thru preserving the sign */
7386   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7387
7388   right = IC_RIGHT(ic);
7389   left  = IC_LEFT(ic);
7390   result = IC_RESULT(ic);
7391
7392   aopOp(right,ic,FALSE);  
7393   aopOp(left,ic,FALSE);
7394   aopOp(result,ic,FALSE);
7395
7396
7397   if ( AOP_TYPE(right) == AOP_LIT) {
7398     genRightShiftLiteral (left,right,result,ic,1);
7399     return ;
7400   }
7401   /* shift count is unknown then we have to form 
7402      a loop get the loop count in B : Note: we take
7403      only the lower order byte since shifting
7404      more that 32 bits make no sense anyway, ( the
7405      largest size of an object can be only 32 bits ) */  
7406
7407   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7408   //pic14_emitcode("inc","b");
7409   //freeAsmop (right,NULL,ic,TRUE);
7410   //aopOp(left,ic,FALSE);
7411   //aopOp(result,ic,FALSE);
7412
7413   /* now move the left to the result if they are not the
7414      same */
7415   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7416       AOP_SIZE(result) > 1) {
7417
7418     size = AOP_SIZE(result);
7419     offset=0;
7420     while (size--) { 
7421       /*
7422         l = aopGet(AOP(left),offset,FALSE,TRUE);
7423         if (*l == '@' && IS_AOP_PREG(result)) {
7424
7425         pic14_emitcode("mov","a,%s",l);
7426         aopPut(AOP(result),"a",offset);
7427         } else
7428         aopPut(AOP(result),l,offset);
7429       */
7430       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7431       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7432
7433       offset++;
7434     }
7435   }
7436
7437   /* mov the highest order bit to OVR */    
7438   tlbl = newiTempLabel(NULL);
7439   tlbl1= newiTempLabel(NULL);
7440
7441   size = AOP_SIZE(result);
7442   offset = size - 1;
7443
7444   pctemp = popGetTempReg();  /* grab a temporary working register. */
7445
7446   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7447
7448   /* offset should be 0, 1 or 3 */
7449   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7450   emitSKPNZ;
7451   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7452
7453   emitpcode(POC_MOVWF, pctemp);
7454
7455
7456   emitpLabel(tlbl->key);
7457
7458   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7459   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7460
7461   while(--size) {
7462     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7463   }
7464
7465   emitpcode(POC_DECFSZ,  pctemp);
7466   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7467   emitpLabel(tlbl1->key);
7468
7469   popReleaseTempReg(pctemp);
7470 #if 0
7471   size = AOP_SIZE(result);
7472   offset = size - 1;
7473   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7474   pic14_emitcode("rlc","a");
7475   pic14_emitcode("mov","ov,c");
7476   /* if it is only one byte then */
7477   if (size == 1) {
7478     l = aopGet(AOP(left),0,FALSE,FALSE);
7479     MOVA(l);
7480     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7481     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7482     pic14_emitcode("mov","c,ov");
7483     pic14_emitcode("rrc","a");
7484     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7485     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7486     aopPut(AOP(result),"a",0);
7487     goto release ;
7488   }
7489
7490   reAdjustPreg(AOP(result));
7491   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7492   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7493   pic14_emitcode("mov","c,ov");
7494   while (size--) {
7495     l = aopGet(AOP(result),offset,FALSE,FALSE);
7496     MOVA(l);
7497     pic14_emitcode("rrc","a");         
7498     aopPut(AOP(result),"a",offset--);
7499   }
7500   reAdjustPreg(AOP(result));
7501   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7502   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7503
7504  release:
7505 #endif
7506
7507   freeAsmop(left,NULL,ic,TRUE);
7508   freeAsmop(result,NULL,ic,TRUE);
7509   freeAsmop(right,NULL,ic,TRUE);
7510 }
7511
7512 /*-----------------------------------------------------------------*/
7513 /* genRightShift - generate code for right shifting                */
7514 /*-----------------------------------------------------------------*/
7515 static void genRightShift (iCode *ic)
7516 {
7517     operand *right, *left, *result;
7518     sym_link *retype ;
7519     int size, offset;
7520     char *l;
7521     symbol *tlbl, *tlbl1 ;
7522
7523     /* if signed then we do it the hard way preserve the
7524     sign bit moving it inwards */
7525     retype = getSpec(operandType(IC_RESULT(ic)));
7526     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7527
7528     if (!SPEC_USIGN(retype)) {
7529         genSignedRightShift (ic);
7530         return ;
7531     }
7532
7533     /* signed & unsigned types are treated the same : i.e. the
7534     signed is NOT propagated inwards : quoting from the
7535     ANSI - standard : "for E1 >> E2, is equivalent to division
7536     by 2**E2 if unsigned or if it has a non-negative value,
7537     otherwise the result is implementation defined ", MY definition
7538     is that the sign does not get propagated */
7539
7540     right = IC_RIGHT(ic);
7541     left  = IC_LEFT(ic);
7542     result = IC_RESULT(ic);
7543
7544     aopOp(right,ic,FALSE);
7545
7546     /* if the shift count is known then do it 
7547     as efficiently as possible */
7548     if (AOP_TYPE(right) == AOP_LIT) {
7549         genRightShiftLiteral (left,right,result,ic, 0);
7550         return ;
7551     }
7552
7553     /* shift count is unknown then we have to form 
7554     a loop get the loop count in B : Note: we take
7555     only the lower order byte since shifting
7556     more that 32 bits make no sense anyway, ( the
7557     largest size of an object can be only 32 bits ) */  
7558
7559     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7560     pic14_emitcode("inc","b");
7561     aopOp(left,ic,FALSE);
7562     aopOp(result,ic,FALSE);
7563
7564     /* now move the left to the result if they are not the
7565     same */
7566     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7567         AOP_SIZE(result) > 1) {
7568
7569         size = AOP_SIZE(result);
7570         offset=0;
7571         while (size--) {
7572             l = aopGet(AOP(left),offset,FALSE,TRUE);
7573             if (*l == '@' && IS_AOP_PREG(result)) {
7574
7575                 pic14_emitcode("mov","a,%s",l);
7576                 aopPut(AOP(result),"a",offset);
7577             } else
7578                 aopPut(AOP(result),l,offset);
7579             offset++;
7580         }
7581     }
7582
7583     tlbl = newiTempLabel(NULL);
7584     tlbl1= newiTempLabel(NULL);
7585     size = AOP_SIZE(result);
7586     offset = size - 1;
7587
7588     /* if it is only one byte then */
7589     if (size == 1) {
7590
7591       tlbl = newiTempLabel(NULL);
7592       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7593         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7594         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7595       }
7596
7597       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7598       emitpcode(POC_RLF,    popGet(AOP(result),0));
7599       emitpLabel(tlbl->key);
7600       emitpcode(POC_RRF,    popGet(AOP(result),0));
7601       emitpcode(POC_ADDLW,  popGetLit(1));
7602       emitSKPC;
7603       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7604
7605       goto release ;
7606     }
7607
7608     reAdjustPreg(AOP(result));
7609     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7610     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7611     CLRC;
7612     while (size--) {
7613         l = aopGet(AOP(result),offset,FALSE,FALSE);
7614         MOVA(l);
7615         pic14_emitcode("rrc","a");         
7616         aopPut(AOP(result),"a",offset--);
7617     }
7618     reAdjustPreg(AOP(result));
7619
7620     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7621     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7622
7623 release:
7624     freeAsmop(left,NULL,ic,TRUE);
7625     freeAsmop (right,NULL,ic,TRUE);
7626     freeAsmop(result,NULL,ic,TRUE);
7627 }
7628
7629 /*-----------------------------------------------------------------*/
7630 /* genUnpackBits - generates code for unpacking bits               */
7631 /*-----------------------------------------------------------------*/
7632 static void genUnpackBits (operand *result, char *rname, int ptype)
7633 {    
7634     int shCnt ;
7635     int rlen = 0 ;
7636     sym_link *etype;
7637     int offset = 0 ;
7638
7639     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7640     etype = getSpec(operandType(result));
7641
7642     /* read the first byte  */
7643     switch (ptype) {
7644
7645     case POINTER:
7646     case IPOINTER:
7647         pic14_emitcode("mov","a,@%s",rname);
7648         break;
7649         
7650     case PPOINTER:
7651         pic14_emitcode("movx","a,@%s",rname);
7652         break;
7653         
7654     case FPOINTER:
7655         pic14_emitcode("movx","a,@dptr");
7656         break;
7657
7658     case CPOINTER:
7659         pic14_emitcode("clr","a");
7660         pic14_emitcode("movc","a","@a+dptr");
7661         break;
7662
7663     case GPOINTER:
7664         pic14_emitcode("lcall","__gptrget");
7665         break;
7666     }
7667
7668     /* if we have bitdisplacement then it fits   */
7669     /* into this byte completely or if length is */
7670     /* less than a byte                          */
7671     if ((shCnt = SPEC_BSTR(etype)) || 
7672         (SPEC_BLEN(etype) <= 8))  {
7673
7674         /* shift right acc */
7675         AccRsh(shCnt);
7676
7677         pic14_emitcode("anl","a,#0x%02x",
7678                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7679         aopPut(AOP(result),"a",offset);
7680         return ;
7681     }
7682
7683     /* bit field did not fit in a byte  */
7684     rlen = SPEC_BLEN(etype) - 8;
7685     aopPut(AOP(result),"a",offset++);
7686
7687     while (1)  {
7688
7689         switch (ptype) {
7690         case POINTER:
7691         case IPOINTER:
7692             pic14_emitcode("inc","%s",rname);
7693             pic14_emitcode("mov","a,@%s",rname);
7694             break;
7695             
7696         case PPOINTER:
7697             pic14_emitcode("inc","%s",rname);
7698             pic14_emitcode("movx","a,@%s",rname);
7699             break;
7700
7701         case FPOINTER:
7702             pic14_emitcode("inc","dptr");
7703             pic14_emitcode("movx","a,@dptr");
7704             break;
7705             
7706         case CPOINTER:
7707             pic14_emitcode("clr","a");
7708             pic14_emitcode("inc","dptr");
7709             pic14_emitcode("movc","a","@a+dptr");
7710             break;
7711             
7712         case GPOINTER:
7713             pic14_emitcode("inc","dptr");
7714             pic14_emitcode("lcall","__gptrget");
7715             break;
7716         }
7717
7718         rlen -= 8;            
7719         /* if we are done */
7720         if ( rlen <= 0 )
7721             break ;
7722         
7723         aopPut(AOP(result),"a",offset++);
7724                               
7725     }
7726     
7727     if (rlen) {
7728         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7729         aopPut(AOP(result),"a",offset);        
7730     }
7731     
7732     return ;
7733 }
7734
7735
7736 /*-----------------------------------------------------------------*/
7737 /* genDataPointerGet - generates code when ptr offset is known     */
7738 /*-----------------------------------------------------------------*/
7739 static void genDataPointerGet (operand *left, 
7740                                operand *result, 
7741                                iCode *ic)
7742 {
7743   int size , offset = 0;
7744
7745
7746   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7747
7748
7749   /* optimization - most of the time, left and result are the same
7750    * address, but different types. for the pic code, we could omit
7751    * the following
7752    */
7753
7754   aopOp(result,ic,TRUE);
7755
7756   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7757
7758   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7759
7760   size = AOP_SIZE(result);
7761
7762   while (size--) {
7763     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7764     offset++;
7765   }
7766
7767   freeAsmop(left,NULL,ic,TRUE);
7768   freeAsmop(result,NULL,ic,TRUE);
7769 }
7770
7771 /*-----------------------------------------------------------------*/
7772 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7773 /*-----------------------------------------------------------------*/
7774 static void genNearPointerGet (operand *left, 
7775                                operand *result, 
7776                                iCode *ic)
7777 {
7778     asmop *aop = NULL;
7779     regs *preg = NULL ;
7780     char *rname ;
7781     sym_link *rtype, *retype;
7782     sym_link *ltype = operandType(left);    
7783     char buffer[80];
7784
7785     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7786
7787     rtype = operandType(result);
7788     retype= getSpec(rtype);
7789     
7790     aopOp(left,ic,FALSE);
7791     
7792     /* if left is rematerialisable and
7793        result is not bit variable type and
7794        the left is pointer to data space i.e
7795        lower 128 bytes of space */
7796     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7797         !IS_BITVAR(retype)         &&
7798         DCL_TYPE(ltype) == POINTER) {
7799       //genDataPointerGet (left,result,ic);
7800         return ;
7801     }
7802     
7803     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7804
7805         /* if the value is already in a pointer register
7806        then don't need anything more */
7807     if (!AOP_INPREG(AOP(left))) {
7808         /* otherwise get a free pointer register */
7809     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7810         aop = newAsmop(0);
7811         preg = getFreePtr(ic,&aop,FALSE);
7812         pic14_emitcode("mov","%s,%s",
7813                 preg->name,
7814                 aopGet(AOP(left),0,FALSE,TRUE));
7815         rname = preg->name ;
7816     } else
7817         rname = aopGet(AOP(left),0,FALSE,FALSE);
7818     
7819     freeAsmop(left,NULL,ic,TRUE);
7820     aopOp (result,ic,FALSE);
7821     
7822       /* if bitfield then unpack the bits */
7823     if (IS_BITVAR(retype)) 
7824         genUnpackBits (result,rname,POINTER);
7825     else {
7826         /* we have can just get the values */
7827         int size = AOP_SIZE(result);
7828         int offset = 0 ;        
7829         
7830     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7831         while (size--) {
7832             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7833
7834                 pic14_emitcode("mov","a,@%s",rname);
7835                 aopPut(AOP(result),"a",offset);
7836             } else {
7837                 sprintf(buffer,"@%s",rname);
7838                 aopPut(AOP(result),buffer,offset);
7839             }
7840             offset++ ;
7841             if (size)
7842                 pic14_emitcode("inc","%s",rname);
7843         }
7844     }
7845
7846     /* now some housekeeping stuff */
7847     if (aop) {
7848         /* we had to allocate for this iCode */
7849     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7850         freeAsmop(NULL,aop,ic,TRUE);
7851     } else { 
7852         /* we did not allocate which means left
7853            already in a pointer register, then
7854            if size > 0 && this could be used again
7855            we have to point it back to where it 
7856            belongs */
7857     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7858         if (AOP_SIZE(result) > 1 &&
7859             !OP_SYMBOL(left)->remat &&
7860             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7861               ic->depth )) {
7862             int size = AOP_SIZE(result) - 1;
7863             while (size--)
7864                 pic14_emitcode("dec","%s",rname);
7865         }
7866     }
7867
7868     /* done */
7869     freeAsmop(result,NULL,ic,TRUE);
7870      
7871 }
7872
7873 /*-----------------------------------------------------------------*/
7874 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7875 /*-----------------------------------------------------------------*/
7876 static void genPagedPointerGet (operand *left, 
7877                                operand *result, 
7878                                iCode *ic)
7879 {
7880     asmop *aop = NULL;
7881     regs *preg = NULL ;
7882     char *rname ;
7883     sym_link *rtype, *retype;    
7884
7885     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7886
7887     rtype = operandType(result);
7888     retype= getSpec(rtype);
7889     
7890     aopOp(left,ic,FALSE);
7891
7892   /* if the value is already in a pointer register
7893        then don't need anything more */
7894     if (!AOP_INPREG(AOP(left))) {
7895         /* otherwise get a free pointer register */
7896         aop = newAsmop(0);
7897         preg = getFreePtr(ic,&aop,FALSE);
7898         pic14_emitcode("mov","%s,%s",
7899                 preg->name,
7900                 aopGet(AOP(left),0,FALSE,TRUE));
7901         rname = preg->name ;
7902     } else
7903         rname = aopGet(AOP(left),0,FALSE,FALSE);
7904     
7905     freeAsmop(left,NULL,ic,TRUE);
7906     aopOp (result,ic,FALSE);
7907
7908     /* if bitfield then unpack the bits */
7909     if (IS_BITVAR(retype)) 
7910         genUnpackBits (result,rname,PPOINTER);
7911     else {
7912         /* we have can just get the values */
7913         int size = AOP_SIZE(result);
7914         int offset = 0 ;        
7915         
7916         while (size--) {
7917             
7918             pic14_emitcode("movx","a,@%s",rname);
7919             aopPut(AOP(result),"a",offset);
7920             
7921             offset++ ;
7922             
7923             if (size)
7924                 pic14_emitcode("inc","%s",rname);
7925         }
7926     }
7927
7928     /* now some housekeeping stuff */
7929     if (aop) {
7930         /* we had to allocate for this iCode */
7931         freeAsmop(NULL,aop,ic,TRUE);
7932     } else { 
7933         /* we did not allocate which means left
7934            already in a pointer register, then
7935            if size > 0 && this could be used again
7936            we have to point it back to where it 
7937            belongs */
7938         if (AOP_SIZE(result) > 1 &&
7939             !OP_SYMBOL(left)->remat &&
7940             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7941               ic->depth )) {
7942             int size = AOP_SIZE(result) - 1;
7943             while (size--)
7944                 pic14_emitcode("dec","%s",rname);
7945         }
7946     }
7947
7948     /* done */
7949     freeAsmop(result,NULL,ic,TRUE);
7950     
7951         
7952 }
7953
7954 /*-----------------------------------------------------------------*/
7955 /* genFarPointerGet - gget value from far space                    */
7956 /*-----------------------------------------------------------------*/
7957 static void genFarPointerGet (operand *left,
7958                               operand *result, iCode *ic)
7959 {
7960     int size, offset ;
7961     sym_link *retype = getSpec(operandType(result));
7962
7963     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7964
7965     aopOp(left,ic,FALSE);
7966
7967     /* if the operand is already in dptr 
7968     then we do nothing else we move the value to dptr */
7969     if (AOP_TYPE(left) != AOP_STR) {
7970         /* if this is remateriazable */
7971         if (AOP_TYPE(left) == AOP_IMMD)
7972             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7973         else { /* we need to get it byte by byte */
7974             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7975             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7976             if (options.model == MODEL_FLAT24)
7977             {
7978                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7979             }
7980         }
7981     }
7982     /* so dptr know contains the address */
7983     freeAsmop(left,NULL,ic,TRUE);
7984     aopOp(result,ic,FALSE);
7985
7986     /* if bit then unpack */
7987     if (IS_BITVAR(retype)) 
7988         genUnpackBits(result,"dptr",FPOINTER);
7989     else {
7990         size = AOP_SIZE(result);
7991         offset = 0 ;
7992
7993         while (size--) {
7994             pic14_emitcode("movx","a,@dptr");
7995             aopPut(AOP(result),"a",offset++);
7996             if (size)
7997                 pic14_emitcode("inc","dptr");
7998         }
7999     }
8000
8001     freeAsmop(result,NULL,ic,TRUE);
8002 }
8003 #if 0
8004 /*-----------------------------------------------------------------*/
8005 /* genCodePointerGet - get value from code space                  */
8006 /*-----------------------------------------------------------------*/
8007 static void genCodePointerGet (operand *left,
8008                                 operand *result, iCode *ic)
8009 {
8010     int size, offset ;
8011     sym_link *retype = getSpec(operandType(result));
8012
8013     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8014
8015     aopOp(left,ic,FALSE);
8016
8017     /* if the operand is already in dptr 
8018     then we do nothing else we move the value to dptr */
8019     if (AOP_TYPE(left) != AOP_STR) {
8020         /* if this is remateriazable */
8021         if (AOP_TYPE(left) == AOP_IMMD)
8022             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8023         else { /* we need to get it byte by byte */
8024             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8025             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8026             if (options.model == MODEL_FLAT24)
8027             {
8028                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8029             }
8030         }
8031     }
8032     /* so dptr know contains the address */
8033     freeAsmop(left,NULL,ic,TRUE);
8034     aopOp(result,ic,FALSE);
8035
8036     /* if bit then unpack */
8037     if (IS_BITVAR(retype)) 
8038         genUnpackBits(result,"dptr",CPOINTER);
8039     else {
8040         size = AOP_SIZE(result);
8041         offset = 0 ;
8042
8043         while (size--) {
8044             pic14_emitcode("clr","a");
8045             pic14_emitcode("movc","a,@a+dptr");
8046             aopPut(AOP(result),"a",offset++);
8047             if (size)
8048                 pic14_emitcode("inc","dptr");
8049         }
8050     }
8051
8052     freeAsmop(result,NULL,ic,TRUE);
8053 }
8054 #endif
8055 /*-----------------------------------------------------------------*/
8056 /* genGenPointerGet - gget value from generic pointer space        */
8057 /*-----------------------------------------------------------------*/
8058 static void genGenPointerGet (operand *left,
8059                               operand *result, iCode *ic)
8060 {
8061   int size, offset ;
8062   sym_link *retype = getSpec(operandType(result));
8063
8064   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8065   aopOp(left,ic,FALSE);
8066   aopOp(result,ic,FALSE);
8067
8068
8069   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8070
8071   /* if the operand is already in dptr 
8072      then we do nothing else we move the value to dptr */
8073   //  if (AOP_TYPE(left) != AOP_STR) {
8074     /* if this is remateriazable */
8075     if (AOP_TYPE(left) == AOP_IMMD) {
8076       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8077       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8078     }
8079     else { /* we need to get it byte by byte */
8080
8081       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8082       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8083
8084       size = AOP_SIZE(result);
8085       offset = 0 ;
8086
8087       while(size--) {
8088         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8089         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8090         if(size)
8091           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8092       }
8093       goto release;
8094     }
8095     //}
8096   /* so dptr know contains the address */
8097
8098   /* if bit then unpack */
8099   //if (IS_BITVAR(retype)) 
8100   //  genUnpackBits(result,"dptr",GPOINTER);
8101
8102  release:
8103   freeAsmop(left,NULL,ic,TRUE);
8104   freeAsmop(result,NULL,ic,TRUE);
8105
8106 }
8107
8108 /*-----------------------------------------------------------------*/
8109 /* genConstPointerGet - get value from const generic pointer space */
8110 /*-----------------------------------------------------------------*/
8111 static void genConstPointerGet (operand *left,
8112                                 operand *result, iCode *ic)
8113 {
8114   //sym_link *retype = getSpec(operandType(result));
8115   symbol *albl = newiTempLabel(NULL);
8116   symbol *blbl = newiTempLabel(NULL);
8117   PIC_OPCODE poc;
8118
8119   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8120   aopOp(left,ic,FALSE);
8121   aopOp(result,ic,FALSE);
8122
8123
8124   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8125
8126   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8127
8128   emitpcode(POC_CALL,popGetLabel(albl->key));
8129   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8130   emitpLabel(albl->key);
8131
8132   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8133     
8134   emitpcode(poc,popGet(AOP(left),1));
8135   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8136   emitpcode(poc,popGet(AOP(left),0));
8137   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8138
8139   emitpLabel(blbl->key);
8140
8141   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8142
8143
8144   freeAsmop(left,NULL,ic,TRUE);
8145   freeAsmop(result,NULL,ic,TRUE);
8146
8147 }
8148 /*-----------------------------------------------------------------*/
8149 /* genPointerGet - generate code for pointer get                   */
8150 /*-----------------------------------------------------------------*/
8151 static void genPointerGet (iCode *ic)
8152 {
8153     operand *left, *result ;
8154     sym_link *type, *etype;
8155     int p_type;
8156
8157     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8158
8159     left = IC_LEFT(ic);
8160     result = IC_RESULT(ic) ;
8161
8162     /* depending on the type of pointer we need to
8163     move it to the correct pointer register */
8164     type = operandType(left);
8165     etype = getSpec(type);
8166
8167     if (IS_PTR_CONST(type))
8168       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8169
8170     /* if left is of type of pointer then it is simple */
8171     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8172         p_type = DCL_TYPE(type);
8173     else {
8174         /* we have to go by the storage class */
8175         p_type = PTR_TYPE(SPEC_OCLS(etype));
8176
8177         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8178
8179         if (SPEC_OCLS(etype)->codesp ) {
8180           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8181           //p_type = CPOINTER ; 
8182         }
8183         else
8184             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8185               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8186                /*p_type = FPOINTER ;*/ 
8187             else
8188                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8189                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8190 /*                  p_type = PPOINTER; */
8191                 else
8192                     if (SPEC_OCLS(etype) == idata )
8193                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8194 /*                      p_type = IPOINTER; */
8195                     else
8196                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8197 /*                      p_type = POINTER ; */
8198     }
8199
8200     /* now that we have the pointer type we assign
8201     the pointer values */
8202     switch (p_type) {
8203
8204     case POINTER:       
8205     case IPOINTER:
8206         genNearPointerGet (left,result,ic);
8207         break;
8208
8209     case PPOINTER:
8210         genPagedPointerGet(left,result,ic);
8211         break;
8212
8213     case FPOINTER:
8214         genFarPointerGet (left,result,ic);
8215         break;
8216
8217     case CPOINTER:
8218         genConstPointerGet (left,result,ic);
8219         //pic14_emitcodePointerGet (left,result,ic);
8220         break;
8221
8222     case GPOINTER:
8223       if (IS_PTR_CONST(type))
8224         genConstPointerGet (left,result,ic);
8225       else
8226         genGenPointerGet (left,result,ic);
8227       break;
8228     }
8229
8230 }
8231
8232 /*-----------------------------------------------------------------*/
8233 /* genPackBits - generates code for packed bit storage             */
8234 /*-----------------------------------------------------------------*/
8235 static void genPackBits (sym_link    *etype ,
8236                          operand *right ,
8237                          char *rname, int p_type)
8238 {
8239     int shCount = 0 ;
8240     int offset = 0  ;
8241     int rLen = 0 ;
8242     int blen, bstr ;   
8243     char *l ;
8244
8245     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8246     blen = SPEC_BLEN(etype);
8247     bstr = SPEC_BSTR(etype);
8248
8249     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8250     MOVA(l);   
8251
8252     /* if the bit lenth is less than or    */
8253     /* it exactly fits a byte then         */
8254     if (SPEC_BLEN(etype) <= 8 )  {
8255         shCount = SPEC_BSTR(etype) ;
8256
8257         /* shift left acc */
8258         AccLsh(shCount);
8259
8260         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8261
8262
8263             switch (p_type) {
8264                 case POINTER:
8265                     pic14_emitcode ("mov","b,a");
8266                     pic14_emitcode("mov","a,@%s",rname);
8267                     break;
8268
8269                 case FPOINTER:
8270                     pic14_emitcode ("mov","b,a");
8271                     pic14_emitcode("movx","a,@dptr");
8272                     break;
8273
8274                 case GPOINTER:
8275                     pic14_emitcode ("push","b");
8276                     pic14_emitcode ("push","acc");
8277                     pic14_emitcode ("lcall","__gptrget");
8278                     pic14_emitcode ("pop","b");
8279                     break;
8280             }
8281
8282             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8283                       ((unsigned char)(0xFF << (blen+bstr)) | 
8284                        (unsigned char)(0xFF >> (8-bstr)) ) );
8285             pic14_emitcode ("orl","a,b");
8286             if (p_type == GPOINTER)
8287                 pic14_emitcode("pop","b");
8288         }
8289     }
8290
8291     switch (p_type) {
8292         case POINTER:
8293             pic14_emitcode("mov","@%s,a",rname);
8294             break;
8295
8296         case FPOINTER:
8297             pic14_emitcode("movx","@dptr,a");
8298             break;
8299
8300         case GPOINTER:
8301             DEBUGpic14_emitcode(";lcall","__gptrput");
8302             break;
8303     }
8304
8305     /* if we r done */
8306     if ( SPEC_BLEN(etype) <= 8 )
8307         return ;
8308
8309     pic14_emitcode("inc","%s",rname);
8310     rLen = SPEC_BLEN(etype) ;     
8311
8312     /* now generate for lengths greater than one byte */
8313     while (1) {
8314
8315         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8316
8317         rLen -= 8 ;
8318         if (rLen <= 0 )
8319             break ;
8320
8321         switch (p_type) {
8322             case POINTER:
8323                 if (*l == '@') {
8324                     MOVA(l);
8325                     pic14_emitcode("mov","@%s,a",rname);
8326                 } else
8327                     pic14_emitcode("mov","@%s,%s",rname,l);
8328                 break;
8329
8330             case FPOINTER:
8331                 MOVA(l);
8332                 pic14_emitcode("movx","@dptr,a");
8333                 break;
8334
8335             case GPOINTER:
8336                 MOVA(l);
8337                 DEBUGpic14_emitcode(";lcall","__gptrput");
8338                 break;  
8339         }   
8340         pic14_emitcode ("inc","%s",rname);
8341     }
8342
8343     MOVA(l);
8344
8345     /* last last was not complete */
8346     if (rLen)   {
8347         /* save the byte & read byte */
8348         switch (p_type) {
8349             case POINTER:
8350                 pic14_emitcode ("mov","b,a");
8351                 pic14_emitcode("mov","a,@%s",rname);
8352                 break;
8353
8354             case FPOINTER:
8355                 pic14_emitcode ("mov","b,a");
8356                 pic14_emitcode("movx","a,@dptr");
8357                 break;
8358
8359             case GPOINTER:
8360                 pic14_emitcode ("push","b");
8361                 pic14_emitcode ("push","acc");
8362                 pic14_emitcode ("lcall","__gptrget");
8363                 pic14_emitcode ("pop","b");
8364                 break;
8365         }
8366
8367         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8368         pic14_emitcode ("orl","a,b");
8369     }
8370
8371     if (p_type == GPOINTER)
8372         pic14_emitcode("pop","b");
8373
8374     switch (p_type) {
8375
8376     case POINTER:
8377         pic14_emitcode("mov","@%s,a",rname);
8378         break;
8379         
8380     case FPOINTER:
8381         pic14_emitcode("movx","@dptr,a");
8382         break;
8383         
8384     case GPOINTER:
8385         DEBUGpic14_emitcode(";lcall","__gptrput");
8386         break;                  
8387     }
8388 }
8389 /*-----------------------------------------------------------------*/
8390 /* genDataPointerSet - remat pointer to data space                 */
8391 /*-----------------------------------------------------------------*/
8392 static void genDataPointerSet(operand *right,
8393                               operand *result,
8394                               iCode *ic)
8395 {
8396     int size, offset = 0 ;
8397     char *l, buffer[256];
8398
8399     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8400     aopOp(right,ic,FALSE);
8401     
8402     l = aopGet(AOP(result),0,FALSE,TRUE);
8403     size = AOP_SIZE(right);
8404 /*
8405     if ( AOP_TYPE(result) == AOP_PCODE) {
8406       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8407               AOP(result)->aopu.pcop->name,
8408               PCOI(AOP(result)->aopu.pcop)->offset);
8409     }
8410 */
8411
8412     // tsd, was l+1 - the underline `_' prefix was being stripped
8413     while (size--) {
8414       if (offset) {
8415         sprintf(buffer,"(%s + %d)",l,offset);
8416         fprintf(stderr,"oops  %s\n",buffer);
8417       } else
8418         sprintf(buffer,"%s",l);
8419
8420         if (AOP_TYPE(right) == AOP_LIT) {
8421           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8422           lit = lit >> (8*offset);
8423           if(lit&0xff) {
8424             pic14_emitcode("movlw","%d",lit);
8425             pic14_emitcode("movwf","%s",buffer);
8426
8427             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8428             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8429             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8430
8431           } else {
8432             pic14_emitcode("clrf","%s",buffer);
8433             //emitpcode(POC_CLRF, popRegFromString(buffer));
8434             emitpcode(POC_CLRF, popGet(AOP(result),0));
8435           }
8436         }else {
8437           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8438           pic14_emitcode("movwf","%s",buffer);
8439
8440           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8441           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8442           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8443
8444         }
8445
8446         offset++;
8447     }
8448
8449     freeAsmop(right,NULL,ic,TRUE);
8450     freeAsmop(result,NULL,ic,TRUE);
8451 }
8452
8453 /*-----------------------------------------------------------------*/
8454 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8455 /*-----------------------------------------------------------------*/
8456 static void genNearPointerSet (operand *right,
8457                                operand *result, 
8458                                iCode *ic)
8459 {
8460     asmop *aop = NULL;
8461     char *l;
8462     sym_link *retype;
8463     sym_link *ptype = operandType(result);
8464
8465     
8466     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8467     retype= getSpec(operandType(right));
8468
8469     aopOp(result,ic,FALSE);
8470     
8471     /* if the result is rematerializable &
8472        in data space & not a bit variable */
8473     //if (AOP_TYPE(result) == AOP_IMMD &&
8474     if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8475         DCL_TYPE(ptype) == POINTER   &&
8476         !IS_BITVAR(retype)) {
8477         genDataPointerSet (right,result,ic);
8478         return;
8479     }
8480
8481     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8482
8483     /* if the value is already in a pointer register
8484     then don't need anything more */
8485     if (!AOP_INPREG(AOP(result))) {
8486         /* otherwise get a free pointer register */
8487         //aop = newAsmop(0);
8488         //preg = getFreePtr(ic,&aop,FALSE);
8489         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8490         //pic14_emitcode("mov","%s,%s",
8491         //         preg->name,
8492         //         aopGet(AOP(result),0,FALSE,TRUE));
8493         //rname = preg->name ;
8494         pic14_emitcode("movwf","fsr");
8495     }// else
8496     //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8497
8498     freeAsmop(result,NULL,ic,TRUE);
8499     aopOp (right,ic,FALSE);
8500     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8501
8502     /* if bitfield then unpack the bits */
8503     if (IS_BITVAR(retype)) {
8504       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8505              "The programmer is obviously confused");
8506       //genPackBits (retype,right,rname,POINTER);
8507       exit(1);
8508     }
8509     else {
8510         /* we have can just get the values */
8511         int size = AOP_SIZE(right);
8512         int offset = 0 ;    
8513
8514     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8515         while (size--) {
8516             l = aopGet(AOP(right),offset,FALSE,TRUE);
8517             if (*l == '@' ) {
8518               //MOVA(l);
8519               //pic14_emitcode("mov","@%s,a",rname);
8520               pic14_emitcode("movf","indf,w ;1");
8521             } else {
8522
8523               if (AOP_TYPE(right) == AOP_LIT) {
8524                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8525                 if(lit) {
8526                   pic14_emitcode("movlw","%s",l);
8527                   pic14_emitcode("movwf","indf ;2");
8528                 } else 
8529                   pic14_emitcode("clrf","indf");
8530               }else {
8531                 pic14_emitcode("movf","%s,w",l);
8532                 pic14_emitcode("movwf","indf ;2");
8533               }
8534             //pic14_emitcode("mov","@%s,%s",rname,l);
8535             }
8536             if (size)
8537               pic14_emitcode("incf","fsr,f ;3");
8538             //pic14_emitcode("inc","%s",rname);
8539             offset++;
8540         }
8541     }
8542
8543     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8544     /* now some housekeeping stuff */
8545     if (aop) {
8546         /* we had to allocate for this iCode */
8547         freeAsmop(NULL,aop,ic,TRUE);
8548     } else { 
8549         /* we did not allocate which means left
8550         already in a pointer register, then
8551         if size > 0 && this could be used again
8552         we have to point it back to where it 
8553         belongs */
8554     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8555         if (AOP_SIZE(right) > 1 &&
8556             !OP_SYMBOL(result)->remat &&
8557             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8558               ic->depth )) {
8559             int size = AOP_SIZE(right) - 1;
8560             while (size--)
8561               pic14_emitcode("decf","fsr,f");
8562               //pic14_emitcode("dec","%s",rname);
8563         }
8564     }
8565
8566     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8567     /* done */
8568     freeAsmop(right,NULL,ic,TRUE);
8569
8570
8571 }
8572
8573 /*-----------------------------------------------------------------*/
8574 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8575 /*-----------------------------------------------------------------*/
8576 static void genPagedPointerSet (operand *right,
8577                                operand *result, 
8578                                iCode *ic)
8579 {
8580     asmop *aop = NULL;
8581     regs *preg = NULL ;
8582     char *rname , *l;
8583     sym_link *retype;
8584        
8585     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8586
8587     retype= getSpec(operandType(right));
8588     
8589     aopOp(result,ic,FALSE);
8590     
8591     /* if the value is already in a pointer register
8592        then don't need anything more */
8593     if (!AOP_INPREG(AOP(result))) {
8594         /* otherwise get a free pointer register */
8595         aop = newAsmop(0);
8596         preg = getFreePtr(ic,&aop,FALSE);
8597         pic14_emitcode("mov","%s,%s",
8598                 preg->name,
8599                 aopGet(AOP(result),0,FALSE,TRUE));
8600         rname = preg->name ;
8601     } else
8602         rname = aopGet(AOP(result),0,FALSE,FALSE);
8603     
8604     freeAsmop(result,NULL,ic,TRUE);
8605     aopOp (right,ic,FALSE);
8606
8607     /* if bitfield then unpack the bits */
8608     if (IS_BITVAR(retype)) 
8609         genPackBits (retype,right,rname,PPOINTER);
8610     else {
8611         /* we have can just get the values */
8612         int size = AOP_SIZE(right);
8613         int offset = 0 ;        
8614         
8615         while (size--) {
8616             l = aopGet(AOP(right),offset,FALSE,TRUE);
8617             
8618             MOVA(l);
8619             pic14_emitcode("movx","@%s,a",rname);
8620
8621             if (size)
8622                 pic14_emitcode("inc","%s",rname);
8623
8624             offset++;
8625         }
8626     }
8627     
8628     /* now some housekeeping stuff */
8629     if (aop) {
8630         /* we had to allocate for this iCode */
8631         freeAsmop(NULL,aop,ic,TRUE);
8632     } else { 
8633         /* we did not allocate which means left
8634            already in a pointer register, then
8635            if size > 0 && this could be used again
8636            we have to point it back to where it 
8637            belongs */
8638         if (AOP_SIZE(right) > 1 &&
8639             !OP_SYMBOL(result)->remat &&
8640             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8641               ic->depth )) {
8642             int size = AOP_SIZE(right) - 1;
8643             while (size--)
8644                 pic14_emitcode("dec","%s",rname);
8645         }
8646     }
8647
8648     /* done */
8649     freeAsmop(right,NULL,ic,TRUE);
8650     
8651         
8652 }
8653
8654 /*-----------------------------------------------------------------*/
8655 /* genFarPointerSet - set value from far space                     */
8656 /*-----------------------------------------------------------------*/
8657 static void genFarPointerSet (operand *right,
8658                               operand *result, iCode *ic)
8659 {
8660     int size, offset ;
8661     sym_link *retype = getSpec(operandType(right));
8662
8663     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8664     aopOp(result,ic,FALSE);
8665
8666     /* if the operand is already in dptr 
8667     then we do nothing else we move the value to dptr */
8668     if (AOP_TYPE(result) != AOP_STR) {
8669         /* if this is remateriazable */
8670         if (AOP_TYPE(result) == AOP_IMMD)
8671             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8672         else { /* we need to get it byte by byte */
8673             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8674             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8675             if (options.model == MODEL_FLAT24)
8676             {
8677                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8678             }
8679         }
8680     }
8681     /* so dptr know contains the address */
8682     freeAsmop(result,NULL,ic,TRUE);
8683     aopOp(right,ic,FALSE);
8684
8685     /* if bit then unpack */
8686     if (IS_BITVAR(retype)) 
8687         genPackBits(retype,right,"dptr",FPOINTER);
8688     else {
8689         size = AOP_SIZE(right);
8690         offset = 0 ;
8691
8692         while (size--) {
8693             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8694             MOVA(l);
8695             pic14_emitcode("movx","@dptr,a");
8696             if (size)
8697                 pic14_emitcode("inc","dptr");
8698         }
8699     }
8700
8701     freeAsmop(right,NULL,ic,TRUE);
8702 }
8703
8704 /*-----------------------------------------------------------------*/
8705 /* genGenPointerSet - set value from generic pointer space         */
8706 /*-----------------------------------------------------------------*/
8707 static void genGenPointerSet (operand *right,
8708                               operand *result, iCode *ic)
8709 {
8710   int size, offset ;
8711   sym_link *retype = getSpec(operandType(right));
8712
8713   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8714
8715   aopOp(result,ic,FALSE);
8716   aopOp(right,ic,FALSE);
8717   size = AOP_SIZE(right);
8718
8719   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8720
8721   /* if the operand is already in dptr 
8722      then we do nothing else we move the value to dptr */
8723   if (AOP_TYPE(result) != AOP_STR) {
8724     /* if this is remateriazable */
8725     if (AOP_TYPE(result) == AOP_IMMD) {
8726       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8727       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8728     }
8729     else { /* we need to get it byte by byte */
8730       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8731       size = AOP_SIZE(right);
8732       offset = 0 ;
8733
8734       /* hack hack! see if this the FSR. If so don't load W */
8735       if(AOP_TYPE(right) != AOP_ACC) {
8736
8737         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8738         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8739
8740         //if(size==2)
8741         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8742         //if(size==4) {
8743         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8744         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8745         //}
8746
8747         while(size--) {
8748           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8749           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8750           
8751           if(size)
8752             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8753         }
8754
8755
8756         goto release;
8757       } 
8758
8759       if(aopIdx(AOP(result),0) != 4) {
8760
8761         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8762         goto release;
8763       }
8764
8765       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8766       goto release;
8767
8768     }
8769   }
8770   /* so dptr know contains the address */
8771
8772
8773   /* if bit then unpack */
8774   if (IS_BITVAR(retype)) 
8775     genPackBits(retype,right,"dptr",GPOINTER);
8776   else {
8777     size = AOP_SIZE(right);
8778     offset = 0 ;
8779
8780     while (--size) {
8781       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8782       if(size)
8783         pic14_emitcode("incf","fsr,f");
8784       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8785       pic14_emitcode("movwf","indf");
8786       //MOVA(l);
8787       //DEBUGpic14_emitcode(";lcall","__gptrput");
8788       //if (size)
8789       //    pic14_emitcode("inc","dptr");
8790     }
8791   }
8792
8793  release:
8794   freeAsmop(right,NULL,ic,TRUE);
8795   freeAsmop(result,NULL,ic,TRUE);
8796 }
8797
8798 /*-----------------------------------------------------------------*/
8799 /* genPointerSet - stores the value into a pointer location        */
8800 /*-----------------------------------------------------------------*/
8801 static void genPointerSet (iCode *ic)
8802 {    
8803     operand *right, *result ;
8804     sym_link *type, *etype;
8805     int p_type;
8806
8807     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8808
8809     right = IC_RIGHT(ic);
8810     result = IC_RESULT(ic) ;
8811
8812     /* depending on the type of pointer we need to
8813     move it to the correct pointer register */
8814     type = operandType(result);
8815     etype = getSpec(type);
8816     /* if left is of type of pointer then it is simple */
8817     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8818         p_type = DCL_TYPE(type);
8819     }
8820     else {
8821         /* we have to go by the storage class */
8822         p_type = PTR_TYPE(SPEC_OCLS(etype));
8823
8824 /*      if (SPEC_OCLS(etype)->codesp ) { */
8825 /*          p_type = CPOINTER ;  */
8826 /*      } */
8827 /*      else */
8828 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8829 /*              p_type = FPOINTER ; */
8830 /*          else */
8831 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8832 /*                  p_type = PPOINTER ; */
8833 /*              else */
8834 /*                  if (SPEC_OCLS(etype) == idata ) */
8835 /*                      p_type = IPOINTER ; */
8836 /*                  else */
8837 /*                      p_type = POINTER ; */
8838     }
8839
8840     /* now that we have the pointer type we assign
8841     the pointer values */
8842     switch (p_type) {
8843
8844     case POINTER:
8845     case IPOINTER:
8846         genNearPointerSet (right,result,ic);
8847         break;
8848
8849     case PPOINTER:
8850         genPagedPointerSet (right,result,ic);
8851         break;
8852
8853     case FPOINTER:
8854         genFarPointerSet (right,result,ic);
8855         break;
8856
8857     case GPOINTER:
8858         genGenPointerSet (right,result,ic);
8859         break;
8860
8861     default:
8862       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
8863               "genPointerSet: illegal pointer type");
8864     }
8865 }
8866
8867 /*-----------------------------------------------------------------*/
8868 /* genIfx - generate code for Ifx statement                        */
8869 /*-----------------------------------------------------------------*/
8870 static void genIfx (iCode *ic, iCode *popIc)
8871 {
8872   operand *cond = IC_COND(ic);
8873   int isbit =0;
8874
8875   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8876
8877   aopOp(cond,ic,FALSE);
8878
8879   /* get the value into acc */
8880   if (AOP_TYPE(cond) != AOP_CRY)
8881     pic14_toBoolean(cond);
8882   else
8883     isbit = 1;
8884   /* the result is now in the accumulator */
8885   freeAsmop(cond,NULL,ic,TRUE);
8886
8887   /* if there was something to be popped then do it */
8888   if (popIc)
8889     genIpop(popIc);
8890
8891   /* if the condition is  a bit variable */
8892   if (isbit && IS_ITEMP(cond) && 
8893       SPIL_LOC(cond)) {
8894     genIfxJump(ic,SPIL_LOC(cond)->rname);
8895     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8896   }
8897   else {
8898     if (isbit && !IS_ITEMP(cond))
8899       genIfxJump(ic,OP_SYMBOL(cond)->rname);
8900     else
8901       genIfxJump(ic,"a");
8902   }
8903   ic->generated = 1;
8904
8905 }
8906
8907 /*-----------------------------------------------------------------*/
8908 /* genAddrOf - generates code for address of                       */
8909 /*-----------------------------------------------------------------*/
8910 static void genAddrOf (iCode *ic)
8911 {
8912   operand *right, *result, *left;
8913   int size, offset ;
8914
8915   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8916
8917
8918   //aopOp(IC_RESULT(ic),ic,FALSE);
8919
8920   aopOp((left=IC_LEFT(ic)),ic,FALSE);
8921   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8922   aopOp((result=IC_RESULT(ic)),ic,TRUE);
8923
8924   DEBUGpic14_AopType(__LINE__,left,right,result);
8925
8926   size = AOP_SIZE(IC_RESULT(ic));
8927   offset = 0;
8928
8929   while (size--) {
8930     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
8931     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8932     offset++;
8933   }
8934
8935   freeAsmop(left,NULL,ic,FALSE);
8936   freeAsmop(result,NULL,ic,TRUE);
8937
8938 }
8939
8940 #if 0
8941 /*-----------------------------------------------------------------*/
8942 /* genFarFarAssign - assignment when both are in far space         */
8943 /*-----------------------------------------------------------------*/
8944 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8945 {
8946     int size = AOP_SIZE(right);
8947     int offset = 0;
8948     char *l ;
8949     /* first push the right side on to the stack */
8950     while (size--) {
8951         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8952         MOVA(l);
8953         pic14_emitcode ("push","acc");
8954     }
8955     
8956     freeAsmop(right,NULL,ic,FALSE);
8957     /* now assign DPTR to result */
8958     aopOp(result,ic,FALSE);
8959     size = AOP_SIZE(result);
8960     while (size--) {
8961         pic14_emitcode ("pop","acc");
8962         aopPut(AOP(result),"a",--offset);
8963     }
8964     freeAsmop(result,NULL,ic,FALSE);
8965         
8966 }
8967 #endif
8968
8969 /*-----------------------------------------------------------------*/
8970 /* genAssign - generate code for assignment                        */
8971 /*-----------------------------------------------------------------*/
8972 static void genAssign (iCode *ic)
8973 {
8974   operand *result, *right;
8975   int size, offset,know_W;
8976   unsigned long lit = 0L;
8977
8978   result = IC_RESULT(ic);
8979   right  = IC_RIGHT(ic) ;
8980
8981   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8982
8983   /* if they are the same */
8984   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8985     return ;
8986
8987   aopOp(right,ic,FALSE);
8988   aopOp(result,ic,TRUE);
8989
8990   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8991
8992   /* if they are the same registers */
8993   if (pic14_sameRegs(AOP(right),AOP(result)))
8994     goto release;
8995
8996   /* if the result is a bit */
8997   if (AOP_TYPE(result) == AOP_CRY) {
8998
8999     /* if the right size is a literal then
9000        we know what the value is */
9001     if (AOP_TYPE(right) == AOP_LIT) {
9002           
9003       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9004                   popGet(AOP(result),0));
9005
9006       if (((int) operandLitValue(right))) 
9007         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9008                        AOP(result)->aopu.aop_dir,
9009                        AOP(result)->aopu.aop_dir);
9010       else
9011         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9012                        AOP(result)->aopu.aop_dir,
9013                        AOP(result)->aopu.aop_dir);
9014       goto release;
9015     }
9016
9017     /* the right is also a bit variable */
9018     if (AOP_TYPE(right) == AOP_CRY) {
9019       emitpcode(POC_BCF,    popGet(AOP(result),0));
9020       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9021       emitpcode(POC_BSF,    popGet(AOP(result),0));
9022
9023       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9024                      AOP(result)->aopu.aop_dir,
9025                      AOP(result)->aopu.aop_dir);
9026       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9027                      AOP(right)->aopu.aop_dir,
9028                      AOP(right)->aopu.aop_dir);
9029       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9030                      AOP(result)->aopu.aop_dir,
9031                      AOP(result)->aopu.aop_dir);
9032       goto release ;
9033     }
9034
9035     /* we need to or */
9036     emitpcode(POC_BCF,    popGet(AOP(result),0));
9037     pic14_toBoolean(right);
9038     emitSKPZ;
9039     emitpcode(POC_BSF,    popGet(AOP(result),0));
9040     //aopPut(AOP(result),"a",0);
9041     goto release ;
9042   }
9043
9044   /* bit variables done */
9045   /* general case */
9046   size = AOP_SIZE(result);
9047   offset = 0 ;
9048   if(AOP_TYPE(right) == AOP_LIT)
9049     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9050
9051   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9052   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9053     if(aopIdx(AOP(result),0) == 4) {
9054   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9055       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9056       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9057       goto release;
9058     } else
9059       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9060   }
9061
9062   know_W=-1;
9063   while (size--) {
9064   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9065     if(AOP_TYPE(right) == AOP_LIT) {
9066       if(lit&0xff) {
9067         if(know_W != (lit&0xff))
9068           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9069         know_W = lit&0xff;
9070         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9071       } else
9072         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9073
9074       lit >>= 8;
9075
9076     } else if (AOP_TYPE(right) == AOP_CRY) {
9077       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9078       if(offset == 0) {
9079         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9080         emitpcode(POC_INCF, popGet(AOP(result),0));
9081       }
9082     } else {
9083   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9084       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9085       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9086     }
9087             
9088     offset++;
9089   }
9090
9091     
9092  release:
9093   freeAsmop (right,NULL,ic,FALSE);
9094   freeAsmop (result,NULL,ic,TRUE);
9095 }   
9096
9097 /*-----------------------------------------------------------------*/
9098 /* genJumpTab - genrates code for jump table                       */
9099 /*-----------------------------------------------------------------*/
9100 static void genJumpTab (iCode *ic)
9101 {
9102     symbol *jtab;
9103     char *l;
9104
9105     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9106
9107     aopOp(IC_JTCOND(ic),ic,FALSE);
9108     /* get the condition into accumulator */
9109     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9110     MOVA(l);
9111     /* multiply by three */
9112     pic14_emitcode("add","a,acc");
9113     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9114
9115     jtab = newiTempLabel(NULL);
9116     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9117     pic14_emitcode("jmp","@a+dptr");
9118     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9119
9120     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9121     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9122     emitSKPNC;
9123     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9124     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9125     emitpLabel(jtab->key);
9126
9127     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9128
9129     /* now generate the jump labels */
9130     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9131          jtab = setNextItem(IC_JTLABELS(ic))) {
9132         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9133         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9134         
9135     }
9136
9137 }
9138
9139 /*-----------------------------------------------------------------*/
9140 /* genMixedOperation - gen code for operators between mixed types  */
9141 /*-----------------------------------------------------------------*/
9142 /*
9143   TSD - Written for the PIC port - but this unfortunately is buggy.
9144   This routine is good in that it is able to efficiently promote 
9145   types to different (larger) sizes. Unfortunately, the temporary
9146   variables that are optimized out by this routine are sometimes
9147   used in other places. So until I know how to really parse the 
9148   iCode tree, I'm going to not be using this routine :(.
9149 */
9150 static int genMixedOperation (iCode *ic)
9151 {
9152 #if 0
9153   operand *result = IC_RESULT(ic);
9154   sym_link *ctype = operandType(IC_LEFT(ic));
9155   operand *right = IC_RIGHT(ic);
9156   int ret = 0;
9157   int big,small;
9158   int offset;
9159
9160   iCode *nextic;
9161   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9162
9163   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9164
9165   nextic = ic->next;
9166   if(!nextic)
9167     return 0;
9168
9169   nextright = IC_RIGHT(nextic);
9170   nextleft  = IC_LEFT(nextic);
9171   nextresult = IC_RESULT(nextic);
9172
9173   aopOp(right,ic,FALSE);
9174   aopOp(result,ic,FALSE);
9175   aopOp(nextright,  nextic, FALSE);
9176   aopOp(nextleft,   nextic, FALSE);
9177   aopOp(nextresult, nextic, FALSE);
9178
9179   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9180
9181     operand *t = right;
9182     right = nextright;
9183     nextright = t; 
9184
9185     pic14_emitcode(";remove right +","");
9186
9187   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9188 /*
9189     operand *t = right;
9190     right = nextleft;
9191     nextleft = t; 
9192 */
9193     pic14_emitcode(";remove left +","");
9194   } else
9195     return 0;
9196
9197   big = AOP_SIZE(nextleft);
9198   small = AOP_SIZE(nextright);
9199
9200   switch(nextic->op) {
9201
9202   case '+':
9203     pic14_emitcode(";optimize a +","");
9204     /* if unsigned or not an integral type */
9205     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9206       pic14_emitcode(";add a bit to something","");
9207     } else {
9208
9209       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9210
9211       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9212         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9213         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9214       } else
9215         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9216
9217       offset = 0;
9218       while(--big) {
9219
9220         offset++;
9221
9222         if(--small) {
9223           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9224             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9225             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9226           }
9227
9228           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9229           emitSKPNC;
9230           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9231                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9232                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9233           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9234           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9235
9236         } else {
9237           pic14_emitcode("rlf","known_zero,w");
9238
9239           /*
9240             if right is signed
9241               btfsc  right,7
9242                addlw ff
9243           */
9244           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9245             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9246             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9247           } else {
9248             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9249           }
9250         }
9251       }
9252       ret = 1;
9253     }
9254   }
9255   ret = 1;
9256
9257 release:
9258   freeAsmop(right,NULL,ic,TRUE);
9259   freeAsmop(result,NULL,ic,TRUE);
9260   freeAsmop(nextright,NULL,ic,TRUE);
9261   freeAsmop(nextleft,NULL,ic,TRUE);
9262   if(ret)
9263     nextic->generated = 1;
9264
9265   return ret;
9266 #else
9267   return 0;
9268 #endif
9269 }
9270 /*-----------------------------------------------------------------*/
9271 /* genCast - gen code for casting                                  */
9272 /*-----------------------------------------------------------------*/
9273 static void genCast (iCode *ic)
9274 {
9275     operand *result = IC_RESULT(ic);
9276     sym_link *ctype = operandType(IC_LEFT(ic));
9277     sym_link *rtype = operandType(IC_RIGHT(ic));
9278     operand *right = IC_RIGHT(ic);
9279     int size, offset ;
9280
9281     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9282     /* if they are equivalent then do nothing */
9283     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9284         return ;
9285
9286     aopOp(right,ic,FALSE) ;
9287     aopOp(result,ic,FALSE);
9288
9289     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9290
9291     /* if the result is a bit */
9292     if (AOP_TYPE(result) == AOP_CRY) {
9293         /* if the right size is a literal then
9294         we know what the value is */
9295       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9296         if (AOP_TYPE(right) == AOP_LIT) {
9297
9298           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9299                       popGet(AOP(result),0));
9300
9301             if (((int) operandLitValue(right))) 
9302               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9303                        AOP(result)->aopu.aop_dir,
9304                        AOP(result)->aopu.aop_dir);
9305             else
9306               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9307                        AOP(result)->aopu.aop_dir,
9308                        AOP(result)->aopu.aop_dir);
9309
9310             goto release;
9311         }
9312
9313         /* the right is also a bit variable */
9314         if (AOP_TYPE(right) == AOP_CRY) {
9315
9316           emitCLRC;
9317           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9318
9319           pic14_emitcode("clrc","");
9320           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9321                    AOP(right)->aopu.aop_dir,
9322                    AOP(right)->aopu.aop_dir);
9323             aopPut(AOP(result),"c",0);
9324             goto release ;
9325         }
9326
9327         /* we need to or */
9328         if (AOP_TYPE(right) == AOP_REG) {
9329           emitpcode(POC_BCF,    popGet(AOP(result),0));
9330           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9331           emitpcode(POC_BSF,    popGet(AOP(result),0));
9332         }
9333         pic14_toBoolean(right);
9334         aopPut(AOP(result),"a",0);
9335         goto release ;
9336     }
9337
9338     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9339       int offset = 1;
9340       size = AOP_SIZE(result);
9341
9342       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9343
9344       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9345       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9346       emitpcode(POC_INCF,   popGet(AOP(result),0));
9347
9348       while (size--)
9349         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9350
9351       goto release;
9352     }
9353
9354     /* if they are the same size : or less */
9355     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9356
9357         /* if they are in the same place */
9358       if (pic14_sameRegs(AOP(right),AOP(result)))
9359         goto release;
9360
9361       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9362       if (IS_PTR_CONST(rtype))
9363         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9364       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9365         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9366
9367       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9368         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9369         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9370         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9371         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9372         if(AOP_SIZE(result) <2)
9373           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9374
9375       } else {
9376
9377         /* if they in different places then copy */
9378         size = AOP_SIZE(result);
9379         offset = 0 ;
9380         while (size--) {
9381           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9382           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9383
9384           //aopPut(AOP(result),
9385           // aopGet(AOP(right),offset,FALSE,FALSE),
9386           // offset);
9387
9388           offset++;
9389         }
9390       }
9391       goto release;
9392     }
9393
9394
9395     /* if the result is of type pointer */
9396     if (IS_PTR(ctype)) {
9397
9398         int p_type;
9399         sym_link *type = operandType(right);
9400         sym_link *etype = getSpec(type);
9401       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9402
9403         /* pointer to generic pointer */
9404         if (IS_GENPTR(ctype)) {
9405             char *l = zero;
9406             
9407             if (IS_PTR(type)) 
9408                 p_type = DCL_TYPE(type);
9409             else {
9410                 /* we have to go by the storage class */
9411                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9412
9413 /*              if (SPEC_OCLS(etype)->codesp )  */
9414 /*                  p_type = CPOINTER ;  */
9415 /*              else */
9416 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9417 /*                      p_type = FPOINTER ; */
9418 /*                  else */
9419 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9420 /*                          p_type = PPOINTER; */
9421 /*                      else */
9422 /*                          if (SPEC_OCLS(etype) == idata ) */
9423 /*                              p_type = IPOINTER ; */
9424 /*                          else */
9425 /*                              p_type = POINTER ; */
9426             }
9427                 
9428             /* the first two bytes are known */
9429             size = GPTRSIZE - 1; 
9430             offset = 0 ;
9431             while (size--) {
9432               if(offset < AOP_SIZE(right))
9433                 aopPut(AOP(result),
9434                        aopGet(AOP(right),offset,FALSE,FALSE),
9435                        offset);
9436               else
9437                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9438               offset++;
9439             }
9440             /* the last byte depending on type */
9441             switch (p_type) {
9442             case IPOINTER:
9443             case POINTER:
9444                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9445                 break;
9446             case FPOINTER:
9447               pic14_emitcode(";BUG!? ","%d",__LINE__);
9448                 l = one;
9449                 break;
9450             case CPOINTER:
9451               pic14_emitcode(";BUG!? ","%d",__LINE__);
9452                 l = "#0x02";
9453                 break;                          
9454             case PPOINTER:
9455               pic14_emitcode(";BUG!? ","%d",__LINE__);
9456                 l = "#0x03";
9457                 break;
9458                 
9459             default:
9460                 /* this should never happen */
9461                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9462                        "got unknown pointer type");
9463                 exit(1);
9464             }
9465             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9466             goto release ;
9467         }
9468         
9469         /* just copy the pointers */
9470         size = AOP_SIZE(result);
9471         offset = 0 ;
9472         while (size--) {
9473             aopPut(AOP(result),
9474                    aopGet(AOP(right),offset,FALSE,FALSE),
9475                    offset);
9476             offset++;
9477         }
9478         goto release ;
9479     }
9480     
9481
9482
9483     /* so we now know that the size of destination is greater
9484     than the size of the source.
9485     Now, if the next iCode is an operator then we might be
9486     able to optimize the operation without performing a cast.
9487     */
9488     if(genMixedOperation(ic))
9489       goto release;
9490
9491     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9492     
9493     /* we move to result for the size of source */
9494     size = AOP_SIZE(right);
9495     offset = 0 ;
9496     while (size--) {
9497       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9498       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9499       offset++;
9500     }
9501
9502     /* now depending on the sign of the destination */
9503     size = AOP_SIZE(result) - AOP_SIZE(right);
9504     /* if unsigned or not an integral type */
9505     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9506       while (size--)
9507         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9508     } else {
9509       /* we need to extend the sign :{ */
9510
9511       if(size == 1) {
9512         /* Save one instruction of casting char to int */
9513         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9514         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9515         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9516       } else {
9517         emitpcodeNULLop(POC_CLRW);
9518
9519         if(offset)
9520           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9521         else
9522           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9523         
9524         emitpcode(POC_MOVLW,   popGetLit(0xff));
9525
9526         while (size--)
9527           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9528       }
9529     }
9530
9531 release:
9532     freeAsmop(right,NULL,ic,TRUE);
9533     freeAsmop(result,NULL,ic,TRUE);
9534
9535 }
9536
9537 /*-----------------------------------------------------------------*/
9538 /* genDjnz - generate decrement & jump if not zero instrucion      */
9539 /*-----------------------------------------------------------------*/
9540 static int genDjnz (iCode *ic, iCode *ifx)
9541 {
9542     symbol *lbl, *lbl1;
9543     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9544
9545     if (!ifx)
9546         return 0;
9547     
9548     /* if the if condition has a false label
9549        then we cannot save */
9550     if (IC_FALSE(ifx))
9551         return 0;
9552
9553     /* if the minus is not of the form 
9554        a = a - 1 */
9555     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9556         !IS_OP_LITERAL(IC_RIGHT(ic)))
9557         return 0;
9558
9559     if (operandLitValue(IC_RIGHT(ic)) != 1)
9560         return 0;
9561
9562     /* if the size of this greater than one then no
9563        saving */
9564     if (getSize(operandType(IC_RESULT(ic))) > 1)
9565         return 0;
9566
9567     /* otherwise we can save BIG */
9568     lbl = newiTempLabel(NULL);
9569     lbl1= newiTempLabel(NULL);
9570
9571     aopOp(IC_RESULT(ic),ic,FALSE);
9572     
9573     if (IS_AOP_PREG(IC_RESULT(ic))) {
9574         pic14_emitcode("dec","%s",
9575                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9576         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9577         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9578     } else {    
9579
9580
9581       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9582       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9583
9584       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9585       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9586
9587     }
9588 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9589 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9590 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9591 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9592
9593     
9594     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9595     ifx->generated = 1;
9596     return 1;
9597 }
9598
9599 /*-----------------------------------------------------------------*/
9600 /* genReceive - generate code for a receive iCode                  */
9601 /*-----------------------------------------------------------------*/
9602 static void genReceive (iCode *ic)
9603 {    
9604   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9605
9606   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9607       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9608         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9609
9610     int size = getSize(operandType(IC_RESULT(ic)));
9611     int offset =  fReturnSizePic - size;
9612     while (size--) {
9613       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9614                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9615       offset++;
9616     }
9617     aopOp(IC_RESULT(ic),ic,FALSE);  
9618     size = AOP_SIZE(IC_RESULT(ic));
9619     offset = 0;
9620     while (size--) {
9621       pic14_emitcode ("pop","acc");
9622       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9623     }
9624         
9625   } else {
9626     _G.accInUse++;
9627     aopOp(IC_RESULT(ic),ic,FALSE);  
9628     _G.accInUse--;
9629     assignResultValue(IC_RESULT(ic));   
9630   }
9631
9632   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9633 }
9634
9635 /*-----------------------------------------------------------------*/
9636 /* genpic14Code - generate code for pic14 based controllers        */
9637 /*-----------------------------------------------------------------*/
9638 /*
9639  * At this point, ralloc.c has gone through the iCode and attempted
9640  * to optimize in a way suitable for a PIC. Now we've got to generate
9641  * PIC instructions that correspond to the iCode.
9642  *
9643  * Once the instructions are generated, we'll pass through both the
9644  * peep hole optimizer and the pCode optimizer.
9645  *-----------------------------------------------------------------*/
9646
9647 void genpic14Code (iCode *lic)
9648 {
9649     iCode *ic;
9650     int cln = 0;
9651
9652     lineHead = lineCurr = NULL;
9653
9654     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9655     addpBlock(pb);
9656
9657     /* if debug information required */
9658     if (options.debug && currFunc) { 
9659       if (currFunc) {
9660         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9661         _G.debugLine = 1;
9662         if (IS_STATIC(currFunc->etype)) {
9663           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9664           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9665         } else {
9666           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9667           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9668         }
9669         _G.debugLine = 0;
9670       }
9671     }
9672
9673
9674     for (ic = lic ; ic ; ic = ic->next ) {
9675
9676       DEBUGpic14_emitcode(";ic","");
9677         if ( cln != ic->lineno ) {
9678             if ( options.debug ) {
9679                 _G.debugLine = 1;
9680                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9681                          FileBaseName(ic->filename),ic->lineno,
9682                          ic->level,ic->block);
9683                 _G.debugLine = 0;
9684             }
9685             pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9686             pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9687                             printCLine(ic->filename, ic->lineno));
9688
9689             cln = ic->lineno ;
9690         }
9691         /* if the result is marked as
9692            spilt and rematerializable or code for
9693            this has already been generated then
9694            do nothing */
9695         if (resultRemat(ic) || ic->generated ) 
9696             continue ;
9697         
9698         /* depending on the operation */
9699         switch (ic->op) {
9700         case '!' :
9701             genNot(ic);
9702             break;
9703             
9704         case '~' :
9705             genCpl(ic);
9706             break;
9707             
9708         case UNARYMINUS:
9709             genUminus (ic);
9710             break;
9711             
9712         case IPUSH:
9713             genIpush (ic);
9714             break;
9715             
9716         case IPOP:
9717             /* IPOP happens only when trying to restore a 
9718                spilt live range, if there is an ifx statement
9719                following this pop then the if statement might
9720                be using some of the registers being popped which
9721                would destory the contents of the register so
9722                we need to check for this condition and handle it */
9723             if (ic->next            && 
9724                 ic->next->op == IFX &&
9725                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9726                 genIfx (ic->next,ic);
9727             else
9728                 genIpop (ic);
9729             break; 
9730             
9731         case CALL:
9732             genCall (ic);
9733             break;
9734             
9735         case PCALL:
9736             genPcall (ic);
9737             break;
9738             
9739         case FUNCTION:
9740             genFunction (ic);
9741             break;
9742             
9743         case ENDFUNCTION:
9744             genEndFunction (ic);
9745             break;
9746             
9747         case RETURN:
9748             genRet (ic);
9749             break;
9750             
9751         case LABEL:
9752             genLabel (ic);
9753             break;
9754             
9755         case GOTO:
9756             genGoto (ic);
9757             break;
9758             
9759         case '+' :
9760             genPlus (ic) ;
9761             break;
9762             
9763         case '-' :
9764             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9765                 genMinus (ic);
9766             break;
9767             
9768         case '*' :
9769             genMult (ic);
9770             break;
9771             
9772         case '/' :
9773             genDiv (ic) ;
9774             break;
9775             
9776         case '%' :
9777             genMod (ic);
9778             break;
9779             
9780         case '>' :
9781             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9782             break;
9783             
9784         case '<' :
9785             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9786             break;
9787             
9788         case LE_OP:
9789         case GE_OP:
9790         case NE_OP:
9791             
9792             /* note these two are xlated by algebraic equivalence
9793                during parsing SDCC.y */
9794             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9795                    "got '>=' or '<=' shouldn't have come here");
9796             break;      
9797             
9798         case EQ_OP:
9799             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9800             break;          
9801             
9802         case AND_OP:
9803             genAndOp (ic);
9804             break;
9805             
9806         case OR_OP:
9807             genOrOp (ic);
9808             break;
9809             
9810         case '^' :
9811             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9812             break;
9813             
9814         case '|' :
9815                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9816             break;
9817             
9818         case BITWISEAND:
9819             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9820             break;
9821             
9822         case INLINEASM:
9823             genInline (ic);
9824             break;
9825             
9826         case RRC:
9827             genRRC (ic);
9828             break;
9829             
9830         case RLC:
9831             genRLC (ic);
9832             break;
9833             
9834         case GETHBIT:
9835             genGetHbit (ic);
9836             break;
9837             
9838         case LEFT_OP:
9839             genLeftShift (ic);
9840             break;
9841             
9842         case RIGHT_OP:
9843             genRightShift (ic);
9844             break;
9845             
9846         case GET_VALUE_AT_ADDRESS:
9847             genPointerGet(ic);
9848             break;
9849             
9850         case '=' :
9851             if (POINTER_SET(ic))
9852                 genPointerSet(ic);
9853             else
9854                 genAssign(ic);
9855             break;
9856             
9857         case IFX:
9858             genIfx (ic,NULL);
9859             break;
9860             
9861         case ADDRESS_OF:
9862             genAddrOf (ic);
9863             break;
9864             
9865         case JUMPTABLE:
9866             genJumpTab (ic);
9867             break;
9868             
9869         case CAST:
9870             genCast (ic);
9871             break;
9872             
9873         case RECEIVE:
9874             genReceive(ic);
9875             break;
9876             
9877         case SEND:
9878             addSet(&_G.sendSet,ic);
9879             break;
9880
9881         default :
9882             ic = ic;
9883         }
9884     }
9885     
9886
9887     /* now we are ready to call the 
9888        peep hole optimizer */
9889     if (!options.nopeep) {
9890       peepHole (&lineHead);
9891     }
9892     /* now do the actual printing */
9893     printLine (lineHead,codeOutFile);
9894
9895 #ifdef PCODE_DEBUG
9896     DFPRINTF((stderr,"printing pBlock\n\n"));
9897     printpBlock(stdout,pb);
9898 #endif
9899
9900     return;
9901 }