975ead83e0f7c7a5aa13781fa3bbdecf716dc4d7
[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   if(IS_OP_POINTER(op)) {
592     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
593   }
594   for (;;) {
595     if (ic->op == '+') {
596       val += (int) operandLitValue(IC_RIGHT(ic));
597     } else if (ic->op == '-') {
598       val -= (int) operandLitValue(IC_RIGHT(ic));
599     } else
600       break;
601         
602     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
603   }
604
605   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
606   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
607   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
608   PCOI(aop->aopu.pcop)->index = val;
609
610   DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
611                       OP_SYMBOL(IC_LEFT(ic))->rname,
612                       val, IS_PTR_CONST(operandType(op)));
613
614   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
615
616   allocDirReg (IC_LEFT(ic));
617
618   return aop;        
619 }
620
621 int aopIdx (asmop *aop, int offset)
622 {
623   if(!aop)
624     return -1;
625
626   if(aop->type !=  AOP_REG)
627     return -2;
628         
629   return aop->aopu.aop_reg[offset]->rIdx;
630
631 }
632 /*-----------------------------------------------------------------*/
633 /* regsInCommon - two operands have some registers in common       */
634 /*-----------------------------------------------------------------*/
635 static bool regsInCommon (operand *op1, operand *op2)
636 {
637     symbol *sym1, *sym2;
638     int i;
639
640     /* if they have registers in common */
641     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
642         return FALSE ;
643
644     sym1 = OP_SYMBOL(op1);
645     sym2 = OP_SYMBOL(op2);
646
647     if (sym1->nRegs == 0 || sym2->nRegs == 0)
648         return FALSE ;
649
650     for (i = 0 ; i < sym1->nRegs ; i++) {
651         int j;
652         if (!sym1->regs[i])
653             continue ;
654
655         for (j = 0 ; j < sym2->nRegs ;j++ ) {
656             if (!sym2->regs[j])
657                 continue ;
658
659             if (sym2->regs[j] == sym1->regs[i])
660                 return TRUE ;
661         }
662     }
663
664     return FALSE ;
665 }
666
667 /*-----------------------------------------------------------------*/
668 /* operandsEqu - equivalent                                        */
669 /*-----------------------------------------------------------------*/
670 static bool operandsEqu ( operand *op1, operand *op2)
671 {
672     symbol *sym1, *sym2;
673
674     /* if they not symbols */
675     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
676         return FALSE;
677
678     sym1 = OP_SYMBOL(op1);
679     sym2 = OP_SYMBOL(op2);
680
681     /* if both are itemps & one is spilt
682        and the other is not then false */
683     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
684         sym1->isspilt != sym2->isspilt )
685         return FALSE ;
686
687     /* if they are the same */
688     if (sym1 == sym2)
689         return TRUE ;
690
691     if (strcmp(sym1->rname,sym2->rname) == 0)
692         return TRUE;
693
694
695     /* if left is a tmp & right is not */
696     if (IS_ITEMP(op1)  && 
697         !IS_ITEMP(op2) &&
698         sym1->isspilt  &&
699         (sym1->usl.spillLoc == sym2))
700         return TRUE;
701
702     if (IS_ITEMP(op2)  && 
703         !IS_ITEMP(op1) &&
704         sym2->isspilt  &&
705         sym1->level > 0 &&
706         (sym2->usl.spillLoc == sym1))
707         return TRUE ;
708
709     return FALSE ;
710 }
711
712 /*-----------------------------------------------------------------*/
713 /* pic14_sameRegs - two asmops have the same registers                   */
714 /*-----------------------------------------------------------------*/
715 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
716 {
717     int i;
718
719     if (aop1 == aop2)
720         return TRUE ;
721
722     if (aop1->type != AOP_REG ||
723         aop2->type != AOP_REG )
724         return FALSE ;
725
726     if (aop1->size != aop2->size )
727         return FALSE ;
728
729     for (i = 0 ; i < aop1->size ; i++ )
730         if (aop1->aopu.aop_reg[i] !=
731             aop2->aopu.aop_reg[i] )
732             return FALSE ;
733
734     return TRUE ;
735 }
736
737 /*-----------------------------------------------------------------*/
738 /* aopOp - allocates an asmop for an operand  :                    */
739 /*-----------------------------------------------------------------*/
740 void aopOp (operand *op, iCode *ic, bool result)
741 {
742     asmop *aop;
743     symbol *sym;
744     int i;
745
746     if (!op)
747         return ;
748
749     //    DEBUGpic14_emitcode(";","%d",__LINE__);
750     /* if this a literal */
751     if (IS_OP_LITERAL(op)) {
752         op->aop = aop = newAsmop(AOP_LIT);
753         aop->aopu.aop_lit = op->operand.valOperand;
754         aop->size = getSize(operandType(op));
755         return;
756     }
757
758     {
759       sym_link *type = operandType(op);
760       if(IS_PTR_CONST(type))
761         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
762     }
763
764     /* if already has a asmop then continue */
765     if (op->aop)
766         return ;
767
768     /* if the underlying symbol has a aop */
769     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
770       DEBUGpic14_emitcode(";","%d",__LINE__);
771         op->aop = OP_SYMBOL(op)->aop;
772         return;
773     }
774
775     /* if this is a true symbol */
776     if (IS_TRUE_SYMOP(op)) {    
777       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
778       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
779       return ;
780     }
781
782     /* this is a temporary : this has
783     only four choices :
784     a) register
785     b) spillocation
786     c) rematerialize 
787     d) conditional   
788     e) can be a return use only */
789
790     sym = OP_SYMBOL(op);
791
792
793     /* if the type is a conditional */
794     if (sym->regType == REG_CND) {
795         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
796         aop->size = 0;
797         return;
798     }
799
800     /* if it is spilt then two situations
801     a) is rematerialize 
802     b) has a spill location */
803     if (sym->isspilt || sym->nRegs == 0) {
804
805       DEBUGpic14_emitcode(";","%d",__LINE__);
806         /* rematerialize it NOW */
807         if (sym->remat) {
808
809             sym->aop = op->aop = aop =
810                                       aopForRemat (op);
811             aop->size = getSize(sym->type);
812             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
813             return;
814         }
815
816         if (sym->accuse) {
817             int i;
818             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
819             aop->size = getSize(sym->type);
820             for ( i = 0 ; i < 2 ; i++ )
821                 aop->aopu.aop_str[i] = accUse[i];
822             DEBUGpic14_emitcode(";","%d",__LINE__);
823             return;  
824         }
825
826         if (sym->ruonly ) {
827             unsigned i;
828             aop = op->aop = sym->aop = newAsmop(AOP_STR);
829             aop->size = getSize(sym->type);
830             for ( i = 0 ; i < fReturnSizePic ; i++ )
831               aop->aopu.aop_str[i] = fReturn[i];
832             DEBUGpic14_emitcode(";","%d",__LINE__);
833             return;
834         }
835
836         /* else spill location  */
837         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
838             /* force a new aop if sizes differ */
839             sym->usl.spillLoc->aop = NULL;
840         }
841         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
842                             __FUNCTION__,__LINE__,
843                             sym->usl.spillLoc->rname,
844                             sym->rname, sym->usl.spillLoc->offset);
845         // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
846         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
847         aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
848         //allocDirReg (IC_LEFT(ic));
849         aop->size = getSize(sym->type);
850
851         return;
852     }
853
854     {
855       sym_link *type = operandType(op);
856       if(IS_PTR_CONST(type)) 
857         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
858     }
859
860     /* must be in a register */
861     sym->aop = op->aop = aop = newAsmop(AOP_REG);
862     aop->size = sym->nRegs;
863     for ( i = 0 ; i < sym->nRegs ;i++)
864         aop->aopu.aop_reg[i] = sym->regs[i];
865 }
866
867 /*-----------------------------------------------------------------*/
868 /* freeAsmop - free up the asmop given to an operand               */
869 /*----------------------------------------------------------------*/
870 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
871 {   
872     asmop *aop ;
873
874     if (!op)
875         aop = aaop;
876     else 
877         aop = op->aop;
878
879     if (!aop)
880         return ;
881
882     if (aop->freed)
883         goto dealloc; 
884
885     aop->freed = 1;
886
887     /* depending on the asmop type only three cases need work AOP_RO
888        , AOP_R1 && AOP_STK */
889 #if 0
890     switch (aop->type) {
891         case AOP_R0 :
892             if (_G.r0Pushed ) {
893                 if (pop) {
894                     pic14_emitcode ("pop","ar0");     
895                     _G.r0Pushed--;
896                 }
897             }
898             bitVectUnSetBit(ic->rUsed,R0_IDX);
899             break;
900
901         case AOP_R1 :
902             if (_G.r1Pushed ) {
903                 if (pop) {
904                     pic14_emitcode ("pop","ar1");
905                     _G.r1Pushed--;
906                 }
907             }
908             bitVectUnSetBit(ic->rUsed,R1_IDX);          
909             break;
910
911         case AOP_STK :
912         {
913             int sz = aop->size;    
914             int stk = aop->aopu.aop_stk + aop->size;
915             bitVectUnSetBit(ic->rUsed,R0_IDX);
916             bitVectUnSetBit(ic->rUsed,R1_IDX);          
917
918             getFreePtr(ic,&aop,FALSE);
919             
920             if (options.stack10bit)
921             {
922                 /* I'm not sure what to do here yet... */
923                 /* #STUB */
924                 fprintf(stderr, 
925                         "*** Warning: probably generating bad code for "
926                         "10 bit stack mode.\n");
927             }
928             
929             if (stk) {
930                 pic14_emitcode ("mov","a,_bp");
931                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
932                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
933             } else {
934                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
935             }
936
937             while (sz--) {
938                 pic14_emitcode("pop","acc");
939                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
940                 if (!sz) break;
941                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
942             }
943             op->aop = aop;
944             freeAsmop(op,NULL,ic,TRUE);
945             if (_G.r0Pushed) {
946                 pic14_emitcode("pop","ar0");
947                 _G.r0Pushed--;
948             }
949
950             if (_G.r1Pushed) {
951                 pic14_emitcode("pop","ar1");
952                 _G.r1Pushed--;
953             }       
954         }
955     }
956 #endif
957
958 dealloc:
959     /* all other cases just dealloc */
960     if (op ) {
961         op->aop = NULL;
962         if (IS_SYMOP(op)) {
963             OP_SYMBOL(op)->aop = NULL;    
964             /* if the symbol has a spill */
965             if (SPIL_LOC(op))
966                 SPIL_LOC(op)->aop = NULL;
967         }
968     }
969 }
970
971 /*-----------------------------------------------------------------*/
972 /* aopGet - for fetching value of the aop                          */
973 /*-----------------------------------------------------------------*/
974 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
975 {
976     char *s = buffer ;
977     char *rs;
978
979     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
980     /* offset is greater than
981     size then zero */
982     if (offset > (aop->size - 1) &&
983         aop->type != AOP_LIT)
984         return zero;
985
986     /* depending on type */
987     switch (aop->type) {
988         
989     case AOP_R0:
990     case AOP_R1:
991         DEBUGpic14_emitcode(";","%d",__LINE__);
992         /* if we need to increment it */       
993         while (offset > aop->coff) {        
994             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
995             aop->coff++;
996         }
997         
998         while (offset < aop->coff) {
999             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1000             aop->coff--;
1001         }
1002         
1003         aop->coff = offset ;
1004         if (aop->paged) {
1005             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1006             return (dname ? "acc" : "a");
1007         }       
1008         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1009         rs = Safe_calloc(1,strlen(s)+1);
1010         strcpy(rs,s);   
1011         return rs;
1012         
1013     case AOP_DPTR:
1014     case AOP_DPTR2:
1015         DEBUGpic14_emitcode(";","%d",__LINE__);
1016     if (aop->type == AOP_DPTR2)
1017     {
1018         genSetDPTR(1);
1019     }
1020     
1021         while (offset > aop->coff) {
1022             pic14_emitcode ("inc","dptr");
1023             aop->coff++;
1024         }
1025         
1026         while (offset < aop->coff) {        
1027             pic14_emitcode("lcall","__decdptr");
1028             aop->coff--;
1029         }
1030         
1031         aop->coff = offset;
1032         if (aop->code) {
1033             pic14_emitcode("clr","a");
1034             pic14_emitcode("movc","a,@a+dptr");
1035         }
1036     else {
1037             pic14_emitcode("movx","a,@dptr");
1038     }
1039             
1040     if (aop->type == AOP_DPTR2)
1041     {
1042         genSetDPTR(0);
1043     }
1044             
1045     return (dname ? "acc" : "a");
1046         
1047         
1048     case AOP_IMMD:
1049         if (bit16) 
1050             sprintf (s,"%s",aop->aopu.aop_immd);
1051         else
1052             if (offset) 
1053                 sprintf(s,"(%s >> %d)",
1054                         aop->aopu.aop_immd,
1055                         offset*8);
1056             else
1057                 sprintf(s,"%s",
1058                         aop->aopu.aop_immd);
1059         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1060         rs = Safe_calloc(1,strlen(s)+1);
1061         strcpy(rs,s);   
1062         return rs;
1063         
1064     case AOP_DIR:
1065       if (offset) {
1066         sprintf(s,"(%s + %d)",
1067                 aop->aopu.aop_dir,
1068                 offset);
1069         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1070       } else
1071             sprintf(s,"%s",aop->aopu.aop_dir);
1072         rs = Safe_calloc(1,strlen(s)+1);
1073         strcpy(rs,s);   
1074         return rs;
1075         
1076     case AOP_REG:
1077       //if (dname) 
1078       //    return aop->aopu.aop_reg[offset]->dname;
1079       //else
1080             return aop->aopu.aop_reg[offset]->name;
1081         
1082     case AOP_CRY:
1083       //pic14_emitcode(";","%d",__LINE__);
1084       return aop->aopu.aop_dir;
1085         
1086     case AOP_ACC:
1087         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1088         return "AOP_accumulator_bug";
1089
1090     case AOP_LIT:
1091         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1092         rs = Safe_calloc(1,strlen(s)+1);
1093         strcpy(rs,s);   
1094         return rs;
1095         
1096     case AOP_STR:
1097         DEBUGpic14_emitcode(";","%d",__LINE__);
1098         aop->coff = offset ;
1099         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1100             dname)
1101             return "acc";
1102         
1103         return aop->aopu.aop_str[offset];
1104         
1105     case AOP_PCODE:
1106       {
1107         pCodeOp *pcop = aop->aopu.pcop;
1108         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1109         if(pcop->name) {
1110           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1111           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1112           sprintf(s,"%s", pcop->name);
1113         } else
1114           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1115
1116       }
1117       rs = Safe_calloc(1,strlen(s)+1);
1118       strcpy(rs,s);   
1119       return rs;
1120
1121     }
1122
1123     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1124            "aopget got unsupported aop->type");
1125     exit(0);
1126 }
1127
1128
1129 /*-----------------------------------------------------------------*/
1130 /* popGetTempReg - create a new temporary pCodeOp                  */
1131 /*-----------------------------------------------------------------*/
1132 pCodeOp *popGetTempReg(void)
1133 {
1134
1135   pCodeOp *pcop;
1136
1137   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1138   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1139     PCOR(pcop)->r->wasUsed=1;
1140     PCOR(pcop)->r->isFree=0;
1141   }
1142
1143   return pcop;
1144 }
1145
1146 /*-----------------------------------------------------------------*/
1147 /* popGetTempReg - create a new temporary pCodeOp                  */
1148 /*-----------------------------------------------------------------*/
1149 void popReleaseTempReg(pCodeOp *pcop)
1150 {
1151
1152   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1153     PCOR(pcop)->r->isFree = 1;
1154
1155 }
1156 /*-----------------------------------------------------------------*/
1157 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1158 /*-----------------------------------------------------------------*/
1159 pCodeOp *popGetLabel(unsigned int key)
1160 {
1161
1162   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1163
1164   if(key>max_key)
1165     max_key = key;
1166
1167   return newpCodeOpLabel(NULL,key+100+labelOffset);
1168 }
1169
1170 /*-----------------------------------------------------------------*/
1171 /* popCopyReg - copy a pcode operator                              */
1172 /*-----------------------------------------------------------------*/
1173 pCodeOp *popCopyReg(pCodeOpReg *pc)
1174 {
1175   pCodeOpReg *pcor;
1176
1177   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1178   pcor->pcop.type = pc->pcop.type;
1179   if(pc->pcop.name) {
1180     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1181       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1182   } else
1183     pcor->pcop.name = NULL;
1184
1185   pcor->r = pc->r;
1186   pcor->rIdx = pc->rIdx;
1187   pcor->r->wasUsed=1;
1188
1189   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1190
1191   return PCOP(pcor);
1192 }
1193 /*-----------------------------------------------------------------*/
1194 /* popGet - asm operator to pcode operator conversion              */
1195 /*-----------------------------------------------------------------*/
1196 pCodeOp *popGetLit(unsigned int lit)
1197 {
1198
1199   return newpCodeOpLit(lit);
1200 }
1201
1202
1203 /*-----------------------------------------------------------------*/
1204 /* popGetImmd - asm operator to pcode immediate conversion         */
1205 /*-----------------------------------------------------------------*/
1206 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1207 {
1208
1209   return newpCodeOpImmd(name, offset,index, 0);
1210 }
1211
1212
1213 /*-----------------------------------------------------------------*/
1214 /* popGet - asm operator to pcode operator conversion              */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *popGetWithString(char *str)
1217 {
1218   pCodeOp *pcop;
1219
1220
1221   if(!str) {
1222     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1223     exit (1);
1224   }
1225
1226   pcop = newpCodeOp(str,PO_STR);
1227
1228   return pcop;
1229 }
1230
1231 pCodeOp *popRegFromString(char *str)
1232 {
1233
1234   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1235   pcop->type = PO_DIR;
1236
1237   DEBUGpic14_emitcode(";","%d",__LINE__);
1238   pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1239
1240   return pcop;
1241 }
1242
1243 pCodeOp *popRegFromIdx(int rIdx)
1244 {
1245   pCodeOp *pcop;
1246
1247   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1248                        __FUNCTION__,__LINE__,rIdx);
1249
1250   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1251
1252   PCOR(pcop)->rIdx = rIdx;
1253   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1254   PCOR(pcop)->r->isFree = 0;
1255   PCOR(pcop)->r->wasUsed = 1;
1256
1257   pcop->type = PCOR(pcop)->r->pc_type;
1258
1259
1260   return pcop;
1261 }
1262 /*-----------------------------------------------------------------*/
1263 /* popGet - asm operator to pcode operator conversion              */
1264 /*-----------------------------------------------------------------*/
1265 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1266 {
1267   //char *s = buffer ;
1268     //char *rs;
1269
1270     pCodeOp *pcop;
1271
1272     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1273     /* offset is greater than
1274     size then zero */
1275
1276     if (offset > (aop->size - 1) &&
1277         aop->type != AOP_LIT)
1278       return NULL;  //zero;
1279
1280     /* depending on type */
1281     switch (aop->type) {
1282         
1283     case AOP_R0:
1284     case AOP_R1:
1285     case AOP_DPTR:
1286     case AOP_DPTR2:
1287     case AOP_ACC:
1288         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1289         return NULL;
1290         
1291     case AOP_IMMD:
1292       DEBUGpic14_emitcode(";","%d",__LINE__);
1293       return popGetImmd(aop->aopu.aop_immd,offset,0);
1294
1295     case AOP_DIR:
1296         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1297         pcop->type = PO_DIR;
1298
1299         /*
1300         if (offset)
1301             sprintf(s,"(%s + %d)",
1302                     aop->aopu.aop_dir,
1303                     offset);
1304         else
1305             sprintf(s,"%s",aop->aopu.aop_dir);
1306         pcop->name = Safe_calloc(1,strlen(s)+1);
1307         strcpy(pcop->name,s);   
1308         */
1309         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1310         strcpy(pcop->name,aop->aopu.aop_dir);   
1311         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1312         if(PCOR(pcop)->r == NULL) {
1313           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1314           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1315         } 
1316
1317       DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1318         PCOR(pcop)->instance = offset;
1319
1320         return pcop;
1321         
1322     case AOP_REG:
1323       {
1324         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1325
1326         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1327         PCOR(pcop)->rIdx = rIdx;
1328         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1329         PCOR(pcop)->instance = offset;
1330         pcop->type = PCOR(pcop)->r->pc_type;
1331         //rs = aop->aopu.aop_reg[offset]->name;
1332         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1333         return pcop;
1334       }
1335
1336     case AOP_CRY:
1337       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1338       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1339       //if(PCOR(pcop)->r == NULL)
1340       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1341       return pcop;
1342         
1343     case AOP_LIT:
1344       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1345
1346     case AOP_STR:
1347       DEBUGpic14_emitcode(";","%d",__LINE__);
1348       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1349       /*
1350       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1351       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1352       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1353       pcop->type = PCOR(pcop)->r->pc_type;
1354       pcop->name = PCOR(pcop)->r->name;
1355
1356       return pcop;
1357       */
1358
1359     case AOP_PCODE:
1360       DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1361       pcop = pCodeOpCopy(aop->aopu.pcop);
1362       PCOI(pcop)->offset = offset;
1363       return pcop;
1364     }
1365
1366     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1367            "popGet got unsupported aop->type");
1368     exit(0);
1369 }
1370 /*-----------------------------------------------------------------*/
1371 /* aopPut - puts a string for a aop                                */
1372 /*-----------------------------------------------------------------*/
1373 void aopPut (asmop *aop, char *s, int offset)
1374 {
1375     char *d = buffer ;
1376     symbol *lbl ;
1377
1378     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1379
1380     if (aop->size && offset > ( aop->size - 1)) {
1381         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1382                "aopPut got offset > aop->size");
1383         exit(0);
1384     }
1385
1386     /* will assign value to value */
1387     /* depending on where it is ofcourse */
1388     switch (aop->type) {
1389     case AOP_DIR:
1390       if (offset) {
1391         sprintf(d,"(%s + %d)",
1392                 aop->aopu.aop_dir,offset);
1393         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1394
1395       } else
1396             sprintf(d,"%s",aop->aopu.aop_dir);
1397         
1398         if (strcmp(d,s)) {
1399           DEBUGpic14_emitcode(";","%d",__LINE__);
1400           if(strcmp(s,"W"))
1401             pic14_emitcode("movf","%s,w",s);
1402           pic14_emitcode("movwf","%s",d);
1403
1404           if(strcmp(s,"W")) {
1405             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1406             if(offset >= aop->size) {
1407               emitpcode(POC_CLRF,popGet(aop,offset));
1408               break;
1409             } else
1410               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1411           }
1412
1413           emitpcode(POC_MOVWF,popGet(aop,offset));
1414
1415
1416         }
1417         break;
1418         
1419     case AOP_REG:
1420       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1421         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1422           /*
1423             if (*s == '@'           ||
1424                 strcmp(s,"r0") == 0 ||
1425                 strcmp(s,"r1") == 0 ||
1426                 strcmp(s,"r2") == 0 ||
1427                 strcmp(s,"r3") == 0 ||
1428                 strcmp(s,"r4") == 0 ||
1429                 strcmp(s,"r5") == 0 ||
1430                 strcmp(s,"r6") == 0 || 
1431                 strcmp(s,"r7") == 0 )
1432                 pic14_emitcode("mov","%s,%s  ; %d",
1433                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1434             else
1435           */
1436
1437           if(strcmp(s,"W")==0 )
1438             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1439
1440           pic14_emitcode("movwf","%s",
1441                    aop->aopu.aop_reg[offset]->name);
1442
1443           if(strcmp(s,zero)==0) {
1444             emitpcode(POC_CLRF,popGet(aop,offset));
1445
1446           } else if(strcmp(s,"W")==0) {
1447             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1448             pcop->type = PO_GPR_REGISTER;
1449
1450             PCOR(pcop)->rIdx = -1;
1451             PCOR(pcop)->r = NULL;
1452
1453             DEBUGpic14_emitcode(";","%d",__LINE__);
1454             pcop->name = Safe_strdup(s);
1455             emitpcode(POC_MOVFW,pcop);
1456             emitpcode(POC_MOVWF,popGet(aop,offset));
1457           } else if(strcmp(s,one)==0) {
1458             emitpcode(POC_CLRF,popGet(aop,offset));
1459             emitpcode(POC_INCF,popGet(aop,offset));
1460           } else {
1461             emitpcode(POC_MOVWF,popGet(aop,offset));
1462           }
1463         }
1464         break;
1465         
1466     case AOP_DPTR:
1467     case AOP_DPTR2:
1468     
1469     if (aop->type == AOP_DPTR2)
1470     {
1471         genSetDPTR(1);
1472     }
1473     
1474         if (aop->code) {
1475             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1476                    "aopPut writting to code space");
1477             exit(0);
1478         }
1479         
1480         while (offset > aop->coff) {
1481             aop->coff++;
1482             pic14_emitcode ("inc","dptr");
1483         }
1484         
1485         while (offset < aop->coff) {
1486             aop->coff-- ;
1487             pic14_emitcode("lcall","__decdptr");
1488         }
1489         
1490         aop->coff = offset;
1491         
1492         /* if not in accumulater */
1493         MOVA(s);        
1494         
1495         pic14_emitcode ("movx","@dptr,a");
1496         
1497     if (aop->type == AOP_DPTR2)
1498     {
1499         genSetDPTR(0);
1500     }
1501         break;
1502         
1503     case AOP_R0:
1504     case AOP_R1:
1505         while (offset > aop->coff) {
1506             aop->coff++;
1507             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1508         }
1509         while (offset < aop->coff) {
1510             aop->coff-- ;
1511             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1512         }
1513         aop->coff = offset;
1514         
1515         if (aop->paged) {
1516             MOVA(s);           
1517             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1518             
1519         } else
1520             if (*s == '@') {
1521                 MOVA(s);
1522                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1523             } else
1524                 if (strcmp(s,"r0") == 0 ||
1525                     strcmp(s,"r1") == 0 ||
1526                     strcmp(s,"r2") == 0 ||
1527                     strcmp(s,"r3") == 0 ||
1528                     strcmp(s,"r4") == 0 ||
1529                     strcmp(s,"r5") == 0 ||
1530                     strcmp(s,"r6") == 0 || 
1531                     strcmp(s,"r7") == 0 ) {
1532                     char buffer[10];
1533                     sprintf(buffer,"a%s",s);
1534                     pic14_emitcode("mov","@%s,%s",
1535                              aop->aopu.aop_ptr->name,buffer);
1536                 } else
1537                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1538         
1539         break;
1540         
1541     case AOP_STK:
1542         if (strcmp(s,"a") == 0)
1543             pic14_emitcode("push","acc");
1544         else
1545             pic14_emitcode("push","%s",s);
1546         
1547         break;
1548         
1549     case AOP_CRY:
1550         /* if bit variable */
1551         if (!aop->aopu.aop_dir) {
1552             pic14_emitcode("clr","a");
1553             pic14_emitcode("rlc","a");
1554         } else {
1555             if (s == zero) 
1556                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1557             else
1558                 if (s == one)
1559                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1560                 else
1561                     if (!strcmp(s,"c"))
1562                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1563                     else {
1564                         lbl = newiTempLabel(NULL);
1565                         
1566                         if (strcmp(s,"a")) {
1567                             MOVA(s);
1568                         }
1569                         pic14_emitcode("clr","c");
1570                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1571                         pic14_emitcode("cpl","c");
1572                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1573                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1574                     }
1575         }
1576         break;
1577         
1578     case AOP_STR:
1579         aop->coff = offset;
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     case AOP_ACC:
1585         aop->coff = offset;
1586         if (!offset && (strcmp(s,"acc") == 0))
1587             break;
1588         
1589         if (strcmp(aop->aopu.aop_str[offset],s))
1590             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1591         break;
1592
1593     default :
1594         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1595                "aopPut got unsupported aop->type");
1596         exit(0);    
1597     }    
1598
1599 }
1600
1601 /*-----------------------------------------------------------------*/
1602 /* reAdjustPreg - points a register back to where it should        */
1603 /*-----------------------------------------------------------------*/
1604 static void reAdjustPreg (asmop *aop)
1605 {
1606     int size ;
1607
1608     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1609     aop->coff = 0;
1610     if ((size = aop->size) <= 1)
1611         return ;
1612     size-- ;
1613     switch (aop->type) {
1614         case AOP_R0 :
1615         case AOP_R1 :
1616             while (size--)
1617                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1618             break;          
1619         case AOP_DPTR :
1620         case AOP_DPTR2:
1621             if (aop->type == AOP_DPTR2)
1622             {
1623                 genSetDPTR(1);
1624             } 
1625             while (size--)
1626             {
1627                 pic14_emitcode("lcall","__decdptr");
1628             }
1629                 
1630             if (aop->type == AOP_DPTR2)
1631             {
1632                 genSetDPTR(0);
1633             }                
1634             break;  
1635
1636     }   
1637
1638 }
1639
1640 /*-----------------------------------------------------------------*/
1641 /* genNotFloat - generates not for float operations              */
1642 /*-----------------------------------------------------------------*/
1643 static void genNotFloat (operand *op, operand *res)
1644 {
1645     int size, offset;
1646     char *l;
1647     symbol *tlbl ;
1648
1649     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1650     /* we will put 127 in the first byte of 
1651     the result */
1652     aopPut(AOP(res),"#127",0);
1653     size = AOP_SIZE(op) - 1;
1654     offset = 1;
1655
1656     l = aopGet(op->aop,offset++,FALSE,FALSE);
1657     MOVA(l);    
1658
1659     while(size--) {
1660         pic14_emitcode("orl","a,%s",
1661                  aopGet(op->aop,
1662                         offset++,FALSE,FALSE));
1663     }
1664     tlbl = newiTempLabel(NULL);
1665
1666     tlbl = newiTempLabel(NULL);
1667     aopPut(res->aop,one,1);
1668     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1669     aopPut(res->aop,zero,1);
1670     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1671
1672     size = res->aop->size - 2;
1673     offset = 2;    
1674     /* put zeros in the rest */
1675     while (size--) 
1676         aopPut(res->aop,zero,offset++);
1677 }
1678
1679 #if 0
1680 /*-----------------------------------------------------------------*/
1681 /* opIsGptr: returns non-zero if the passed operand is             */   
1682 /* a generic pointer type.                                         */
1683 /*-----------------------------------------------------------------*/ 
1684 static int opIsGptr(operand *op)
1685 {
1686     sym_link *type = operandType(op);
1687     
1688     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1689     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1690     {
1691         return 1;
1692     }
1693     return 0;        
1694 }
1695 #endif
1696
1697 /*-----------------------------------------------------------------*/
1698 /* pic14_getDataSize - get the operand data size                         */
1699 /*-----------------------------------------------------------------*/
1700 int pic14_getDataSize(operand *op)
1701 {
1702     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1703
1704
1705     return AOP_SIZE(op);
1706
1707     // tsd- in the pic port, the genptr size is 1, so this code here
1708     // fails. ( in the 8051 port, the size was 4).
1709 #if 0
1710     int size;
1711     size = AOP_SIZE(op);
1712     if (size == GPTRSIZE)
1713     {
1714         sym_link *type = operandType(op);
1715         if (IS_GENPTR(type))
1716         {
1717             /* generic pointer; arithmetic operations
1718              * should ignore the high byte (pointer type).
1719              */
1720             size--;
1721     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1722         }
1723     }
1724     return size;
1725 #endif
1726 }
1727
1728 /*-----------------------------------------------------------------*/
1729 /* pic14_outAcc - output Acc                                             */
1730 /*-----------------------------------------------------------------*/
1731 void pic14_outAcc(operand *result)
1732 {
1733   int size,offset;
1734   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1735   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1736
1737
1738   size = pic14_getDataSize(result);
1739   if(size){
1740     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1741     size--;
1742     offset = 1;
1743     /* unsigned or positive */
1744     while(size--)
1745       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1746   }
1747
1748 }
1749
1750 /*-----------------------------------------------------------------*/
1751 /* pic14_outBitC - output a bit C                                        */
1752 /*-----------------------------------------------------------------*/
1753 void pic14_outBitC(operand *result)
1754 {
1755
1756     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1757     /* if the result is bit */
1758     if (AOP_TYPE(result) == AOP_CRY) 
1759         aopPut(AOP(result),"c",0);
1760     else {
1761         pic14_emitcode("clr","a  ; %d", __LINE__);
1762         pic14_emitcode("rlc","a");
1763         pic14_outAcc(result);
1764     }
1765 }
1766
1767 /*-----------------------------------------------------------------*/
1768 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1769 /*-----------------------------------------------------------------*/
1770 void pic14_toBoolean(operand *oper)
1771 {
1772     int size = AOP_SIZE(oper) - 1;
1773     int offset = 1;
1774
1775     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1776
1777     if ( AOP_TYPE(oper) != AOP_ACC) {
1778       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1779     }
1780     while (size--) {
1781       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1782     }
1783 }
1784
1785
1786 /*-----------------------------------------------------------------*/
1787 /* genNot - generate code for ! operation                          */
1788 /*-----------------------------------------------------------------*/
1789 static void genNot (iCode *ic)
1790 {
1791   symbol *tlbl;
1792   sym_link *optype = operandType(IC_LEFT(ic));
1793   int size;
1794
1795   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1796   /* assign asmOps to operand & result */
1797   aopOp (IC_LEFT(ic),ic,FALSE);
1798   aopOp (IC_RESULT(ic),ic,TRUE);
1799
1800   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1801   /* if in bit space then a special case */
1802   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1803     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1804       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1805       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1806     } else {
1807       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1808       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1809       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1810     }
1811     goto release;
1812   }
1813
1814   /* if type float then do float */
1815   if (IS_FLOAT(optype)) {
1816     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1817     goto release;
1818   }
1819
1820   size = AOP_SIZE(IC_RESULT(ic));
1821   if(size == 1) {
1822     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1823     emitpcode(POC_ANDLW,popGetLit(1));
1824     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1825     goto release;
1826   }
1827   pic14_toBoolean(IC_LEFT(ic));
1828
1829   tlbl = newiTempLabel(NULL);
1830   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1831   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1832   pic14_outBitC(IC_RESULT(ic));
1833
1834  release:    
1835   /* release the aops */
1836   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1837   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1838 }
1839
1840
1841 /*-----------------------------------------------------------------*/
1842 /* genCpl - generate code for complement                           */
1843 /*-----------------------------------------------------------------*/
1844 static void genCpl (iCode *ic)
1845 {
1846     int offset = 0;
1847     int size ;
1848
1849
1850     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1851     /* assign asmOps to operand & result */
1852     aopOp (IC_LEFT(ic),ic,FALSE);
1853     aopOp (IC_RESULT(ic),ic,TRUE);
1854
1855     /* if both are in bit space then 
1856     a special case */
1857     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1858         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1859
1860         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1861         pic14_emitcode("cpl","c"); 
1862         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1863         goto release; 
1864     } 
1865
1866     size = AOP_SIZE(IC_RESULT(ic));
1867     while (size--) {
1868         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1869         MOVA(l);       
1870         pic14_emitcode("cpl","a");
1871         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1872     }
1873
1874
1875 release:
1876     /* release the aops */
1877     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1878     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1879 }
1880
1881 /*-----------------------------------------------------------------*/
1882 /* genUminusFloat - unary minus for floating points                */
1883 /*-----------------------------------------------------------------*/
1884 static void genUminusFloat(operand *op,operand *result)
1885 {
1886     int size ,offset =0 ;
1887     char *l;
1888
1889     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1890     /* for this we just need to flip the 
1891     first it then copy the rest in place */
1892     size = AOP_SIZE(op) - 1;
1893     l = aopGet(AOP(op),3,FALSE,FALSE);
1894
1895     MOVA(l);    
1896
1897     pic14_emitcode("cpl","acc.7");
1898     aopPut(AOP(result),"a",3);    
1899
1900     while(size--) {
1901         aopPut(AOP(result),
1902                aopGet(AOP(op),offset,FALSE,FALSE),
1903                offset);
1904         offset++;
1905     }          
1906 }
1907
1908 /*-----------------------------------------------------------------*/
1909 /* genUminus - unary minus code generation                         */
1910 /*-----------------------------------------------------------------*/
1911 static void genUminus (iCode *ic)
1912 {
1913   int size, i;
1914   sym_link *optype, *rtype;
1915
1916
1917   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1918   /* assign asmops */
1919   aopOp(IC_LEFT(ic),ic,FALSE);
1920   aopOp(IC_RESULT(ic),ic,TRUE);
1921
1922   /* if both in bit space then special
1923      case */
1924   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1925       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1926
1927     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1928     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1929     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1930
1931     goto release; 
1932   } 
1933
1934   optype = operandType(IC_LEFT(ic));
1935   rtype = operandType(IC_RESULT(ic));
1936
1937   /* if float then do float stuff */
1938   if (IS_FLOAT(optype)) {
1939     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1940     goto release;
1941   }
1942
1943   /* otherwise subtract from zero by taking the 2's complement */
1944   size = AOP_SIZE(IC_LEFT(ic));
1945
1946   for(i=0; i<size; i++) {
1947     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1948       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1949     else {
1950       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1951       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1952     }
1953   }
1954
1955   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1956   for(i=1; i<size; i++) {
1957     emitSKPNZ;
1958     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1959   }
1960
1961  release:
1962   /* release the aops */
1963   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1964   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1965 }
1966
1967 /*-----------------------------------------------------------------*/
1968 /* saveRegisters - will look for a call and save the registers     */
1969 /*-----------------------------------------------------------------*/
1970 static void saveRegisters(iCode *lic) 
1971 {
1972     int i;
1973     iCode *ic;
1974     bitVect *rsave;
1975     sym_link *dtype;
1976
1977     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1978     /* look for call */
1979     for (ic = lic ; ic ; ic = ic->next) 
1980         if (ic->op == CALL || ic->op == PCALL)
1981             break;
1982
1983     if (!ic) {
1984         fprintf(stderr,"found parameter push with no function call\n");
1985         return ;
1986     }
1987
1988     /* if the registers have been saved already then
1989     do nothing */
1990     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1991         return ;
1992
1993     /* find the registers in use at this time 
1994     and push them away to safety */
1995     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1996                           ic->rUsed);
1997
1998     ic->regsSaved = 1;
1999     if (options.useXstack) {
2000         if (bitVectBitValue(rsave,R0_IDX))
2001             pic14_emitcode("mov","b,r0");
2002         pic14_emitcode("mov","r0,%s",spname);
2003         for (i = 0 ; i < pic14_nRegs ; i++) {
2004             if (bitVectBitValue(rsave,i)) {
2005                 if (i == R0_IDX)
2006                     pic14_emitcode("mov","a,b");
2007                 else
2008                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2009                 pic14_emitcode("movx","@r0,a");
2010                 pic14_emitcode("inc","r0");
2011             }
2012         }
2013         pic14_emitcode("mov","%s,r0",spname);
2014         if (bitVectBitValue(rsave,R0_IDX))
2015             pic14_emitcode("mov","r0,b");           
2016     }// else
2017     //for (i = 0 ; i < pic14_nRegs ; i++) {
2018     //    if (bitVectBitValue(rsave,i))
2019     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2020     //}
2021
2022     dtype = operandType(IC_LEFT(ic));
2023     if (currFunc && dtype && 
2024         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2025         IFFUNC_ISISR(currFunc->type) &&
2026         !ic->bankSaved) 
2027
2028         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2029
2030 }
2031 /*-----------------------------------------------------------------*/
2032 /* unsaveRegisters - pop the pushed registers                      */
2033 /*-----------------------------------------------------------------*/
2034 static void unsaveRegisters (iCode *ic)
2035 {
2036     int i;
2037     bitVect *rsave;
2038
2039     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2040     /* find the registers in use at this time 
2041     and push them away to safety */
2042     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2043                           ic->rUsed);
2044     
2045     if (options.useXstack) {
2046         pic14_emitcode("mov","r0,%s",spname);   
2047         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2048             if (bitVectBitValue(rsave,i)) {
2049                 pic14_emitcode("dec","r0");
2050                 pic14_emitcode("movx","a,@r0");
2051                 if (i == R0_IDX)
2052                     pic14_emitcode("mov","b,a");
2053                 else
2054                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2055             }       
2056
2057         }
2058         pic14_emitcode("mov","%s,r0",spname);
2059         if (bitVectBitValue(rsave,R0_IDX))
2060             pic14_emitcode("mov","r0,b");
2061     } //else
2062     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2063     //    if (bitVectBitValue(rsave,i))
2064     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2065     //}
2066
2067 }  
2068
2069
2070 /*-----------------------------------------------------------------*/
2071 /* pushSide -                                                      */
2072 /*-----------------------------------------------------------------*/
2073 static void pushSide(operand * oper, int size)
2074 {
2075 #if 0
2076         int offset = 0;
2077     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2078         while (size--) {
2079                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2080                 if (AOP_TYPE(oper) != AOP_REG &&
2081                     AOP_TYPE(oper) != AOP_DIR &&
2082                     strcmp(l,"a") ) {
2083                         pic14_emitcode("mov","a,%s",l);
2084                         pic14_emitcode("push","acc");
2085                 } else
2086                         pic14_emitcode("push","%s",l);
2087         }
2088 #endif
2089 }
2090
2091 /*-----------------------------------------------------------------*/
2092 /* assignResultValue -                                             */
2093 /*-----------------------------------------------------------------*/
2094 static void assignResultValue(operand * oper)
2095 {
2096   int size = AOP_SIZE(oper);
2097
2098   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2099
2100   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2101
2102   if(!GpsuedoStkPtr) {
2103     /* The last byte in the assignment is in W */
2104     size--;
2105     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2106     GpsuedoStkPtr++;
2107   }
2108
2109   while (size--) {
2110     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2111     GpsuedoStkPtr++;
2112     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2113   }
2114 }
2115
2116
2117 /*-----------------------------------------------------------------*/
2118 /* genIpush - genrate code for pushing this gets a little complex  */
2119 /*-----------------------------------------------------------------*/
2120 static void genIpush (iCode *ic)
2121 {
2122
2123   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2124 #if 0
2125     int size, offset = 0 ;
2126     char *l;
2127
2128
2129     /* if this is not a parm push : ie. it is spill push 
2130     and spill push is always done on the local stack */
2131     if (!ic->parmPush) {
2132
2133         /* and the item is spilt then do nothing */
2134         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2135             return ;
2136
2137         aopOp(IC_LEFT(ic),ic,FALSE);
2138         size = AOP_SIZE(IC_LEFT(ic));
2139         /* push it on the stack */
2140         while(size--) {
2141             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2142             if (*l == '#') {
2143                 MOVA(l);
2144                 l = "acc";
2145             }
2146             pic14_emitcode("push","%s",l);
2147         }
2148         return ;        
2149     }
2150
2151     /* this is a paramter push: in this case we call
2152     the routine to find the call and save those
2153     registers that need to be saved */   
2154     saveRegisters(ic);
2155
2156     /* then do the push */
2157     aopOp(IC_LEFT(ic),ic,FALSE);
2158
2159
2160         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2161     size = AOP_SIZE(IC_LEFT(ic));
2162
2163     while (size--) {
2164         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2165         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2166             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2167             strcmp(l,"a") ) {
2168             pic14_emitcode("mov","a,%s",l);
2169             pic14_emitcode("push","acc");
2170         } else
2171             pic14_emitcode("push","%s",l);
2172     }       
2173
2174     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2175 #endif
2176 }
2177
2178 /*-----------------------------------------------------------------*/
2179 /* genIpop - recover the registers: can happen only for spilling   */
2180 /*-----------------------------------------------------------------*/
2181 static void genIpop (iCode *ic)
2182 {
2183   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2184 #if 0
2185     int size,offset ;
2186
2187
2188     /* if the temp was not pushed then */
2189     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2190         return ;
2191
2192     aopOp(IC_LEFT(ic),ic,FALSE);
2193     size = AOP_SIZE(IC_LEFT(ic));
2194     offset = (size-1);
2195     while (size--) 
2196         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2197                                    FALSE,TRUE));
2198
2199     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2200 #endif
2201 }
2202
2203 /*-----------------------------------------------------------------*/
2204 /* unsaverbank - restores the resgister bank from stack            */
2205 /*-----------------------------------------------------------------*/
2206 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2207 {
2208   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2209 #if 0
2210     int i;
2211     asmop *aop ;
2212     regs *r = NULL;
2213
2214     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2215     if (popPsw) {
2216         if (options.useXstack) {
2217             aop = newAsmop(0);
2218             r = getFreePtr(ic,&aop,FALSE);
2219             
2220             
2221             pic14_emitcode("mov","%s,_spx",r->name);
2222             pic14_emitcode("movx","a,@%s",r->name);
2223             pic14_emitcode("mov","psw,a");
2224             pic14_emitcode("dec","%s",r->name);
2225             
2226         }else
2227             pic14_emitcode ("pop","psw");
2228     }
2229
2230     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2231         if (options.useXstack) {       
2232             pic14_emitcode("movx","a,@%s",r->name);
2233             //pic14_emitcode("mov","(%s+%d),a",
2234             //       regspic14[i].base,8*bank+regspic14[i].offset);
2235             pic14_emitcode("dec","%s",r->name);
2236
2237         } else 
2238           pic14_emitcode("pop",""); //"(%s+%d)",
2239         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2240     }
2241
2242     if (options.useXstack) {
2243
2244         pic14_emitcode("mov","_spx,%s",r->name);
2245         freeAsmop(NULL,aop,ic,TRUE);
2246
2247     }
2248 #endif 
2249 }
2250
2251 /*-----------------------------------------------------------------*/
2252 /* saverbank - saves an entire register bank on the stack          */
2253 /*-----------------------------------------------------------------*/
2254 static void saverbank (int bank, iCode *ic, bool pushPsw)
2255 {
2256   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2257 #if 0
2258     int i;
2259     asmop *aop ;
2260     regs *r = NULL;
2261
2262     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2263     if (options.useXstack) {
2264
2265         aop = newAsmop(0);
2266         r = getFreePtr(ic,&aop,FALSE);  
2267         pic14_emitcode("mov","%s,_spx",r->name);
2268
2269     }
2270
2271     for (i = 0 ; i < pic14_nRegs ;i++) {
2272         if (options.useXstack) {
2273             pic14_emitcode("inc","%s",r->name);
2274             //pic14_emitcode("mov","a,(%s+%d)",
2275             //         regspic14[i].base,8*bank+regspic14[i].offset);
2276             pic14_emitcode("movx","@%s,a",r->name);           
2277         } else 
2278           pic14_emitcode("push","");// "(%s+%d)",
2279                      //regspic14[i].base,8*bank+regspic14[i].offset);
2280     }
2281     
2282     if (pushPsw) {
2283         if (options.useXstack) {
2284             pic14_emitcode("mov","a,psw");
2285             pic14_emitcode("movx","@%s,a",r->name);     
2286             pic14_emitcode("inc","%s",r->name);
2287             pic14_emitcode("mov","_spx,%s",r->name);       
2288             freeAsmop (NULL,aop,ic,TRUE);
2289             
2290         } else
2291             pic14_emitcode("push","psw");
2292         
2293         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2294     }
2295     ic->bankSaved = 1;
2296 #endif
2297 }
2298
2299 /*-----------------------------------------------------------------*/
2300 /* genCall - generates a call statement                            */
2301 /*-----------------------------------------------------------------*/
2302 static void genCall (iCode *ic)
2303 {
2304   sym_link *dtype;   
2305
2306   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2307
2308   /* if caller saves & we have not saved then */
2309   if (!ic->regsSaved)
2310     saveRegisters(ic);
2311
2312   /* if we are calling a function that is not using
2313      the same register bank then we need to save the
2314      destination registers on the stack */
2315   dtype = operandType(IC_LEFT(ic));
2316   if (currFunc && dtype && 
2317       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2318       IFFUNC_ISISR(currFunc->type) &&
2319       !ic->bankSaved) 
2320
2321     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2322
2323   /* if send set is not empty the assign */
2324   if (_G.sendSet) {
2325     iCode *sic;
2326     /* For the Pic port, there is no data stack.
2327      * So parameters passed to functions are stored
2328      * in registers. (The pCode optimizer will get
2329      * rid of most of these :).
2330      */
2331     int psuedoStkPtr=-1; 
2332     int firstTimeThruLoop = 1;
2333
2334     _G.sendSet = reverseSet(_G.sendSet);
2335
2336     /* First figure how many parameters are getting passed */
2337     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2338          sic = setNextItem(_G.sendSet)) {
2339
2340       aopOp(IC_LEFT(sic),sic,FALSE);
2341       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2342       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2343     }
2344
2345     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2346          sic = setNextItem(_G.sendSet)) {
2347       int size, offset = 0;
2348
2349       aopOp(IC_LEFT(sic),sic,FALSE);
2350       size = AOP_SIZE(IC_LEFT(sic));
2351
2352       while (size--) {
2353         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2354                              AopType(AOP_TYPE(IC_LEFT(sic))));
2355
2356         if(!firstTimeThruLoop) {
2357           /* If this is not the first time we've been through the loop
2358            * then we need to save the parameter in a temporary
2359            * register. The last byte of the last parameter is
2360            * passed in W. */
2361           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2362
2363         }
2364         firstTimeThruLoop=0;
2365
2366         //if (strcmp(l,fReturn[offset])) {
2367
2368         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2369              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2370           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2371         else
2372           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2373
2374         //}
2375         offset++;
2376       }
2377       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2378     }
2379     _G.sendSet = NULL;
2380   }
2381   /* make the call */
2382   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2383                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2384                                       OP_SYMBOL(IC_LEFT(ic))->name));
2385
2386   GpsuedoStkPtr=0;
2387   /* if we need assign a result value */
2388   if ((IS_ITEMP(IC_RESULT(ic)) && 
2389        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2390         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2391       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2392
2393     _G.accInUse++;
2394     aopOp(IC_RESULT(ic),ic,FALSE);
2395     _G.accInUse--;
2396
2397     assignResultValue(IC_RESULT(ic));
2398
2399     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2400                          AopType(AOP_TYPE(IC_RESULT(ic))));
2401                 
2402     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2403   }
2404
2405   /* adjust the stack for parameters if 
2406      required */
2407   if (ic->parmBytes) {
2408     int i;
2409     if (ic->parmBytes > 3) {
2410       pic14_emitcode("mov","a,%s",spname);
2411       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2412       pic14_emitcode("mov","%s,a",spname);
2413     } else 
2414       for ( i = 0 ; i <  ic->parmBytes ;i++)
2415         pic14_emitcode("dec","%s",spname);
2416
2417   }
2418
2419   /* if register bank was saved then pop them */
2420   if (ic->bankSaved)
2421     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2422
2423   /* if we hade saved some registers then unsave them */
2424   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2425     unsaveRegisters (ic);
2426
2427
2428 }
2429
2430 /*-----------------------------------------------------------------*/
2431 /* genPcall - generates a call by pointer statement                */
2432 /*-----------------------------------------------------------------*/
2433 static void genPcall (iCode *ic)
2434 {
2435     sym_link *dtype;
2436     symbol *rlbl = newiTempLabel(NULL);
2437
2438
2439     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2440     /* if caller saves & we have not saved then */
2441     if (!ic->regsSaved)
2442         saveRegisters(ic);
2443
2444     /* if we are calling a function that is not using
2445     the same register bank then we need to save the
2446     destination registers on the stack */
2447     dtype = operandType(IC_LEFT(ic));
2448     if (currFunc && dtype && 
2449         IFFUNC_ISISR(currFunc->type) &&
2450         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2451         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2452
2453
2454     /* push the return address on to the stack */
2455     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2456     pic14_emitcode("push","acc");    
2457     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2458     pic14_emitcode("push","acc");
2459     
2460     if (options.model == MODEL_FLAT24)
2461     {
2462         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2463         pic14_emitcode("push","acc");    
2464     }
2465
2466     /* now push the calling address */
2467     aopOp(IC_LEFT(ic),ic,FALSE);
2468
2469     pushSide(IC_LEFT(ic), FPTRSIZE);
2470
2471     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2472
2473     /* if send set is not empty the assign */
2474     if (_G.sendSet) {
2475         iCode *sic ;
2476
2477         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2478              sic = setNextItem(_G.sendSet)) {
2479             int size, offset = 0;
2480             aopOp(IC_LEFT(sic),sic,FALSE);
2481             size = AOP_SIZE(IC_LEFT(sic));
2482             while (size--) {
2483                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2484                                 FALSE,FALSE);
2485                 if (strcmp(l,fReturn[offset]))
2486                     pic14_emitcode("mov","%s,%s",
2487                              fReturn[offset],
2488                              l);
2489                 offset++;
2490             }
2491             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2492         }
2493         _G.sendSet = NULL;
2494     }
2495
2496     pic14_emitcode("ret","");
2497     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2498
2499
2500     /* if we need assign a result value */
2501     if ((IS_ITEMP(IC_RESULT(ic)) &&
2502          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2503           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2504         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2505
2506         _G.accInUse++;
2507         aopOp(IC_RESULT(ic),ic,FALSE);
2508         _G.accInUse--;
2509         
2510         assignResultValue(IC_RESULT(ic));
2511
2512         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2513     }
2514
2515     /* adjust the stack for parameters if 
2516     required */
2517     if (ic->parmBytes) {
2518         int i;
2519         if (ic->parmBytes > 3) {
2520             pic14_emitcode("mov","a,%s",spname);
2521             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2522             pic14_emitcode("mov","%s,a",spname);
2523         } else 
2524             for ( i = 0 ; i <  ic->parmBytes ;i++)
2525                 pic14_emitcode("dec","%s",spname);
2526
2527     }
2528
2529     /* if register bank was saved then unsave them */
2530     if (currFunc && dtype && 
2531         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533
2534     /* if we hade saved some registers then
2535     unsave them */
2536     if (ic->regsSaved)
2537         unsaveRegisters (ic);
2538
2539 }
2540
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result  is rematerializable                       */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2545 {
2546     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2547     if (SKIP_IC(ic) || ic->op == IFX)
2548         return 0;
2549
2550     if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552         if (sym->remat && !POINTER_SET(ic)) 
2553             return 1;
2554     }
2555
2556     return 0;
2557 }
2558
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2561 #else
2562 #define STRCASECMP strcasecmp
2563 #endif
2564
2565 #if 0
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2570 {
2571   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2572     int i =0;
2573     
2574     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2575     if (options.excludeRegs[i] &&
2576     STRCASECMP(options.excludeRegs[i],"none") == 0)
2577         return FALSE ;
2578
2579     for ( i = 0 ; options.excludeRegs[i]; i++) {
2580         if (options.excludeRegs[i] &&
2581         STRCASECMP(s,options.excludeRegs[i]) == 0)
2582             return TRUE;
2583     }
2584     return FALSE ;
2585 }
2586 #endif
2587
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry                 */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2592 {
2593     symbol *sym;
2594     sym_link *ftype;
2595
2596     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2597
2598     labelOffset += (max_key+4);
2599     max_key=0;
2600     GpsuedoStkPtr=0;
2601     _G.nRegsSaved = 0;
2602     /* create the function header */
2603     pic14_emitcode(";","-----------------------------------------");
2604     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605     pic14_emitcode(";","-----------------------------------------");
2606
2607     pic14_emitcode("","%s:",sym->rname);
2608     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2609
2610     ftype = operandType(IC_LEFT(ic));
2611
2612     /* if critical function then turn interrupts off */
2613     if (IFFUNC_ISCRITICAL(ftype))
2614         pic14_emitcode("clr","ea");
2615
2616     /* here we need to generate the equates for the
2617        register bank if required */
2618 #if 0
2619     if (FUNC_REGBANK(ftype) != rbank) {
2620         int i ;
2621
2622         rbank = FUNC_REGBANK(ftype);
2623         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624             if (strcmp(regspic14[i].base,"0") == 0)
2625                 pic14_emitcode("","%s = 0x%02x",
2626                          regspic14[i].dname,
2627                          8*rbank+regspic14[i].offset);
2628             else
2629                 pic14_emitcode ("","%s = %s + 0x%02x",
2630                           regspic14[i].dname,
2631                           regspic14[i].base,
2632                           8*rbank+regspic14[i].offset);
2633         }
2634     }
2635 #endif
2636
2637     /* if this is an interrupt service routine then
2638     save acc, b, dpl, dph  */
2639     if (IFFUNC_ISISR(sym->type)) {
2640       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641       emitpcodeNULLop(POC_NOP);
2642       emitpcodeNULLop(POC_NOP);
2643       emitpcodeNULLop(POC_NOP);
2644       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2645       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2646       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2647       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2648
2649       pBlockConvert2ISR(pb);
2650 #if 0  
2651         if (!inExcludeList("acc"))          
2652             pic14_emitcode ("push","acc");      
2653         if (!inExcludeList("b"))
2654             pic14_emitcode ("push","b");
2655         if (!inExcludeList("dpl"))
2656             pic14_emitcode ("push","dpl");
2657         if (!inExcludeList("dph"))
2658             pic14_emitcode ("push","dph");
2659         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2660         {
2661             pic14_emitcode ("push", "dpx");
2662             /* Make sure we're using standard DPTR */
2663             pic14_emitcode ("push", "dps");
2664             pic14_emitcode ("mov", "dps, #0x00");
2665             if (options.stack10bit)
2666             {   
2667                 /* This ISR could conceivably use DPTR2. Better save it. */
2668                 pic14_emitcode ("push", "dpl1");
2669                 pic14_emitcode ("push", "dph1");
2670                 pic14_emitcode ("push", "dpx1");
2671             }
2672         }
2673         /* if this isr has no bank i.e. is going to
2674            run with bank 0 , then we need to save more
2675            registers :-) */
2676         if (!FUNC_REGBANK(sym->type)) {
2677
2678             /* if this function does not call any other
2679                function then we can be economical and
2680                save only those registers that are used */
2681             if (! IFFUNC_HASFCALL(sym->type)) {
2682                 int i;
2683
2684                 /* if any registers used */
2685                 if (sym->regsUsed) {
2686                     /* save the registers used */
2687                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2688                         if (bitVectBitValue(sym->regsUsed,i) ||
2689                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2690                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2691                     }
2692                 }
2693                 
2694             } else {
2695                 /* this function has  a function call cannot
2696                    determines register usage so we will have the
2697                    entire bank */
2698                 saverbank(0,ic,FALSE);
2699             }       
2700         }
2701 #endif
2702     } else {
2703         /* if callee-save to be used for this function
2704            then save the registers being used in this function */
2705         if (IFFUNC_CALLEESAVES(sym->type)) {
2706             int i;
2707             
2708             /* if any registers used */
2709             if (sym->regsUsed) {
2710                 /* save the registers used */
2711                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2712                     if (bitVectBitValue(sym->regsUsed,i) ||
2713                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2714                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2715                         _G.nRegsSaved++;
2716                     }
2717                 }
2718             }
2719         }
2720     }
2721
2722     /* set the register bank to the desired value */
2723     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2724         pic14_emitcode("push","psw");
2725         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2726     }
2727
2728     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2729
2730         if (options.useXstack) {
2731             pic14_emitcode("mov","r0,%s",spname);
2732             pic14_emitcode("mov","a,_bp");
2733             pic14_emitcode("movx","@r0,a");
2734             pic14_emitcode("inc","%s",spname);
2735         }
2736         else
2737         {
2738             /* set up the stack */
2739             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2740         }
2741         pic14_emitcode ("mov","_bp,%s",spname);
2742     }
2743
2744     /* adjust the stack for the function */
2745     if (sym->stack) {
2746
2747         int i = sym->stack;
2748         if (i > 256 ) 
2749             werror(W_STACK_OVERFLOW,sym->name);
2750
2751         if (i > 3 && sym->recvSize < 4) {              
2752
2753             pic14_emitcode ("mov","a,sp");
2754             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2755             pic14_emitcode ("mov","sp,a");
2756            
2757         }
2758         else
2759             while(i--)
2760                 pic14_emitcode("inc","sp");
2761     }
2762
2763      if (sym->xstack) {
2764
2765         pic14_emitcode ("mov","a,_spx");
2766         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2767         pic14_emitcode ("mov","_spx,a");
2768     }    
2769
2770 }
2771
2772 /*-----------------------------------------------------------------*/
2773 /* genEndFunction - generates epilogue for functions               */
2774 /*-----------------------------------------------------------------*/
2775 static void genEndFunction (iCode *ic)
2776 {
2777     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2778
2779     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2780
2781     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2782     {
2783         pic14_emitcode ("mov","%s,_bp",spname);
2784     }
2785
2786     /* if use external stack but some variables were
2787     added to the local stack then decrement the
2788     local stack */
2789     if (options.useXstack && sym->stack) {      
2790         pic14_emitcode("mov","a,sp");
2791         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2792         pic14_emitcode("mov","sp,a");
2793     }
2794
2795
2796     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2797         if (options.useXstack) {
2798             pic14_emitcode("mov","r0,%s",spname);
2799             pic14_emitcode("movx","a,@r0");
2800             pic14_emitcode("mov","_bp,a");
2801             pic14_emitcode("dec","%s",spname);
2802         }
2803         else
2804         {
2805             pic14_emitcode ("pop","_bp");
2806         }
2807     }
2808
2809     /* restore the register bank  */    
2810     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2811         pic14_emitcode ("pop","psw");
2812
2813     if (IFFUNC_ISISR(sym->type)) {
2814
2815         /* now we need to restore the registers */
2816         /* if this isr has no bank i.e. is going to
2817            run with bank 0 , then we need to save more
2818            registers :-) */
2819         if (!FUNC_REGBANK(sym->type)) {
2820             
2821             /* if this function does not call any other
2822                function then we can be economical and
2823                save only those registers that are used */
2824             if (! IFFUNC_HASFCALL(sym->type)) {
2825                 int i;
2826                 
2827                 /* if any registers used */
2828                 if (sym->regsUsed) {
2829                     /* save the registers used */
2830                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2831                         if (bitVectBitValue(sym->regsUsed,i) ||
2832                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2833                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2834                     }
2835                 }
2836                 
2837             } else {
2838                 /* this function has  a function call cannot
2839                    determines register usage so we will have the
2840                    entire bank */
2841                 unsaverbank(0,ic,FALSE);
2842             }       
2843         }
2844 #if 0
2845         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2846         {
2847             if (options.stack10bit)
2848             {
2849                 pic14_emitcode ("pop", "dpx1");
2850                 pic14_emitcode ("pop", "dph1");
2851                 pic14_emitcode ("pop", "dpl1");
2852             }   
2853             pic14_emitcode ("pop", "dps");
2854             pic14_emitcode ("pop", "dpx");
2855         }
2856         if (!inExcludeList("dph"))
2857             pic14_emitcode ("pop","dph");
2858         if (!inExcludeList("dpl"))
2859             pic14_emitcode ("pop","dpl");
2860         if (!inExcludeList("b"))
2861             pic14_emitcode ("pop","b");
2862         if (!inExcludeList("acc"))
2863             pic14_emitcode ("pop","acc");
2864
2865         if (IFFUNC_ISCRITICAL(sym->type))
2866             pic14_emitcode("setb","ea");
2867 #endif
2868
2869         /* if debug then send end of function */
2870 /*      if (options.debug && currFunc) { */
2871         if (currFunc) {
2872             _G.debugLine = 1;
2873             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2874                      FileBaseName(ic->filename),currFunc->lastLine,
2875                      ic->level,ic->block); 
2876             if (IS_STATIC(currFunc->etype))         
2877                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2878             else
2879                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2880             _G.debugLine = 0;
2881         }
2882         
2883         pic14_emitcode ("reti","");
2884
2885         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2886         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2887         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2888         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2889         emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
2890         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2891
2892         emitpcodeNULLop(POC_RETFIE);
2893
2894     }
2895     else {
2896         if (IFFUNC_ISCRITICAL(sym->type))
2897             pic14_emitcode("setb","ea");
2898         
2899         if (IFFUNC_CALLEESAVES(sym->type)) {
2900             int i;
2901             
2902             /* if any registers used */
2903             if (sym->regsUsed) {
2904                 /* save the registers used */
2905                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2906                     if (bitVectBitValue(sym->regsUsed,i) ||
2907                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2908                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2909                 }
2910             }
2911             
2912         }
2913
2914         /* if debug then send end of function */
2915         if (currFunc) {
2916             _G.debugLine = 1;
2917             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2918                      FileBaseName(ic->filename),currFunc->lastLine,
2919                      ic->level,ic->block); 
2920             if (IS_STATIC(currFunc->etype))         
2921                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2922             else
2923                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2924             _G.debugLine = 0;
2925         }
2926
2927         pic14_emitcode ("return","");
2928         emitpcodeNULLop(POC_RETURN);
2929
2930         /* Mark the end of a function */
2931         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2932     }
2933
2934 }
2935
2936 /*-----------------------------------------------------------------*/
2937 /* genRet - generate code for return statement                     */
2938 /*-----------------------------------------------------------------*/
2939 static void genRet (iCode *ic)
2940 {
2941   int size,offset = 0 , pushed = 0;
2942     
2943   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2944   /* if we have no return value then
2945      just generate the "ret" */
2946   if (!IC_LEFT(ic)) 
2947     goto jumpret;       
2948     
2949   /* we have something to return then
2950      move the return value into place */
2951   aopOp(IC_LEFT(ic),ic,FALSE);
2952   size = AOP_SIZE(IC_LEFT(ic));
2953     
2954   while (size--) {
2955     char *l ;
2956     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2957       /* #NOCHANGE */
2958       l = aopGet(AOP(IC_LEFT(ic)),offset++,
2959                  FALSE,TRUE);
2960       pic14_emitcode("push","%s",l);
2961       pushed++;
2962     } else {
2963       l = aopGet(AOP(IC_LEFT(ic)),offset,
2964                  FALSE,FALSE);
2965       if (strcmp(fReturn[offset],l)) {
2966         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2967             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2968           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2969         }else {
2970           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2971         }
2972         if(size) {
2973           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2974           pic14_emitcode("movwf","%s",fReturn[offset]);
2975         }
2976         offset++;
2977       }
2978     }
2979   }    
2980
2981   if (pushed) {
2982     while(pushed) {
2983       pushed--;
2984       if (strcmp(fReturn[pushed],"a"))
2985         pic14_emitcode("pop",fReturn[pushed]);
2986       else
2987         pic14_emitcode("pop","acc");
2988     }
2989   }
2990   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2991     
2992  jumpret:
2993   /* generate a jump to the return label
2994      if the next is not the return statement */
2995   if (!(ic->next && ic->next->op == LABEL &&
2996         IC_LABEL(ic->next) == returnLabel)) {
2997         
2998     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2999     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3000   }
3001     
3002 }
3003
3004 /*-----------------------------------------------------------------*/
3005 /* genLabel - generates a label                                    */
3006 /*-----------------------------------------------------------------*/
3007 static void genLabel (iCode *ic)
3008 {
3009     /* special case never generate */
3010     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3011     if (IC_LABEL(ic) == entryLabel)
3012         return ;
3013
3014     emitpLabel(IC_LABEL(ic)->key);
3015     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3016 }
3017
3018 /*-----------------------------------------------------------------*/
3019 /* genGoto - generates a goto                                      */
3020 /*-----------------------------------------------------------------*/
3021 //tsd
3022 static void genGoto (iCode *ic)
3023 {
3024   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3025   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3026 }
3027
3028
3029 /*-----------------------------------------------------------------*/
3030 /* genMultbits :- multiplication of bits                           */
3031 /*-----------------------------------------------------------------*/
3032 static void genMultbits (operand *left, 
3033                          operand *right, 
3034                          operand *result)
3035 {
3036   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3037
3038   if(!pic14_sameRegs(AOP(result),AOP(right)))
3039     emitpcode(POC_BSF,  popGet(AOP(result),0));
3040
3041   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3042   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3043   emitpcode(POC_BCF,  popGet(AOP(result),0));
3044
3045 }
3046
3047
3048 /*-----------------------------------------------------------------*/
3049 /* genMultOneByte : 8 bit multiplication & division                */
3050 /*-----------------------------------------------------------------*/
3051 static void genMultOneByte (operand *left,
3052                             operand *right,
3053                             operand *result)
3054 {
3055   sym_link *opetype = operandType(result);
3056
3057   // symbol *lbl ;
3058   int size,offset;
3059
3060   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3061   DEBUGpic14_AopType(__LINE__,left,right,result);
3062   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3063
3064   /* (if two literals, the value is computed before) */
3065   /* if one literal, literal on the right */
3066   if (AOP_TYPE(left) == AOP_LIT){
3067     operand *t = right;
3068     right = left;
3069     left = t;
3070   }
3071
3072   size = AOP_SIZE(result);
3073   if(size == 1) {
3074
3075     if (AOP_TYPE(right) == AOP_LIT){
3076       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3077                      aopGet(AOP(right),0,FALSE,FALSE), 
3078                      aopGet(AOP(left),0,FALSE,FALSE), 
3079                      aopGet(AOP(result),0,FALSE,FALSE));
3080       pic14_emitcode("call","genMultLit");
3081     } else {
3082       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3083                      aopGet(AOP(right),0,FALSE,FALSE), 
3084                      aopGet(AOP(left),0,FALSE,FALSE), 
3085                      aopGet(AOP(result),0,FALSE,FALSE));
3086       pic14_emitcode("call","genMult8X8_8");
3087
3088     }
3089     genMult8X8_8 (left, right,result);
3090
3091
3092     /* signed or unsigned */
3093     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3094     //l = aopGet(AOP(left),0,FALSE,FALSE);
3095     //MOVA(l);       
3096     //pic14_emitcode("mul","ab");
3097     /* if result size = 1, mul signed = mul unsigned */
3098     //aopPut(AOP(result),"a",0);
3099
3100   } else {  // (size > 1)
3101
3102     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3103                    aopGet(AOP(right),0,FALSE,FALSE), 
3104                    aopGet(AOP(left),0,FALSE,FALSE), 
3105                    aopGet(AOP(result),0,FALSE,FALSE));
3106
3107     if (SPEC_USIGN(opetype)){
3108       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3109       genUMult8X8_16 (left, right, result, NULL);
3110
3111       if (size > 2) {
3112         /* for filling the MSBs */
3113         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3114         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3115       }
3116     }
3117     else{
3118       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3119
3120       pic14_emitcode("mov","a,b");
3121
3122       /* adjust the MSB if left or right neg */
3123
3124       /* if one literal */
3125       if (AOP_TYPE(right) == AOP_LIT){
3126         pic14_emitcode("multiply ","right is a lit");
3127         /* AND literal negative */
3128         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3129           /* adjust MSB (c==0 after mul) */
3130           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3131         }
3132       }
3133       else{
3134         genSMult8X8_16 (left, right, result, NULL);
3135       }
3136
3137       if(size > 2){
3138         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3139         /* get the sign */
3140         pic14_emitcode("rlc","a");
3141         pic14_emitcode("subb","a,acc");
3142       }
3143     }
3144
3145     size -= 2;   
3146     offset = 2;
3147     if (size > 0)
3148       while (size--)
3149         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3150     //aopPut(AOP(result),"a",offset++);
3151   }
3152 }
3153
3154 /*-----------------------------------------------------------------*/
3155 /* genMult - generates code for multiplication                     */
3156 /*-----------------------------------------------------------------*/
3157 static void genMult (iCode *ic)
3158 {
3159     operand *left = IC_LEFT(ic);
3160     operand *right = IC_RIGHT(ic);
3161     operand *result= IC_RESULT(ic);   
3162
3163     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3164     /* assign the amsops */
3165     aopOp (left,ic,FALSE);
3166     aopOp (right,ic,FALSE);
3167     aopOp (result,ic,TRUE);
3168
3169   DEBUGpic14_AopType(__LINE__,left,right,result);
3170
3171     /* special cases first */
3172     /* both are bits */
3173     if (AOP_TYPE(left) == AOP_CRY &&
3174         AOP_TYPE(right)== AOP_CRY) {
3175         genMultbits(left,right,result);
3176         goto release ;
3177     }
3178
3179     /* if both are of size == 1 */
3180     if (AOP_SIZE(left) == 1 &&
3181         AOP_SIZE(right) == 1 ) {
3182         genMultOneByte(left,right,result);
3183         goto release ;
3184     }
3185
3186     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3187
3188     /* should have been converted to function call */
3189     //assert(0) ;
3190
3191 release :
3192     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3193     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3194     freeAsmop(result,NULL,ic,TRUE); 
3195 }
3196
3197 /*-----------------------------------------------------------------*/
3198 /* genDivbits :- division of bits                                  */
3199 /*-----------------------------------------------------------------*/
3200 static void genDivbits (operand *left, 
3201                         operand *right, 
3202                         operand *result)
3203 {
3204
3205     char *l;
3206
3207     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3208     /* the result must be bit */    
3209     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3210     l = aopGet(AOP(left),0,FALSE,FALSE);
3211
3212     MOVA(l);    
3213
3214     pic14_emitcode("div","ab");
3215     pic14_emitcode("rrc","a");
3216     aopPut(AOP(result),"c",0);
3217 }
3218
3219 /*-----------------------------------------------------------------*/
3220 /* genDivOneByte : 8 bit division                                  */
3221 /*-----------------------------------------------------------------*/
3222 static void genDivOneByte (operand *left,
3223                            operand *right,
3224                            operand *result)
3225 {
3226     sym_link *opetype = operandType(result);
3227     char *l ;
3228     symbol *lbl ;
3229     int size,offset;
3230
3231     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3232     size = AOP_SIZE(result) - 1;
3233     offset = 1;
3234     /* signed or unsigned */
3235     if (SPEC_USIGN(opetype)) {
3236         /* unsigned is easy */
3237         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3238         l = aopGet(AOP(left),0,FALSE,FALSE);
3239         MOVA(l);        
3240         pic14_emitcode("div","ab");
3241         aopPut(AOP(result),"a",0);
3242         while (size--)
3243             aopPut(AOP(result),zero,offset++);
3244         return ;
3245     }
3246
3247     /* signed is a little bit more difficult */
3248
3249     /* save the signs of the operands */
3250     l = aopGet(AOP(left),0,FALSE,FALSE);    
3251     MOVA(l);    
3252     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3253     pic14_emitcode("push","acc"); /* save it on the stack */
3254
3255     /* now sign adjust for both left & right */
3256     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3257     MOVA(l);       
3258     lbl = newiTempLabel(NULL);
3259     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3260     pic14_emitcode("cpl","a");   
3261     pic14_emitcode("inc","a");
3262     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263     pic14_emitcode("mov","b,a");
3264
3265     /* sign adjust left side */
3266     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3267     MOVA(l);
3268
3269     lbl = newiTempLabel(NULL);
3270     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3271     pic14_emitcode("cpl","a");
3272     pic14_emitcode("inc","a");
3273     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3274
3275     /* now the division */
3276     pic14_emitcode("div","ab");
3277     /* we are interested in the lower order
3278     only */
3279     pic14_emitcode("mov","b,a");
3280     lbl = newiTempLabel(NULL);
3281     pic14_emitcode("pop","acc");   
3282     /* if there was an over flow we don't 
3283     adjust the sign of the result */
3284     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3285     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3286     CLRC;
3287     pic14_emitcode("clr","a");
3288     pic14_emitcode("subb","a,b");
3289     pic14_emitcode("mov","b,a");
3290     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3291
3292     /* now we are done */
3293     aopPut(AOP(result),"b",0);
3294     if(size > 0){
3295         pic14_emitcode("mov","c,b.7");
3296         pic14_emitcode("subb","a,acc");   
3297     }
3298     while (size--)
3299         aopPut(AOP(result),"a",offset++);
3300
3301 }
3302
3303 /*-----------------------------------------------------------------*/
3304 /* genDiv - generates code for division                            */
3305 /*-----------------------------------------------------------------*/
3306 static void genDiv (iCode *ic)
3307 {
3308     operand *left = IC_LEFT(ic);
3309     operand *right = IC_RIGHT(ic);
3310     operand *result= IC_RESULT(ic);   
3311
3312     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3313     /* assign the amsops */
3314     aopOp (left,ic,FALSE);
3315     aopOp (right,ic,FALSE);
3316     aopOp (result,ic,TRUE);
3317
3318     /* special cases first */
3319     /* both are bits */
3320     if (AOP_TYPE(left) == AOP_CRY &&
3321         AOP_TYPE(right)== AOP_CRY) {
3322         genDivbits(left,right,result);
3323         goto release ;
3324     }
3325
3326     /* if both are of size == 1 */
3327     if (AOP_SIZE(left) == 1 &&
3328         AOP_SIZE(right) == 1 ) {
3329         genDivOneByte(left,right,result);
3330         goto release ;
3331     }
3332
3333     /* should have been converted to function call */
3334     assert(0);
3335 release :
3336     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3337     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3338     freeAsmop(result,NULL,ic,TRUE); 
3339 }
3340
3341 /*-----------------------------------------------------------------*/
3342 /* genModbits :- modulus of bits                                   */
3343 /*-----------------------------------------------------------------*/
3344 static void genModbits (operand *left, 
3345                         operand *right, 
3346                         operand *result)
3347 {
3348
3349     char *l;
3350
3351     /* the result must be bit */    
3352     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3353     l = aopGet(AOP(left),0,FALSE,FALSE);
3354
3355     MOVA(l);       
3356
3357     pic14_emitcode("div","ab");
3358     pic14_emitcode("mov","a,b");
3359     pic14_emitcode("rrc","a");
3360     aopPut(AOP(result),"c",0);
3361 }
3362
3363 /*-----------------------------------------------------------------*/
3364 /* genModOneByte : 8 bit modulus                                   */
3365 /*-----------------------------------------------------------------*/
3366 static void genModOneByte (operand *left,
3367                            operand *right,
3368                            operand *result)
3369 {
3370     sym_link *opetype = operandType(result);
3371     char *l ;
3372     symbol *lbl ;
3373
3374     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3375     /* signed or unsigned */
3376     if (SPEC_USIGN(opetype)) {
3377         /* unsigned is easy */
3378         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3379         l = aopGet(AOP(left),0,FALSE,FALSE);
3380         MOVA(l);    
3381         pic14_emitcode("div","ab");
3382         aopPut(AOP(result),"b",0);
3383         return ;
3384     }
3385
3386     /* signed is a little bit more difficult */
3387
3388     /* save the signs of the operands */
3389     l = aopGet(AOP(left),0,FALSE,FALSE);    
3390     MOVA(l);
3391
3392     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3393     pic14_emitcode("push","acc"); /* save it on the stack */
3394
3395     /* now sign adjust for both left & right */
3396     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3397     MOVA(l);
3398
3399     lbl = newiTempLabel(NULL);
3400     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3401     pic14_emitcode("cpl","a");   
3402     pic14_emitcode("inc","a");
3403     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3404     pic14_emitcode("mov","b,a"); 
3405
3406     /* sign adjust left side */
3407     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3408     MOVA(l);
3409
3410     lbl = newiTempLabel(NULL);
3411     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3412     pic14_emitcode("cpl","a");   
3413     pic14_emitcode("inc","a");
3414     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3415
3416     /* now the multiplication */
3417     pic14_emitcode("div","ab");
3418     /* we are interested in the lower order
3419     only */
3420     lbl = newiTempLabel(NULL);
3421     pic14_emitcode("pop","acc");   
3422     /* if there was an over flow we don't 
3423     adjust the sign of the result */
3424     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3425     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3426     CLRC ;
3427     pic14_emitcode("clr","a");
3428     pic14_emitcode("subb","a,b");
3429     pic14_emitcode("mov","b,a");
3430     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3431
3432     /* now we are done */
3433     aopPut(AOP(result),"b",0);
3434
3435 }
3436
3437 /*-----------------------------------------------------------------*/
3438 /* genMod - generates code for division                            */
3439 /*-----------------------------------------------------------------*/
3440 static void genMod (iCode *ic)
3441 {
3442     operand *left = IC_LEFT(ic);
3443     operand *right = IC_RIGHT(ic);
3444     operand *result= IC_RESULT(ic);  
3445
3446     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3447     /* assign the amsops */
3448     aopOp (left,ic,FALSE);
3449     aopOp (right,ic,FALSE);
3450     aopOp (result,ic,TRUE);
3451
3452     /* special cases first */
3453     /* both are bits */
3454     if (AOP_TYPE(left) == AOP_CRY &&
3455         AOP_TYPE(right)== AOP_CRY) {
3456         genModbits(left,right,result);
3457         goto release ;
3458     }
3459
3460     /* if both are of size == 1 */
3461     if (AOP_SIZE(left) == 1 &&
3462         AOP_SIZE(right) == 1 ) {
3463         genModOneByte(left,right,result);
3464         goto release ;
3465     }
3466
3467     /* should have been converted to function call */
3468     assert(0);
3469
3470 release :
3471     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3472     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3473     freeAsmop(result,NULL,ic,TRUE); 
3474 }
3475
3476 /*-----------------------------------------------------------------*/
3477 /* genIfxJump :- will create a jump depending on the ifx           */
3478 /*-----------------------------------------------------------------*/
3479 /*
3480   note: May need to add parameter to indicate when a variable is in bit space.
3481 */
3482 static void genIfxJump (iCode *ic, char *jval)
3483 {
3484
3485     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3486     /* if true label then we jump if condition
3487     supplied is true */
3488     if ( IC_TRUE(ic) ) {
3489
3490         if(strcmp(jval,"a") == 0)
3491           emitSKPZ;
3492         else if (strcmp(jval,"c") == 0)
3493           emitSKPC;
3494         else {
3495           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3496           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3497         }
3498
3499         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3500         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3501
3502     }
3503     else {
3504         /* false label is present */
3505         if(strcmp(jval,"a") == 0)
3506           emitSKPNZ;
3507         else if (strcmp(jval,"c") == 0)
3508           emitSKPNC;
3509         else {
3510           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3511           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3512         }
3513
3514         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3515         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3516
3517     }
3518
3519
3520     /* mark the icode as generated */
3521     ic->generated = 1;
3522 }
3523
3524 /*-----------------------------------------------------------------*/
3525 /* genSkip                                                         */
3526 /*-----------------------------------------------------------------*/
3527 static void genSkip(iCode *ifx,int status_bit)
3528 {
3529   if(!ifx)
3530     return;
3531
3532   if ( IC_TRUE(ifx) ) {
3533     switch(status_bit) {
3534     case 'z':
3535       emitSKPNZ;
3536       break;
3537
3538     case 'c':
3539       emitSKPNC;
3540       break;
3541
3542     case 'd':
3543       emitSKPDC;
3544       break;
3545
3546     }
3547
3548     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3549     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3550
3551   } else {
3552
3553     switch(status_bit) {
3554
3555     case 'z':
3556       emitSKPZ;
3557       break;
3558
3559     case 'c':
3560       emitSKPC;
3561       break;
3562
3563     case 'd':
3564       emitSKPDC;
3565       break;
3566     }
3567     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3568     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3569
3570   }
3571
3572 }
3573
3574 /*-----------------------------------------------------------------*/
3575 /* genSkipc                                                        */
3576 /*-----------------------------------------------------------------*/
3577 static void genSkipc(resolvedIfx *rifx)
3578 {
3579   if(!rifx)
3580     return;
3581
3582   if(rifx->condition)
3583     emitSKPC;
3584   else
3585     emitSKPNC;
3586
3587   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3588   rifx->generated = 1;
3589 }
3590
3591 /*-----------------------------------------------------------------*/
3592 /* genSkipz2                                                       */
3593 /*-----------------------------------------------------------------*/
3594 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3595 {
3596   if(!rifx)
3597     return;
3598
3599   if( (rifx->condition ^ invert_condition) & 1)
3600     emitSKPZ;
3601   else
3602     emitSKPNZ;
3603
3604   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3605   rifx->generated = 1;
3606 }
3607
3608 /*-----------------------------------------------------------------*/
3609 /* genSkipz                                                        */
3610 /*-----------------------------------------------------------------*/
3611 static void genSkipz(iCode *ifx, int condition)
3612 {
3613   if(!ifx)
3614     return;
3615
3616   if(condition)
3617     emitSKPNZ;
3618   else
3619     emitSKPZ;
3620
3621   if ( IC_TRUE(ifx) )
3622     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3623   else
3624     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3625
3626   if ( IC_TRUE(ifx) )
3627     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3628   else
3629     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3630
3631 }
3632 /*-----------------------------------------------------------------*/
3633 /* genSkipCond                                                     */
3634 /*-----------------------------------------------------------------*/
3635 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3636 {
3637   if(!rifx)
3638     return;
3639
3640   if(rifx->condition)
3641     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3642   else
3643     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3644
3645
3646   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3647   rifx->generated = 1;
3648 }
3649
3650 #if 0
3651 /*-----------------------------------------------------------------*/
3652 /* genChkZeroes :- greater or less than comparison                 */
3653 /*     For each byte in a literal that is zero, inclusive or the   */
3654 /*     the corresponding byte in the operand with W                */
3655 /*     returns true if any of the bytes are zero                   */
3656 /*-----------------------------------------------------------------*/
3657 static int genChkZeroes(operand *op, int lit,  int size)
3658 {
3659
3660   int i;
3661   int flag =1;
3662
3663   while(size--) {
3664     i = (lit >> (size*8)) & 0xff;
3665
3666     if(i==0) {
3667       if(flag) 
3668         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3669       else
3670         emitpcode(POC_IORFW, popGet(AOP(op),size));
3671       flag = 0;
3672     }
3673   }
3674
3675   return (flag==0);
3676 }
3677 #endif
3678
3679 /*-----------------------------------------------------------------*/
3680 /* genCmp :- greater or less than comparison                       */
3681 /*-----------------------------------------------------------------*/
3682 static void genCmp (operand *left,operand *right,
3683                     operand *result, iCode *ifx, int sign)
3684 {
3685   int size; //, offset = 0 ;
3686   unsigned long lit = 0L,i = 0;
3687   resolvedIfx rFalseIfx;
3688   //  resolvedIfx rTrueIfx;
3689   symbol *truelbl;
3690   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3691   if(ifx) {
3692     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3693     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3694   }
3695
3696
3697   resolveIfx(&rFalseIfx,ifx);
3698   truelbl  = newiTempLabel(NULL);
3699   size = max(AOP_SIZE(left),AOP_SIZE(right));
3700
3701 #define _swapp
3702
3703   /* if literal is on the right then swap with left */
3704   if ((AOP_TYPE(right) == AOP_LIT)) {
3705     operand *tmp = right ;
3706     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3707     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3708 #ifdef _swapp
3709     DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3710     lit = (lit - 1) & mask;
3711     DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3712
3713     right = left;
3714     left = tmp;
3715     rFalseIfx.condition ^= 1;
3716 #endif
3717
3718   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3719     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3720   }
3721
3722
3723   //if(IC_TRUE(ifx) == NULL)
3724   /* if left & right are bit variables */
3725   if (AOP_TYPE(left) == AOP_CRY &&
3726       AOP_TYPE(right) == AOP_CRY ) {
3727     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3728     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3729   } else {
3730     /* subtract right from left if at the
3731        end the carry flag is set then we know that
3732        left is greater than right */
3733
3734     //    {
3735
3736     symbol *lbl  = newiTempLabel(NULL);
3737
3738 #ifndef _swapp
3739     if(AOP_TYPE(right) == AOP_LIT) {
3740
3741       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3742
3743       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3744
3745       /* special cases */
3746
3747       if(lit == 0) {
3748
3749         if(sign != 0) 
3750           genSkipCond(&rFalseIfx,left,size-1,7);
3751         else 
3752           /* no need to compare to 0...*/
3753           /* NOTE: this is a de-generate compare that most certainly 
3754            *       creates some dead code. */
3755           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3756
3757         if(ifx) ifx->generated = 1;
3758         return;
3759
3760       }
3761       size--;
3762
3763       if(size == 0) {
3764         //i = (lit >> (size*8)) & 0xff;
3765         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3766         
3767         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3768
3769         i = ((0-lit) & 0xff);
3770         if(sign) {
3771           if( i == 0x81) { 
3772             /* lit is 0x7f, all signed chars are less than
3773              * this except for 0x7f itself */
3774             emitpcode(POC_XORLW, popGetLit(0x7f));
3775             genSkipz2(&rFalseIfx,0);
3776           } else {
3777             emitpcode(POC_ADDLW, popGetLit(0x80));
3778             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3779             genSkipc(&rFalseIfx);
3780           }
3781
3782         } else {
3783           if(lit == 1) {
3784             genSkipz2(&rFalseIfx,1);
3785           } else {
3786             emitpcode(POC_ADDLW, popGetLit(i));
3787             genSkipc(&rFalseIfx);
3788           }
3789         }
3790
3791         if(ifx) ifx->generated = 1;
3792         return;
3793       }
3794
3795       /* chars are out of the way. now do ints and longs */
3796
3797
3798       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3799         
3800       /* special cases */
3801
3802       if(sign) {
3803
3804         if(lit == 0) {
3805           genSkipCond(&rFalseIfx,left,size,7);
3806           if(ifx) ifx->generated = 1;
3807           return;
3808         }
3809
3810         if(lit <0x100) {
3811           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3812
3813           //rFalseIfx.condition ^= 1;
3814           //genSkipCond(&rFalseIfx,left,size,7);
3815           //rFalseIfx.condition ^= 1;
3816
3817           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3818           if(rFalseIfx.condition)
3819             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3820           else
3821             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3822
3823           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3824           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3825           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3826
3827           while(size > 1)
3828             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3829
3830           if(rFalseIfx.condition) {
3831             emitSKPZ;
3832             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3833
3834           } else {
3835             emitSKPNZ;
3836           }
3837
3838           genSkipc(&rFalseIfx);
3839           emitpLabel(truelbl->key);
3840           if(ifx) ifx->generated = 1;
3841           return;
3842
3843         }
3844
3845         if(size == 1) {
3846
3847           if( (lit & 0xff) == 0) {
3848             /* lower byte is zero */
3849             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3850             i = ((lit >> 8) & 0xff) ^0x80;
3851             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3852             emitpcode(POC_ADDLW, popGetLit( 0x80));
3853             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3854             genSkipc(&rFalseIfx);
3855
3856
3857             if(ifx) ifx->generated = 1;
3858             return;
3859
3860           }
3861         } else {
3862           /* Special cases for signed longs */
3863           if( (lit & 0xffffff) == 0) {
3864             /* lower byte is zero */
3865             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3866             i = ((lit >> 8*3) & 0xff) ^0x80;
3867             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3868             emitpcode(POC_ADDLW, popGetLit( 0x80));
3869             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3870             genSkipc(&rFalseIfx);
3871
3872
3873             if(ifx) ifx->generated = 1;
3874             return;
3875
3876           }
3877
3878         }
3879
3880
3881         if(lit & (0x80 << (size*8))) {
3882           /* lit is negative */
3883           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3884
3885           //genSkipCond(&rFalseIfx,left,size,7);
3886
3887           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3888
3889           if(rFalseIfx.condition)
3890             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3891           else
3892             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3893
3894
3895         } else {
3896           /* lit is positive */
3897           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3898           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3899           if(rFalseIfx.condition)
3900             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3901           else
3902             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3903
3904         }
3905
3906         /*
3907           This works, but is only good for ints.
3908           It also requires a "known zero" register.
3909           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3910           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3911           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3912           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3913           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3914           genSkipc(&rFalseIfx);
3915
3916           emitpLabel(truelbl->key);
3917           if(ifx) ifx->generated = 1;
3918           return;
3919         **/
3920           
3921         /* There are no more special cases, so perform a general compare */
3922   
3923         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3924         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3925
3926         while(size--) {
3927
3928           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3929           emitSKPNZ;
3930           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3931         }
3932         //rFalseIfx.condition ^= 1;
3933         genSkipc(&rFalseIfx);
3934
3935         emitpLabel(truelbl->key);
3936
3937         if(ifx) ifx->generated = 1;
3938         return;
3939
3940
3941       }
3942
3943
3944       /* sign is out of the way. So now do an unsigned compare */
3945       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3946
3947
3948       /* General case - compare to an unsigned literal on the right.*/
3949
3950       i = (lit >> (size*8)) & 0xff;
3951       emitpcode(POC_MOVLW, popGetLit(i));
3952       emitpcode(POC_SUBFW, popGet(AOP(left),size));
3953       while(size--) {
3954         i = (lit >> (size*8)) & 0xff;
3955
3956         if(i) {
3957           emitpcode(POC_MOVLW, popGetLit(i));
3958           emitSKPNZ;
3959           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3960         } else {
3961           /* this byte of the lit is zero, 
3962            *if it's not the last then OR in the variable */
3963           if(size)
3964             emitpcode(POC_IORFW, popGet(AOP(left),size));
3965         }
3966       }
3967
3968
3969       emitpLabel(lbl->key);
3970       //if(emitFinalCheck)
3971       genSkipc(&rFalseIfx);
3972       if(sign)
3973         emitpLabel(truelbl->key);
3974
3975       if(ifx) ifx->generated = 1;
3976       return;
3977
3978
3979     }
3980 #endif
3981     if(AOP_TYPE(left) == AOP_LIT) {
3982       //symbol *lbl = newiTempLabel(NULL);
3983
3984       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3985
3986
3987       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3988
3989       /* Special cases */
3990       if((lit == 0) && (sign == 0)){
3991
3992         size--;
3993         emitpcode(POC_MOVFW, popGet(AOP(right),size));
3994         while(size) 
3995           emitpcode(POC_IORFW, popGet(AOP(right),--size));
3996
3997         genSkipz2(&rFalseIfx,0);
3998         if(ifx) ifx->generated = 1;
3999         return;
4000       }
4001
4002       if(size==1) {
4003         /* Special cases */
4004         lit &= 0xff;
4005         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4006           /* degenerate compare can never be true */
4007           if(rFalseIfx.condition == 0)
4008             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4009
4010           if(ifx) ifx->generated = 1;
4011           return;
4012         }
4013
4014         if(sign) {
4015           /* signed comparisons to a literal byte */
4016
4017           int lp1 = (lit+1) & 0xff;
4018
4019           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4020           switch (lp1) {
4021           case 0:
4022             rFalseIfx.condition ^= 1;
4023             genSkipCond(&rFalseIfx,right,0,7);
4024             break;
4025           case 0x7f:
4026             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4027             emitpcode(POC_XORLW, popGetLit(0x7f));
4028             genSkipz2(&rFalseIfx,1);
4029             break;
4030           default:
4031             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4032             emitpcode(POC_ADDLW, popGetLit(0x80));
4033             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4034             rFalseIfx.condition ^= 1;
4035             genSkipc(&rFalseIfx);
4036             break;
4037           }
4038         } else {
4039           /* unsigned comparisons to a literal byte */
4040
4041           switch(lit & 0xff ) {
4042           case 0:
4043             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4044             genSkipz2(&rFalseIfx,0);
4045             break;
4046           case 0x7f:
4047             rFalseIfx.condition ^= 1;
4048             genSkipCond(&rFalseIfx,right,0,7);
4049             break;
4050
4051           default:
4052             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4053             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4054             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4055             rFalseIfx.condition ^= 1;
4056             genSkipc(&rFalseIfx);
4057             break;
4058           }
4059         }
4060
4061         if(ifx) ifx->generated = 1;
4062         return;
4063
4064       } else {
4065
4066         /* Size is greater than 1 */
4067
4068         if(sign) {
4069           int lp1 = lit+1;
4070
4071           size--;
4072
4073           if(lp1 == 0) {
4074             /* this means lit = 0xffffffff, or -1 */
4075
4076
4077             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4078             rFalseIfx.condition ^= 1;
4079             genSkipCond(&rFalseIfx,right,size,7);
4080             if(ifx) ifx->generated = 1;
4081             return;
4082           }
4083
4084           if(lit == 0) {
4085             int s = size;
4086
4087             if(rFalseIfx.condition) {
4088               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4089               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4090             }
4091
4092             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4093             while(size--)
4094               emitpcode(POC_IORFW, popGet(AOP(right),size));
4095
4096
4097             emitSKPZ;
4098             if(rFalseIfx.condition) {
4099               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4100               emitpLabel(truelbl->key);
4101             }else {
4102               rFalseIfx.condition ^= 1;
4103               genSkipCond(&rFalseIfx,right,s,7);
4104             }
4105
4106             if(ifx) ifx->generated = 1;
4107             return;
4108           }
4109
4110           if((size == 1) &&  (0 == (lp1&0xff))) {
4111             /* lower byte of signed word is zero */
4112             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4113             i = ((lp1 >> 8) & 0xff) ^0x80;
4114             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4115             emitpcode(POC_ADDLW, popGetLit( 0x80));
4116             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4117             rFalseIfx.condition ^= 1;
4118             genSkipc(&rFalseIfx);
4119
4120
4121             if(ifx) ifx->generated = 1;
4122             return;
4123           }
4124
4125           if(lit & (0x80 << (size*8))) {
4126             /* Lit is less than zero */
4127             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4128             //rFalseIfx.condition ^= 1;
4129             //genSkipCond(&rFalseIfx,left,size,7);
4130             //rFalseIfx.condition ^= 1;
4131             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4133
4134             if(rFalseIfx.condition)
4135               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4136             else
4137               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4138
4139
4140           } else {
4141             /* Lit is greater than or equal to zero */
4142             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4143             //rFalseIfx.condition ^= 1;
4144             //genSkipCond(&rFalseIfx,right,size,7);
4145             //rFalseIfx.condition ^= 1;
4146
4147             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4148             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4149
4150             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4151             if(rFalseIfx.condition)
4152               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4153             else
4154               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4155
4156           }
4157
4158
4159           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4160           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4161
4162           while(size--) {
4163
4164             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4165             emitSKPNZ;
4166             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4167           }
4168           rFalseIfx.condition ^= 1;
4169           //rFalseIfx.condition = 1;
4170           genSkipc(&rFalseIfx);
4171
4172           emitpLabel(truelbl->key);
4173
4174           if(ifx) ifx->generated = 1;
4175           return;
4176           // end of if (sign)
4177         } else {
4178
4179           /* compare word or long to an unsigned literal on the right.*/
4180
4181
4182           size--;
4183           if(lit < 0xff) {
4184             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4185             switch (lit) {
4186             case 0:
4187               break; /* handled above */
4188 /*
4189             case 0xff:
4190               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4191               while(size--)
4192                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4193               genSkipz2(&rFalseIfx,0);
4194               break;
4195 */
4196             default:
4197               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4198               while(--size)
4199                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4200
4201               emitSKPZ;
4202               if(rFalseIfx.condition)
4203                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4204               else
4205                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4206
4207
4208               emitpcode(POC_MOVLW, popGetLit(lit+1));
4209               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4210
4211               rFalseIfx.condition ^= 1;
4212               genSkipc(&rFalseIfx);
4213             }
4214
4215             emitpLabel(truelbl->key);
4216
4217             if(ifx) ifx->generated = 1;
4218             return;
4219           }
4220
4221
4222           lit++;
4223           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4224           i = (lit >> (size*8)) & 0xff;
4225
4226           emitpcode(POC_MOVLW, popGetLit(i));
4227           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4228
4229           while(size--) {
4230             i = (lit >> (size*8)) & 0xff;
4231
4232             if(i) {
4233               emitpcode(POC_MOVLW, popGetLit(i));
4234               emitSKPNZ;
4235               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4236             } else {
4237               /* this byte of the lit is zero, 
4238                *if it's not the last then OR in the variable */
4239               if(size)
4240                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4241             }
4242           }
4243
4244
4245           emitpLabel(lbl->key);
4246
4247           rFalseIfx.condition ^= 1;
4248           genSkipc(&rFalseIfx);
4249         }
4250
4251         if(sign)
4252           emitpLabel(truelbl->key);
4253         if(ifx) ifx->generated = 1;
4254         return;
4255       }
4256     }
4257     /* Compare two variables */
4258
4259     DEBUGpic14_emitcode(";sign","%d",sign);
4260
4261     size--;
4262     if(sign) {
4263       /* Sigh. thus sucks... */
4264       if(size) {
4265         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4266         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4267         emitpcode(POC_MOVLW, popGetLit(0x80));
4268         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4269         emitpcode(POC_XORFW, popGet(AOP(right),size));
4270         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4271       } else {
4272         /* Signed char comparison */
4273         /* Special thanks to Nikolai Golovchenko for this snippet */
4274         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4275         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4276         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4277         emitpcode(POC_XORFW, popGet(AOP(left),0));
4278         emitpcode(POC_XORFW, popGet(AOP(right),0));
4279         emitpcode(POC_ADDLW, popGetLit(0x80));
4280
4281         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4282         genSkipc(&rFalseIfx);
4283           
4284         if(ifx) ifx->generated = 1;
4285         return;
4286       }
4287
4288     } else {
4289
4290       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4291       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4292     }
4293
4294
4295     /* The rest of the bytes of a multi-byte compare */
4296     while (size) {
4297
4298       emitSKPZ;
4299       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4300       size--;
4301
4302       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4303       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4304
4305
4306     }
4307
4308     emitpLabel(lbl->key);
4309
4310     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4311     genSkipc(&rFalseIfx);
4312     if(ifx) ifx->generated = 1;
4313     return;
4314
4315   }
4316
4317   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4318     pic14_outBitC(result);
4319   } else {
4320     /* if the result is used in the next
4321        ifx conditional branch then generate
4322        code a little differently */
4323     if (ifx )
4324       genIfxJump (ifx,"c");
4325     else
4326       pic14_outBitC(result);
4327     /* leave the result in acc */
4328   }
4329
4330 }
4331
4332 /*-----------------------------------------------------------------*/
4333 /* genCmpGt :- greater than comparison                             */
4334 /*-----------------------------------------------------------------*/
4335 static void genCmpGt (iCode *ic, iCode *ifx)
4336 {
4337     operand *left, *right, *result;
4338     sym_link *letype , *retype;
4339     int sign ;
4340
4341     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4342     left = IC_LEFT(ic);
4343     right= IC_RIGHT(ic);
4344     result = IC_RESULT(ic);
4345
4346     letype = getSpec(operandType(left));
4347     retype =getSpec(operandType(right));
4348     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4349     /* assign the amsops */
4350     aopOp (left,ic,FALSE);
4351     aopOp (right,ic,FALSE);
4352     aopOp (result,ic,TRUE);
4353
4354     genCmp(right, left, result, ifx, sign);
4355
4356     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4357     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4358     freeAsmop(result,NULL,ic,TRUE); 
4359 }
4360
4361 /*-----------------------------------------------------------------*/
4362 /* genCmpLt - less than comparisons                                */
4363 /*-----------------------------------------------------------------*/
4364 static void genCmpLt (iCode *ic, iCode *ifx)
4365 {
4366     operand *left, *right, *result;
4367     sym_link *letype , *retype;
4368     int sign ;
4369
4370     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4371     left = IC_LEFT(ic);
4372     right= IC_RIGHT(ic);
4373     result = IC_RESULT(ic);
4374
4375     letype = getSpec(operandType(left));
4376     retype =getSpec(operandType(right));
4377     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4378
4379     /* assign the amsops */
4380     aopOp (left,ic,FALSE);
4381     aopOp (right,ic,FALSE);
4382     aopOp (result,ic,TRUE);
4383
4384     genCmp(left, right, result, ifx, sign);
4385
4386     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4387     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4388     freeAsmop(result,NULL,ic,TRUE); 
4389 }
4390
4391 /*-----------------------------------------------------------------*/
4392 /* genc16bit2lit - compare a 16 bit value to a literal             */
4393 /*-----------------------------------------------------------------*/
4394 static void genc16bit2lit(operand *op, int lit, int offset)
4395 {
4396   int i;
4397
4398   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4399   if( (lit&0xff) == 0) 
4400     i=1;
4401   else
4402     i=0;
4403
4404   switch( BYTEofLONG(lit,i)) { 
4405   case 0:
4406     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4407     break;
4408   case 1:
4409     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4410     break;
4411   case 0xff:
4412     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4413     break;
4414   default:
4415     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4416     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4417   }
4418
4419   i ^= 1;
4420
4421   switch( BYTEofLONG(lit,i)) { 
4422   case 0:
4423     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4424     break;
4425   case 1:
4426     emitSKPNZ;
4427     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4428     break;
4429   case 0xff:
4430     emitSKPNZ;
4431     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4432     break;
4433   default:
4434     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4435     emitSKPNZ;
4436     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4437
4438   }
4439
4440 }
4441
4442 /*-----------------------------------------------------------------*/
4443 /* gencjneshort - compare and jump if not equal                    */
4444 /*-----------------------------------------------------------------*/
4445 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4446 {
4447   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4448   int offset = 0;
4449   resolvedIfx rIfx;
4450   symbol *lbl;
4451
4452   unsigned long lit = 0L;
4453   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4454   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4455
4456   resolveIfx(&rIfx,ifx);
4457   lbl =  newiTempLabel(NULL);
4458
4459
4460   /* if the left side is a literal or 
4461      if the right is in a pointer register and left 
4462      is not */
4463   if ((AOP_TYPE(left) == AOP_LIT) || 
4464       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4465     operand *t = right;
4466     right = left;
4467     left = t;
4468   }
4469   if(AOP_TYPE(right) == AOP_LIT)
4470     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4471
4472   /* if the right side is a literal then anything goes */
4473   if (AOP_TYPE(right) == AOP_LIT &&
4474       AOP_TYPE(left) != AOP_DIR ) {
4475     switch(size) {
4476     case 2:
4477       genc16bit2lit(left, lit, 0);
4478       emitSKPNZ;
4479       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4480       break;
4481     default:
4482       while (size--) {
4483         if(lit & 0xff) {
4484           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4485           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4486         } else {
4487           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4488         }
4489
4490         emitSKPNZ;
4491         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4492         offset++;
4493         lit >>= 8;
4494       }
4495       break;
4496     }
4497   }
4498
4499   /* if the right side is in a register or in direct space or
4500      if the left is a pointer register & right is not */    
4501   else if (AOP_TYPE(right) == AOP_REG ||
4502            AOP_TYPE(right) == AOP_DIR || 
4503            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4504            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4505     switch(size) {
4506     case 2:
4507       genc16bit2lit(left, lit, 0);
4508       emitSKPNZ;
4509       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4510       break;
4511     default:
4512       while (size--) {
4513         int emit_skip=1;
4514         if((AOP_TYPE(left) == AOP_DIR) && 
4515            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4516
4517           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4518           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4519
4520         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4521             
4522           switch (lit & 0xff) {
4523           case 0:
4524             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4525             break;
4526           case 1:
4527             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4528             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4529             emit_skip=0;
4530             break;
4531           case 0xff:
4532             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4533             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4534             emit_skip=0;
4535             break;
4536           default:
4537             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4538             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4539           }
4540           lit >>= 8;
4541
4542         } else {
4543           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4544         }
4545         if(emit_skip) {
4546           if(AOP_TYPE(result) == AOP_CRY) {
4547             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4548             if(rIfx.condition)
4549               emitSKPNZ;
4550             else
4551               emitSKPZ;
4552             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4553           } else {
4554             /* fix me. probably need to check result size too */
4555             emitpcode(POC_CLRF,popGet(AOP(result),0));
4556             if(rIfx.condition)
4557               emitSKPNZ;
4558             else
4559               emitSKPZ;
4560             emitpcode(POC_INCF,popGet(AOP(result),0));
4561           }
4562           if(ifx)
4563             ifx->generated=1;
4564         }
4565         emit_skip++;
4566         offset++;
4567       }
4568       break;
4569     }
4570   } else if(AOP_TYPE(right) == AOP_REG &&
4571             AOP_TYPE(left) != AOP_DIR){
4572
4573     while(size--) {
4574       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4575       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4576       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4577       if(rIfx.condition)
4578         emitSKPNZ;
4579       else
4580         emitSKPZ;
4581       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4582       offset++;
4583     }
4584       
4585   }else{
4586     /* right is a pointer reg need both a & b */
4587     while(size--) {
4588       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4589       if(strcmp(l,"b"))
4590         pic14_emitcode("mov","b,%s",l);
4591       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4592       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4593       offset++;
4594     }
4595   }
4596   emitpLabel(lbl->key);
4597
4598   if(ifx)
4599     ifx->generated = 1;
4600 }
4601
4602 #if 0
4603 /*-----------------------------------------------------------------*/
4604 /* gencjne - compare and jump if not equal                         */
4605 /*-----------------------------------------------------------------*/
4606 static void gencjne(operand *left, operand *right, iCode *ifx)
4607 {
4608     symbol *tlbl  = newiTempLabel(NULL);
4609
4610     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4611     gencjneshort(left, right, lbl);
4612
4613     pic14_emitcode("mov","a,%s",one);
4614     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4615     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4616     pic14_emitcode("clr","a");
4617     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4618
4619     emitpLabel(lbl->key);
4620     emitpLabel(tlbl->key);
4621
4622 }
4623 #endif
4624
4625 /*-----------------------------------------------------------------*/
4626 /* genCmpEq - generates code for equal to                          */
4627 /*-----------------------------------------------------------------*/
4628 static void genCmpEq (iCode *ic, iCode *ifx)
4629 {
4630     operand *left, *right, *result;
4631     unsigned long lit = 0L;
4632     int size,offset=0;
4633
4634     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4635
4636     if(ifx)
4637       DEBUGpic14_emitcode ("; ifx is non-null","");
4638     else
4639       DEBUGpic14_emitcode ("; ifx is null","");
4640
4641     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4642     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4643     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4644
4645     size = max(AOP_SIZE(left),AOP_SIZE(right));
4646
4647     DEBUGpic14_AopType(__LINE__,left,right,result);
4648
4649     /* if literal, literal on the right or 
4650     if the right is in a pointer register and left 
4651     is not */
4652     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4653         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4654       operand *tmp = right ;
4655       right = left;
4656       left = tmp;
4657     }
4658
4659
4660     if(ifx && !AOP_SIZE(result)){
4661         symbol *tlbl;
4662         /* if they are both bit variables */
4663         if (AOP_TYPE(left) == AOP_CRY &&
4664             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4665             if(AOP_TYPE(right) == AOP_LIT){
4666                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4667                 if(lit == 0L){
4668                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4669                     pic14_emitcode("cpl","c");
4670                 } else if(lit == 1L) {
4671                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4672                 } else {
4673                     pic14_emitcode("clr","c");
4674                 }
4675                 /* AOP_TYPE(right) == AOP_CRY */
4676             } else {
4677                 symbol *lbl = newiTempLabel(NULL);
4678                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4679                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4680                 pic14_emitcode("cpl","c");
4681                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4682             }
4683             /* if true label then we jump if condition
4684             supplied is true */
4685             tlbl = newiTempLabel(NULL);
4686             if ( IC_TRUE(ifx) ) {
4687                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4688                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4689             } else {
4690                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4691                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4692             }
4693             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4694
4695             {
4696               /* left and right are both bit variables, result is carry */
4697               resolvedIfx rIfx;
4698               
4699               resolveIfx(&rIfx,ifx);
4700
4701               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4702               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4703               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4704               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4705               genSkipz2(&rIfx,0);
4706             }
4707         } else {
4708
4709           /* They're not both bit variables. Is the right a literal? */
4710           if(AOP_TYPE(right) == AOP_LIT) {
4711             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4712             
4713             switch(size) {
4714
4715             case 1:
4716               switch(lit & 0xff) {
4717               case 1:
4718                 if ( IC_TRUE(ifx) ) {
4719                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4720                   emitSKPNZ;
4721                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4722                 } else {
4723                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4724                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4725                 }
4726                 break;
4727               case 0xff:
4728                 if ( IC_TRUE(ifx) ) {
4729                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4730                   emitSKPNZ;
4731                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4732                 } else {
4733                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4734                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4735                 }
4736                 break;
4737               default:
4738                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4739                 if(lit)
4740                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4741                 genSkip(ifx,'z');
4742               }
4743
4744
4745               /* end of size == 1 */
4746               break;
4747               
4748             case 2:
4749               genc16bit2lit(left,lit,offset);
4750               genSkip(ifx,'z');
4751               break;
4752               /* end of size == 2 */
4753
4754             default:
4755               /* size is 4 */
4756               if(lit==0) {
4757                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4758                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4759                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4760                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4761
4762               } else {
4763
4764                 /* search for patterns that can be optimized */
4765
4766                 genc16bit2lit(left,lit,0);
4767                 lit >>= 16;
4768                 if(lit) {
4769                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4770                   //genSkip(ifx,'z');
4771                   genc16bit2lit(left,lit,2);
4772                 } else {
4773                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4774                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4775
4776                 }
4777                 
4778               }
4779
4780               genSkip(ifx,'z');
4781             }
4782           
4783             ifx->generated = 1;
4784             goto release ;
4785             
4786
4787           } else if(AOP_TYPE(right) == AOP_CRY ) {
4788             /* we know the left is not a bit, but that the right is */
4789             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4790             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4791                       popGet(AOP(right),offset));
4792             emitpcode(POC_XORLW,popGetLit(1));
4793
4794             /* if the two are equal, then W will be 0 and the Z bit is set
4795              * we could test Z now, or go ahead and check the high order bytes if
4796              * the variable we're comparing is larger than a byte. */
4797
4798             while(--size)
4799               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4800
4801             if ( IC_TRUE(ifx) ) {
4802               emitSKPNZ;
4803               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4804               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4805             } else {
4806               emitSKPZ;
4807               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4808               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4809             }
4810
4811           } else {
4812             /* They're both variables that are larger than bits */
4813             int s = size;
4814
4815             tlbl = newiTempLabel(NULL);
4816
4817             while(size--) {
4818               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4819               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4820
4821               if ( IC_TRUE(ifx) ) {
4822                 if(size) {
4823                   emitSKPZ;
4824                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4825                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4826                 } else {
4827                   emitSKPNZ;
4828                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4829                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4830                 }
4831               } else {
4832                 emitSKPZ;
4833                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4834                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4835               }
4836               offset++;
4837             }
4838             if(s>1 && IC_TRUE(ifx)) {
4839               emitpLabel(tlbl->key);
4840               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4841             }
4842           }
4843         }
4844         /* mark the icode as generated */
4845         ifx->generated = 1;
4846         goto release ;
4847     }
4848
4849     /* if they are both bit variables */
4850     if (AOP_TYPE(left) == AOP_CRY &&
4851         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4852         if(AOP_TYPE(right) == AOP_LIT){
4853             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4854             if(lit == 0L){
4855                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4856                 pic14_emitcode("cpl","c");
4857             } else if(lit == 1L) {
4858                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4859             } else {
4860                 pic14_emitcode("clr","c");
4861             }
4862             /* AOP_TYPE(right) == AOP_CRY */
4863         } else {
4864             symbol *lbl = newiTempLabel(NULL);
4865             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4866             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4867             pic14_emitcode("cpl","c");
4868             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4869         }
4870         /* c = 1 if egal */
4871         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4872             pic14_outBitC(result);
4873             goto release ;
4874         }
4875         if (ifx) {
4876             genIfxJump (ifx,"c");
4877             goto release ;
4878         }
4879         /* if the result is used in an arithmetic operation
4880         then put the result in place */
4881         pic14_outBitC(result);
4882     } else {
4883       
4884       gencjne(left,right,result,ifx);
4885 /*
4886       if(ifx) 
4887         gencjne(left,right,newiTempLabel(NULL));
4888       else {
4889         if(IC_TRUE(ifx)->key)
4890           gencjne(left,right,IC_TRUE(ifx)->key);
4891         else
4892           gencjne(left,right,IC_FALSE(ifx)->key);
4893         ifx->generated = 1;
4894         goto release ;
4895       }
4896       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4897         aopPut(AOP(result),"a",0);
4898         goto release ;
4899       }
4900
4901       if (ifx) {
4902         genIfxJump (ifx,"a");
4903         goto release ;
4904       }
4905 */
4906       /* if the result is used in an arithmetic operation
4907          then put the result in place */
4908 /*
4909       if (AOP_TYPE(result) != AOP_CRY) 
4910         pic14_outAcc(result);
4911 */
4912       /* leave the result in acc */
4913     }
4914
4915 release:
4916     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4917     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4918     freeAsmop(result,NULL,ic,TRUE);
4919 }
4920
4921 /*-----------------------------------------------------------------*/
4922 /* ifxForOp - returns the icode containing the ifx for operand     */
4923 /*-----------------------------------------------------------------*/
4924 static iCode *ifxForOp ( operand *op, iCode *ic )
4925 {
4926     /* if true symbol then needs to be assigned */
4927     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4928     if (IS_TRUE_SYMOP(op))
4929         return NULL ;
4930
4931     /* if this has register type condition and
4932     the next instruction is ifx with the same operand
4933     and live to of the operand is upto the ifx only then */
4934     if (ic->next &&
4935         ic->next->op == IFX &&
4936         IC_COND(ic->next)->key == op->key &&
4937         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4938         return ic->next;
4939
4940     if (ic->next &&
4941         ic->next->op == IFX &&
4942         IC_COND(ic->next)->key == op->key) {
4943       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4944       return ic->next;
4945     }
4946
4947     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4948     if (ic->next &&
4949         ic->next->op == IFX)
4950       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4951
4952     if (ic->next &&
4953         ic->next->op == IFX &&
4954         IC_COND(ic->next)->key == op->key) {
4955       DEBUGpic14_emitcode ("; "," key is okay");
4956       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4957                            OP_SYMBOL(op)->liveTo,
4958                            ic->next->seq);
4959     }
4960
4961
4962     return NULL;
4963 }
4964 /*-----------------------------------------------------------------*/
4965 /* genAndOp - for && operation                                     */
4966 /*-----------------------------------------------------------------*/
4967 static void genAndOp (iCode *ic)
4968 {
4969     operand *left,*right, *result;
4970     symbol *tlbl;
4971
4972     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4973     /* note here that && operations that are in an
4974     if statement are taken away by backPatchLabels
4975     only those used in arthmetic operations remain */
4976     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4977     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4978     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4979
4980     /* if both are bit variables */
4981     if (AOP_TYPE(left) == AOP_CRY &&
4982         AOP_TYPE(right) == AOP_CRY ) {
4983         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4984         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4985         pic14_outBitC(result);
4986     } else {
4987         tlbl = newiTempLabel(NULL);
4988         pic14_toBoolean(left);    
4989         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4990         pic14_toBoolean(right);
4991         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4992         pic14_outBitAcc(result);
4993     }
4994
4995     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4996     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4997     freeAsmop(result,NULL,ic,TRUE);
4998 }
4999
5000
5001 /*-----------------------------------------------------------------*/
5002 /* genOrOp - for || operation                                      */
5003 /*-----------------------------------------------------------------*/
5004 /*
5005   tsd pic port -
5006   modified this code, but it doesn't appear to ever get called
5007 */
5008
5009 static void genOrOp (iCode *ic)
5010 {
5011     operand *left,*right, *result;
5012     symbol *tlbl;
5013
5014     /* note here that || operations that are in an
5015     if statement are taken away by backPatchLabels
5016     only those used in arthmetic operations remain */
5017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5018     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5019     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5020     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5021
5022     DEBUGpic14_AopType(__LINE__,left,right,result);
5023
5024     /* if both are bit variables */
5025     if (AOP_TYPE(left) == AOP_CRY &&
5026         AOP_TYPE(right) == AOP_CRY ) {
5027       pic14_emitcode("clrc","");
5028       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5029                AOP(left)->aopu.aop_dir,
5030                AOP(left)->aopu.aop_dir);
5031       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5032                AOP(right)->aopu.aop_dir,
5033                AOP(right)->aopu.aop_dir);
5034       pic14_emitcode("setc","");
5035
5036     } else {
5037         tlbl = newiTempLabel(NULL);
5038         pic14_toBoolean(left);
5039         emitSKPZ;
5040         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5041         pic14_toBoolean(right);
5042         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5043
5044         pic14_outBitAcc(result);
5045     }
5046
5047     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5048     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5049     freeAsmop(result,NULL,ic,TRUE);            
5050 }
5051
5052 /*-----------------------------------------------------------------*/
5053 /* isLiteralBit - test if lit == 2^n                               */
5054 /*-----------------------------------------------------------------*/
5055 static int isLiteralBit(unsigned long lit)
5056 {
5057     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5058     0x100L,0x200L,0x400L,0x800L,
5059     0x1000L,0x2000L,0x4000L,0x8000L,
5060     0x10000L,0x20000L,0x40000L,0x80000L,
5061     0x100000L,0x200000L,0x400000L,0x800000L,
5062     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5063     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5064     int idx;
5065     
5066     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5067     for(idx = 0; idx < 32; idx++)
5068         if(lit == pw[idx])
5069             return idx+1;
5070     return 0;
5071 }
5072
5073 /*-----------------------------------------------------------------*/
5074 /* continueIfTrue -                                                */
5075 /*-----------------------------------------------------------------*/
5076 static void continueIfTrue (iCode *ic)
5077 {
5078     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5079     if(IC_TRUE(ic))
5080         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5081     ic->generated = 1;
5082 }
5083
5084 /*-----------------------------------------------------------------*/
5085 /* jmpIfTrue -                                                     */
5086 /*-----------------------------------------------------------------*/
5087 static void jumpIfTrue (iCode *ic)
5088 {
5089     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5090     if(!IC_TRUE(ic))
5091         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5092     ic->generated = 1;
5093 }
5094
5095 /*-----------------------------------------------------------------*/
5096 /* jmpTrueOrFalse -                                                */
5097 /*-----------------------------------------------------------------*/
5098 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5099 {
5100     // ugly but optimized by peephole
5101     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5102     if(IC_TRUE(ic)){
5103         symbol *nlbl = newiTempLabel(NULL);
5104         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5105         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5106         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5107         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5108     }
5109     else{
5110         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5111         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5112     }
5113     ic->generated = 1;
5114 }
5115
5116 /*-----------------------------------------------------------------*/
5117 /* genAnd  - code for and                                          */
5118 /*-----------------------------------------------------------------*/
5119 static void genAnd (iCode *ic, iCode *ifx)
5120 {
5121   operand *left, *right, *result;
5122   int size, offset=0;  
5123   unsigned long lit = 0L;
5124   int bytelit = 0;
5125   resolvedIfx rIfx;
5126
5127
5128   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5129   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5130   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5131   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5132
5133   resolveIfx(&rIfx,ifx);
5134
5135   /* if left is a literal & right is not then exchange them */
5136   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5137       AOP_NEEDSACC(left)) {
5138     operand *tmp = right ;
5139     right = left;
5140     left = tmp;
5141   }
5142
5143   /* if result = right then exchange them */
5144   if(pic14_sameRegs(AOP(result),AOP(right))){
5145     operand *tmp = right ;
5146     right = left;
5147     left = tmp;
5148   }
5149
5150   /* if right is bit then exchange them */
5151   if (AOP_TYPE(right) == AOP_CRY &&
5152       AOP_TYPE(left) != AOP_CRY){
5153     operand *tmp = right ;
5154     right = left;
5155     left = tmp;
5156   }
5157   if(AOP_TYPE(right) == AOP_LIT)
5158     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5159
5160   size = AOP_SIZE(result);
5161
5162   DEBUGpic14_AopType(__LINE__,left,right,result);
5163
5164   // if(bit & yy)
5165   // result = bit & yy;
5166   if (AOP_TYPE(left) == AOP_CRY){
5167     // c = bit & literal;
5168     if(AOP_TYPE(right) == AOP_LIT){
5169       if(lit & 1) {
5170         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5171           // no change
5172           goto release;
5173         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5174       } else {
5175         // bit(result) = 0;
5176         if(size && (AOP_TYPE(result) == AOP_CRY)){
5177           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5178           goto release;
5179         }
5180         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5181           jumpIfTrue(ifx);
5182           goto release;
5183         }
5184         pic14_emitcode("clr","c");
5185       }
5186     } else {
5187       if (AOP_TYPE(right) == AOP_CRY){
5188         // c = bit & bit;
5189         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5190         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5191       } else {
5192         // c = bit & val;
5193         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5194         // c = lsb
5195         pic14_emitcode("rrc","a");
5196         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5197       }
5198     }
5199     // bit = c
5200     // val = c
5201     if(size)
5202       pic14_outBitC(result);
5203     // if(bit & ...)
5204     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5205       genIfxJump(ifx, "c");           
5206     goto release ;
5207   }
5208
5209   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5210   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5211   if((AOP_TYPE(right) == AOP_LIT) &&
5212      (AOP_TYPE(result) == AOP_CRY) &&
5213      (AOP_TYPE(left) != AOP_CRY)){
5214     int posbit = isLiteralBit(lit);
5215     /* left &  2^n */
5216     if(posbit){
5217       posbit--;
5218       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5219       // bit = left & 2^n
5220       if(size)
5221         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5222       // if(left &  2^n)
5223       else{
5224         if(ifx){
5225 /*
5226           if(IC_TRUE(ifx)) {
5227             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5228             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5229           } else {
5230             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5231             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5232           }
5233 */
5234           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5235                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5236           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5237           
5238           ifx->generated = 1;
5239         }
5240         goto release;
5241       }
5242     } else {
5243       symbol *tlbl = newiTempLabel(NULL);
5244       int sizel = AOP_SIZE(left);
5245       if(size)
5246         pic14_emitcode("setb","c");
5247       while(sizel--){
5248         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5249           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5250           // byte ==  2^n ?
5251           if((posbit = isLiteralBit(bytelit)) != 0)
5252             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5253           else{
5254             if(bytelit != 0x0FFL)
5255               pic14_emitcode("anl","a,%s",
5256                              aopGet(AOP(right),offset,FALSE,TRUE));
5257             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5258           }
5259         }
5260         offset++;
5261       }
5262       // bit = left & literal
5263       if(size){
5264         pic14_emitcode("clr","c");
5265         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5266       }
5267       // if(left & literal)
5268       else{
5269         if(ifx)
5270           jmpTrueOrFalse(ifx, tlbl);
5271         goto release ;
5272       }
5273     }
5274     pic14_outBitC(result);
5275     goto release ;
5276   }
5277
5278   /* if left is same as result */
5279   if(pic14_sameRegs(AOP(result),AOP(left))){
5280     int know_W = -1;
5281     for(;size--; offset++,lit>>=8) {
5282       if(AOP_TYPE(right) == AOP_LIT){
5283         switch(lit & 0xff) {
5284         case 0x00:
5285           /*  and'ing with 0 has clears the result */
5286           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5287           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5288           break;
5289         case 0xff:
5290           /* and'ing with 0xff is a nop when the result and left are the same */
5291           break;
5292
5293         default:
5294           {
5295             int p = my_powof2( (~lit) & 0xff );
5296             if(p>=0) {
5297               /* only one bit is set in the literal, so use a bcf instruction */
5298               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5299               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5300
5301             } else {
5302               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5303               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5304               if(know_W != (lit&0xff))
5305                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5306               know_W = lit &0xff;
5307               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5308             }
5309           }    
5310         }
5311       } else {
5312         if (AOP_TYPE(left) == AOP_ACC) {
5313           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5314         } else {                    
5315           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5316           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5317
5318         }
5319       }
5320     }
5321
5322   } else {
5323     // left & result in different registers
5324     if(AOP_TYPE(result) == AOP_CRY){
5325       // result = bit
5326       // if(size), result in bit
5327       // if(!size && ifx), conditional oper: if(left & right)
5328       symbol *tlbl = newiTempLabel(NULL);
5329       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5330       if(size)
5331         pic14_emitcode("setb","c");
5332       while(sizer--){
5333         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5334         pic14_emitcode("anl","a,%s",
5335                        aopGet(AOP(left),offset,FALSE,FALSE));
5336         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5337         offset++;
5338       }
5339       if(size){
5340         CLRC;
5341         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5342         pic14_outBitC(result);
5343       } else if(ifx)
5344         jmpTrueOrFalse(ifx, tlbl);
5345     } else {
5346       for(;(size--);offset++) {
5347         // normal case
5348         // result = left & right
5349         if(AOP_TYPE(right) == AOP_LIT){
5350           int t = (lit >> (offset*8)) & 0x0FFL;
5351           switch(t) { 
5352           case 0x00:
5353             pic14_emitcode("clrf","%s",
5354                            aopGet(AOP(result),offset,FALSE,FALSE));
5355             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5356             break;
5357           case 0xff:
5358             pic14_emitcode("movf","%s,w",
5359                            aopGet(AOP(left),offset,FALSE,FALSE));
5360             pic14_emitcode("movwf","%s",
5361                            aopGet(AOP(result),offset,FALSE,FALSE));
5362             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5363             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5364             break;
5365           default:
5366             pic14_emitcode("movlw","0x%x",t);
5367             pic14_emitcode("andwf","%s,w",
5368                            aopGet(AOP(left),offset,FALSE,FALSE));
5369             pic14_emitcode("movwf","%s",
5370                            aopGet(AOP(result),offset,FALSE,FALSE));
5371               
5372             emitpcode(POC_MOVLW, popGetLit(t));
5373             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5374             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5375           }
5376           continue;
5377         }
5378
5379         if (AOP_TYPE(left) == AOP_ACC) {
5380           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5381           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5382         } else {
5383           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5384           pic14_emitcode("andwf","%s,w",
5385                          aopGet(AOP(left),offset,FALSE,FALSE));
5386           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5387           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5388         }
5389         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5390         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5391       }
5392     }
5393   }
5394
5395   release :
5396     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5397   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5398   freeAsmop(result,NULL,ic,TRUE);     
5399 }
5400
5401 /*-----------------------------------------------------------------*/
5402 /* genOr  - code for or                                            */
5403 /*-----------------------------------------------------------------*/
5404 static void genOr (iCode *ic, iCode *ifx)
5405 {
5406     operand *left, *right, *result;
5407     int size, offset=0;
5408     unsigned long lit = 0L;
5409
5410     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5411
5412     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5413     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5414     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5415
5416     DEBUGpic14_AopType(__LINE__,left,right,result);
5417
5418     /* if left is a literal & right is not then exchange them */
5419     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5420         AOP_NEEDSACC(left)) {
5421         operand *tmp = right ;
5422         right = left;
5423         left = tmp;
5424     }
5425
5426     /* if result = right then exchange them */
5427     if(pic14_sameRegs(AOP(result),AOP(right))){
5428         operand *tmp = right ;
5429         right = left;
5430         left = tmp;
5431     }
5432
5433     /* if right is bit then exchange them */
5434     if (AOP_TYPE(right) == AOP_CRY &&
5435         AOP_TYPE(left) != AOP_CRY){
5436         operand *tmp = right ;
5437         right = left;
5438         left = tmp;
5439     }
5440
5441     DEBUGpic14_AopType(__LINE__,left,right,result);
5442
5443     if(AOP_TYPE(right) == AOP_LIT)
5444         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5445
5446     size = AOP_SIZE(result);
5447
5448     // if(bit | yy)
5449     // xx = bit | yy;
5450     if (AOP_TYPE(left) == AOP_CRY){
5451         if(AOP_TYPE(right) == AOP_LIT){
5452             // c = bit & literal;
5453             if(lit){
5454                 // lit != 0 => result = 1
5455                 if(AOP_TYPE(result) == AOP_CRY){
5456                   if(size)
5457                     emitpcode(POC_BSF, popGet(AOP(result),0));
5458                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5459                   //     AOP(result)->aopu.aop_dir,
5460                   //     AOP(result)->aopu.aop_dir);
5461                     else if(ifx)
5462                         continueIfTrue(ifx);
5463                     goto release;
5464                 }
5465             } else {
5466                 // lit == 0 => result = left
5467                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5468                     goto release;
5469                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5470             }
5471         } else {
5472             if (AOP_TYPE(right) == AOP_CRY){
5473               if(pic14_sameRegs(AOP(result),AOP(left))){
5474                 // c = bit | bit;
5475                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5476                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5477                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5478
5479                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5480                          AOP(result)->aopu.aop_dir,
5481                          AOP(result)->aopu.aop_dir);
5482                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5483                          AOP(right)->aopu.aop_dir,
5484                          AOP(right)->aopu.aop_dir);
5485                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5486                          AOP(result)->aopu.aop_dir,
5487                          AOP(result)->aopu.aop_dir);
5488               } else {
5489                 if( AOP_TYPE(result) == AOP_ACC) {
5490                   emitpcode(POC_MOVLW, popGetLit(0));
5491                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5492                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5493                   emitpcode(POC_MOVLW, popGetLit(1));
5494
5495                 } else {
5496
5497                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5498                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5499                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5500                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5501
5502                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5503                                  AOP(result)->aopu.aop_dir,
5504                                  AOP(result)->aopu.aop_dir);
5505                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5506                                  AOP(right)->aopu.aop_dir,
5507                                  AOP(right)->aopu.aop_dir);
5508                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5509                                  AOP(left)->aopu.aop_dir,
5510                                  AOP(left)->aopu.aop_dir);
5511                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5512                                  AOP(result)->aopu.aop_dir,
5513                                  AOP(result)->aopu.aop_dir);
5514                 }
5515               }
5516             } else {
5517                 // c = bit | val;
5518                 symbol *tlbl = newiTempLabel(NULL);
5519                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5520
5521
5522                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5523                 if( AOP_TYPE(right) == AOP_ACC) {
5524                   emitpcode(POC_IORLW, popGetLit(0));
5525                   emitSKPNZ;
5526                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5527                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5528                 }
5529
5530
5531
5532                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5533                     pic14_emitcode(";XXX setb","c");
5534                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5535                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5536                 pic14_toBoolean(right);
5537                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5538                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5539                     jmpTrueOrFalse(ifx, tlbl);
5540                     goto release;
5541                 } else {
5542                     CLRC;
5543                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5544                 }
5545             }
5546         }
5547         // bit = c
5548         // val = c
5549         if(size)
5550             pic14_outBitC(result);
5551         // if(bit | ...)
5552         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5553             genIfxJump(ifx, "c");           
5554         goto release ;
5555     }
5556
5557     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5558     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5559     if((AOP_TYPE(right) == AOP_LIT) &&
5560        (AOP_TYPE(result) == AOP_CRY) &&
5561        (AOP_TYPE(left) != AOP_CRY)){
5562         if(lit){
5563           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5564             // result = 1
5565             if(size)
5566                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5567             else 
5568                 continueIfTrue(ifx);
5569             goto release;
5570         } else {
5571           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5572             // lit = 0, result = boolean(left)
5573             if(size)
5574                 pic14_emitcode(";XXX setb","c");
5575             pic14_toBoolean(right);
5576             if(size){
5577                 symbol *tlbl = newiTempLabel(NULL);
5578                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5579                 CLRC;
5580                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5581             } else {
5582                 genIfxJump (ifx,"a");
5583                 goto release;
5584             }
5585         }
5586         pic14_outBitC(result);
5587         goto release ;
5588     }
5589
5590     /* if left is same as result */
5591     if(pic14_sameRegs(AOP(result),AOP(left))){
5592       int know_W = -1;
5593       for(;size--; offset++,lit>>=8) {
5594         if(AOP_TYPE(right) == AOP_LIT){
5595           if((lit & 0xff) == 0)
5596             /*  or'ing with 0 has no effect */
5597             continue;
5598           else {
5599             int p = my_powof2(lit & 0xff);
5600             if(p>=0) {
5601               /* only one bit is set in the literal, so use a bsf instruction */
5602               emitpcode(POC_BSF,
5603                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5604             } else {
5605               if(know_W != (lit & 0xff))
5606                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5607               know_W = lit & 0xff;
5608               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5609             }
5610                     
5611           }
5612         } else {
5613           if (AOP_TYPE(left) == AOP_ACC) {
5614             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5615             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5616           } else {                  
5617             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5618             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5619
5620             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5621             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5622
5623           }
5624         }
5625       }
5626     } else {
5627         // left & result in different registers
5628         if(AOP_TYPE(result) == AOP_CRY){
5629             // result = bit
5630             // if(size), result in bit
5631             // if(!size && ifx), conditional oper: if(left | right)
5632             symbol *tlbl = newiTempLabel(NULL);
5633             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5634             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5635
5636
5637             if(size)
5638                 pic14_emitcode(";XXX setb","c");
5639             while(sizer--){
5640                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5641                 pic14_emitcode(";XXX orl","a,%s",
5642                          aopGet(AOP(left),offset,FALSE,FALSE));
5643                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5644                 offset++;
5645             }
5646             if(size){
5647                 CLRC;
5648                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5649                 pic14_outBitC(result);
5650             } else if(ifx)
5651                 jmpTrueOrFalse(ifx, tlbl);
5652         } else for(;(size--);offset++){
5653           // normal case
5654           // result = left & right
5655           if(AOP_TYPE(right) == AOP_LIT){
5656             int t = (lit >> (offset*8)) & 0x0FFL;
5657             switch(t) { 
5658             case 0x00:
5659               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5660               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5661
5662               pic14_emitcode("movf","%s,w",
5663                        aopGet(AOP(left),offset,FALSE,FALSE));
5664               pic14_emitcode("movwf","%s",
5665                        aopGet(AOP(result),offset,FALSE,FALSE));
5666               break;
5667             default:
5668               emitpcode(POC_MOVLW,  popGetLit(t));
5669               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5670               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5671
5672               pic14_emitcode("movlw","0x%x",t);
5673               pic14_emitcode("iorwf","%s,w",
5674                        aopGet(AOP(left),offset,FALSE,FALSE));
5675               pic14_emitcode("movwf","%s",
5676                        aopGet(AOP(result),offset,FALSE,FALSE));
5677               
5678             }
5679             continue;
5680           }
5681
5682           // faster than result <- left, anl result,right
5683           // and better if result is SFR
5684           if (AOP_TYPE(left) == AOP_ACC) {
5685             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5686             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5687           } else {
5688             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5689             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5690
5691             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5692             pic14_emitcode("iorwf","%s,w",
5693                      aopGet(AOP(left),offset,FALSE,FALSE));
5694           }
5695           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5696           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5697         }
5698     }
5699
5700 release :
5701     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5702     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5703     freeAsmop(result,NULL,ic,TRUE);     
5704 }
5705
5706 /*-----------------------------------------------------------------*/
5707 /* genXor - code for xclusive or                                   */
5708 /*-----------------------------------------------------------------*/
5709 static void genXor (iCode *ic, iCode *ifx)
5710 {
5711   operand *left, *right, *result;
5712   int size, offset=0;
5713   unsigned long lit = 0L;
5714
5715   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5716
5717   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5718   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5719   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5720
5721   /* if left is a literal & right is not ||
5722      if left needs acc & right does not */
5723   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5724       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5725     operand *tmp = right ;
5726     right = left;
5727     left = tmp;
5728   }
5729
5730   /* if result = right then exchange them */
5731   if(pic14_sameRegs(AOP(result),AOP(right))){
5732     operand *tmp = right ;
5733     right = left;
5734     left = tmp;
5735   }
5736
5737   /* if right is bit then exchange them */
5738   if (AOP_TYPE(right) == AOP_CRY &&
5739       AOP_TYPE(left) != AOP_CRY){
5740     operand *tmp = right ;
5741     right = left;
5742     left = tmp;
5743   }
5744   if(AOP_TYPE(right) == AOP_LIT)
5745     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5746
5747   size = AOP_SIZE(result);
5748
5749   // if(bit ^ yy)
5750   // xx = bit ^ yy;
5751   if (AOP_TYPE(left) == AOP_CRY){
5752     if(AOP_TYPE(right) == AOP_LIT){
5753       // c = bit & literal;
5754       if(lit>>1){
5755         // lit>>1  != 0 => result = 1
5756         if(AOP_TYPE(result) == AOP_CRY){
5757           if(size)
5758             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5759             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5760           else if(ifx)
5761             continueIfTrue(ifx);
5762           goto release;
5763         }
5764         pic14_emitcode("setb","c");
5765       } else{
5766         // lit == (0 or 1)
5767         if(lit == 0){
5768           // lit == 0, result = left
5769           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5770             goto release;
5771           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5772         } else{
5773           // lit == 1, result = not(left)
5774           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5775             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5776             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5777             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5778             goto release;
5779           } else {
5780             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5781             pic14_emitcode("cpl","c");
5782           }
5783         }
5784       }
5785
5786     } else {
5787       // right != literal
5788       symbol *tlbl = newiTempLabel(NULL);
5789       if (AOP_TYPE(right) == AOP_CRY){
5790         // c = bit ^ bit;
5791         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5792       }
5793       else{
5794         int sizer = AOP_SIZE(right);
5795         // c = bit ^ val
5796         // if val>>1 != 0, result = 1
5797         pic14_emitcode("setb","c");
5798         while(sizer){
5799           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5800           if(sizer == 1)
5801             // test the msb of the lsb
5802             pic14_emitcode("anl","a,#0xfe");
5803           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5804           sizer--;
5805         }
5806         // val = (0,1)
5807         pic14_emitcode("rrc","a");
5808       }
5809       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5810       pic14_emitcode("cpl","c");
5811       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5812     }
5813     // bit = c
5814     // val = c
5815     if(size)
5816       pic14_outBitC(result);
5817     // if(bit | ...)
5818     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5819       genIfxJump(ifx, "c");           
5820     goto release ;
5821   }
5822
5823   if(pic14_sameRegs(AOP(result),AOP(left))){
5824     /* if left is same as result */
5825     for(;size--; offset++) {
5826       if(AOP_TYPE(right) == AOP_LIT){
5827         int t  = (lit >> (offset*8)) & 0x0FFL;
5828         if(t == 0x00L)
5829           continue;
5830         else
5831           if (IS_AOP_PREG(left)) {
5832             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5833             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5834             aopPut(AOP(result),"a",offset);
5835           } else {
5836             emitpcode(POC_MOVLW, popGetLit(t));
5837             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5838             pic14_emitcode("xrl","%s,%s",
5839                            aopGet(AOP(left),offset,FALSE,TRUE),
5840                            aopGet(AOP(right),offset,FALSE,FALSE));
5841           }
5842       } else {
5843         if (AOP_TYPE(left) == AOP_ACC)
5844           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5845         else {
5846           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5847           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5848 /*
5849           if (IS_AOP_PREG(left)) {
5850             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5851             aopPut(AOP(result),"a",offset);
5852           } else
5853             pic14_emitcode("xrl","%s,a",
5854                            aopGet(AOP(left),offset,FALSE,TRUE));
5855 */
5856         }
5857       }
5858     }
5859   } else {
5860     // left & result in different registers
5861     if(AOP_TYPE(result) == AOP_CRY){
5862       // result = bit
5863       // if(size), result in bit
5864       // if(!size && ifx), conditional oper: if(left ^ right)
5865       symbol *tlbl = newiTempLabel(NULL);
5866       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5867       if(size)
5868         pic14_emitcode("setb","c");
5869       while(sizer--){
5870         if((AOP_TYPE(right) == AOP_LIT) &&
5871            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5872           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5873         } else {
5874           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5875           pic14_emitcode("xrl","a,%s",
5876                          aopGet(AOP(left),offset,FALSE,FALSE));
5877         }
5878         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5879         offset++;
5880       }
5881       if(size){
5882         CLRC;
5883         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5884         pic14_outBitC(result);
5885       } else if(ifx)
5886         jmpTrueOrFalse(ifx, tlbl);
5887     } else for(;(size--);offset++){
5888       // normal case
5889       // result = left & right
5890       if(AOP_TYPE(right) == AOP_LIT){
5891         int t = (lit >> (offset*8)) & 0x0FFL;
5892         switch(t) { 
5893         case 0x00:
5894           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5895           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5896           pic14_emitcode("movf","%s,w",
5897                          aopGet(AOP(left),offset,FALSE,FALSE));
5898           pic14_emitcode("movwf","%s",
5899                          aopGet(AOP(result),offset,FALSE,FALSE));
5900           break;
5901         case 0xff:
5902           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5903           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5904           pic14_emitcode("comf","%s,w",
5905                          aopGet(AOP(left),offset,FALSE,FALSE));
5906           pic14_emitcode("movwf","%s",
5907                          aopGet(AOP(result),offset,FALSE,FALSE));
5908           break;
5909         default:
5910           emitpcode(POC_MOVLW, popGetLit(t));
5911           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5912           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5913           pic14_emitcode("movlw","0x%x",t);
5914           pic14_emitcode("xorwf","%s,w",
5915                          aopGet(AOP(left),offset,FALSE,FALSE));
5916           pic14_emitcode("movwf","%s",
5917                          aopGet(AOP(result),offset,FALSE,FALSE));
5918
5919         }
5920         continue;
5921       }
5922
5923       // faster than result <- left, anl result,right
5924       // and better if result is SFR
5925       if (AOP_TYPE(left) == AOP_ACC) {
5926         emitpcode(POC_XORFW,popGet(AOP(right),offset));
5927         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5928       } else {
5929         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5930         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5931         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5932         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5933       }
5934       if ( AOP_TYPE(result) != AOP_ACC){
5935         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5936         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5937       }
5938     }
5939   }
5940
5941   release :
5942     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5943   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5944   freeAsmop(result,NULL,ic,TRUE);     
5945 }
5946
5947 /*-----------------------------------------------------------------*/
5948 /* genInline - write the inline code out                           */
5949 /*-----------------------------------------------------------------*/
5950 static void genInline (iCode *ic)
5951 {
5952     char *buffer, *bp, *bp1;
5953     
5954     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5955
5956     _G.inLine += (!options.asmpeep);
5957
5958     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5959     strcpy(buffer,IC_INLINE(ic));
5960
5961     /* emit each line as a code */
5962     while (*bp) {
5963         if (*bp == '\n') {
5964             *bp++ = '\0';
5965             pic14_emitcode(bp1,"");
5966             addpCode2pBlock(pb,newpCodeInlineP(bp1));
5967             bp1 = bp;
5968         } else {
5969             if (*bp == ':') {
5970                 bp++;
5971                 *bp = '\0';
5972                 bp++;
5973                 pic14_emitcode(bp1,"");
5974                 bp1 = bp;
5975             } else
5976                 bp++;
5977         }
5978     }
5979     if (bp1 != bp) {
5980         pic14_emitcode(bp1,"");
5981         addpCode2pBlock(pb,newpCodeInlineP(bp1));
5982     }
5983     /*     pic14_emitcode("",buffer); */
5984     _G.inLine -= (!options.asmpeep);
5985 }
5986
5987 /*-----------------------------------------------------------------*/
5988 /* genRRC - rotate right with carry                                */
5989 /*-----------------------------------------------------------------*/
5990 static void genRRC (iCode *ic)
5991 {
5992   operand *left , *result ;
5993   int size, offset = 0, same;
5994
5995   /* rotate right with carry */
5996   left = IC_LEFT(ic);
5997   result=IC_RESULT(ic);
5998   aopOp (left,ic,FALSE);
5999   aopOp (result,ic,FALSE);
6000
6001   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6002
6003   same = pic14_sameRegs(AOP(result),AOP(left));
6004
6005   size = AOP_SIZE(result);    
6006
6007   /* get the lsb and put it into the carry */
6008   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6009
6010   offset = 0 ;
6011
6012   while(size--) {
6013
6014     if(same) {
6015       emitpcode(POC_RRF, popGet(AOP(left),offset));
6016     } else {
6017       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6018       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6019     }
6020
6021     offset++;
6022   }
6023
6024   freeAsmop(left,NULL,ic,TRUE);
6025   freeAsmop(result,NULL,ic,TRUE);
6026 }
6027
6028 /*-----------------------------------------------------------------*/
6029 /* genRLC - generate code for rotate left with carry               */
6030 /*-----------------------------------------------------------------*/
6031 static void genRLC (iCode *ic)
6032 {    
6033   operand *left , *result ;
6034   int size, offset = 0;
6035   int same;
6036
6037   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6038   /* rotate right with carry */
6039   left = IC_LEFT(ic);
6040   result=IC_RESULT(ic);
6041   aopOp (left,ic,FALSE);
6042   aopOp (result,ic,FALSE);
6043
6044   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6045
6046   same = pic14_sameRegs(AOP(result),AOP(left));
6047
6048   /* move it to the result */
6049   size = AOP_SIZE(result);    
6050
6051   /* get the msb and put it into the carry */
6052   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6053
6054   offset = 0 ;
6055
6056   while(size--) {
6057
6058     if(same) {
6059       emitpcode(POC_RLF, popGet(AOP(left),offset));
6060     } else {
6061       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6062       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6063     }
6064
6065     offset++;
6066   }
6067
6068
6069   freeAsmop(left,NULL,ic,TRUE);
6070   freeAsmop(result,NULL,ic,TRUE);
6071 }
6072
6073 /*-----------------------------------------------------------------*/
6074 /* genGetHbit - generates code get highest order bit               */
6075 /*-----------------------------------------------------------------*/
6076 static void genGetHbit (iCode *ic)
6077 {
6078     operand *left, *result;
6079     left = IC_LEFT(ic);
6080     result=IC_RESULT(ic);
6081     aopOp (left,ic,FALSE);
6082     aopOp (result,ic,FALSE);
6083
6084     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6085     /* get the highest order byte into a */
6086     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6087     if(AOP_TYPE(result) == AOP_CRY){
6088         pic14_emitcode("rlc","a");
6089         pic14_outBitC(result);
6090     }
6091     else{
6092         pic14_emitcode("rl","a");
6093         pic14_emitcode("anl","a,#0x01");
6094         pic14_outAcc(result);
6095     }
6096
6097
6098     freeAsmop(left,NULL,ic,TRUE);
6099     freeAsmop(result,NULL,ic,TRUE);
6100 }
6101
6102 /*-----------------------------------------------------------------*/
6103 /* AccRol - rotate left accumulator by known count                 */
6104 /*-----------------------------------------------------------------*/
6105 static void AccRol (int shCount)
6106 {
6107     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6108     shCount &= 0x0007;              // shCount : 0..7
6109     switch(shCount){
6110         case 0 :
6111             break;
6112         case 1 :
6113             pic14_emitcode("rl","a");
6114             break;
6115         case 2 :
6116             pic14_emitcode("rl","a");
6117             pic14_emitcode("rl","a");
6118             break;
6119         case 3 :
6120             pic14_emitcode("swap","a");
6121             pic14_emitcode("rr","a");
6122             break;
6123         case 4 :
6124             pic14_emitcode("swap","a");
6125             break;
6126         case 5 :
6127             pic14_emitcode("swap","a");
6128             pic14_emitcode("rl","a");
6129             break;
6130         case 6 :
6131             pic14_emitcode("rr","a");
6132             pic14_emitcode("rr","a");
6133             break;
6134         case 7 :
6135             pic14_emitcode("rr","a");
6136             break;
6137     }
6138 }
6139
6140 /*-----------------------------------------------------------------*/
6141 /* AccLsh - left shift accumulator by known count                  */
6142 /*-----------------------------------------------------------------*/
6143 static void AccLsh (int shCount)
6144 {
6145     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6146     if(shCount != 0){
6147         if(shCount == 1)
6148             pic14_emitcode("add","a,acc");
6149         else 
6150             if(shCount == 2) {
6151             pic14_emitcode("add","a,acc");
6152             pic14_emitcode("add","a,acc");
6153         } else {
6154             /* rotate left accumulator */
6155             AccRol(shCount);
6156             /* and kill the lower order bits */
6157             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6158         }
6159     }
6160 }
6161
6162 /*-----------------------------------------------------------------*/
6163 /* AccRsh - right shift accumulator by known count                 */
6164 /*-----------------------------------------------------------------*/
6165 static void AccRsh (int shCount)
6166 {
6167     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6168     if(shCount != 0){
6169         if(shCount == 1){
6170             CLRC;
6171             pic14_emitcode("rrc","a");
6172         } else {
6173             /* rotate right accumulator */
6174             AccRol(8 - shCount);
6175             /* and kill the higher order bits */
6176             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6177         }
6178     }
6179 }
6180
6181 #if 0
6182 /*-----------------------------------------------------------------*/
6183 /* AccSRsh - signed right shift accumulator by known count                 */
6184 /*-----------------------------------------------------------------*/
6185 static void AccSRsh (int shCount)
6186 {
6187     symbol *tlbl ;
6188     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6189     if(shCount != 0){
6190         if(shCount == 1){
6191             pic14_emitcode("mov","c,acc.7");
6192             pic14_emitcode("rrc","a");
6193         } else if(shCount == 2){
6194             pic14_emitcode("mov","c,acc.7");
6195             pic14_emitcode("rrc","a");
6196             pic14_emitcode("mov","c,acc.7");
6197             pic14_emitcode("rrc","a");
6198         } else {
6199             tlbl = newiTempLabel(NULL);
6200             /* rotate right accumulator */
6201             AccRol(8 - shCount);
6202             /* and kill the higher order bits */
6203             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6204             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6205             pic14_emitcode("orl","a,#0x%02x",
6206                      (unsigned char)~SRMask[shCount]);
6207             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6208         }
6209     }
6210 }
6211 #endif
6212 /*-----------------------------------------------------------------*/
6213 /* shiftR1Left2Result - shift right one byte from left to result   */
6214 /*-----------------------------------------------------------------*/
6215 static void shiftR1Left2ResultSigned (operand *left, int offl,
6216                                 operand *result, int offr,
6217                                 int shCount)
6218 {
6219   int same;
6220
6221   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6222
6223   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6224
6225   switch(shCount) {
6226   case 1:
6227     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6228     if(same) 
6229       emitpcode(POC_RRF, popGet(AOP(result),offr));
6230     else {
6231       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6232       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6233     }
6234
6235     break;
6236   case 2:
6237
6238     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6239     if(same) 
6240       emitpcode(POC_RRF, popGet(AOP(result),offr));
6241     else {
6242       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6243       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6244     }
6245     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6246     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6247
6248     break;
6249
6250   case 3:
6251     if(same)
6252       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6253     else {
6254       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6255       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6256     }
6257
6258     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6259     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6260     emitpcode(POC_ANDLW, popGetLit(0x1f));
6261
6262     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6263     emitpcode(POC_IORLW, popGetLit(0xe0));
6264
6265     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6266     break;
6267
6268   case 4:
6269     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6270     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6271     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6272     emitpcode(POC_IORLW,  popGetLit(0xf0));
6273     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6274     break;
6275   case 5:
6276     if(same) {
6277       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6278     } else {
6279       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6280       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6281     }
6282     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6283     emitpcode(POC_ANDLW,  popGetLit(0x07));
6284     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6285     emitpcode(POC_IORLW,  popGetLit(0xf8));
6286     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6287     break;
6288
6289   case 6:
6290     if(same) {
6291       emitpcode(POC_MOVLW, popGetLit(0x00));
6292       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6293       emitpcode(POC_MOVLW, popGetLit(0xfe));
6294       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6295       emitpcode(POC_IORLW, popGetLit(0x01));
6296       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6297     } else {
6298       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6299       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6300       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6301       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6302       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6303     }
6304     break;
6305
6306   case 7:
6307     if(same) {
6308       emitpcode(POC_MOVLW, popGetLit(0x00));
6309       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6310       emitpcode(POC_MOVLW, popGetLit(0xff));
6311       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6312     } else {
6313       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6314       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6315       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6316     }
6317
6318   default:
6319     break;
6320   }
6321 }
6322
6323 /*-----------------------------------------------------------------*/
6324 /* shiftR1Left2Result - shift right one byte from left to result   */
6325 /*-----------------------------------------------------------------*/
6326 static void shiftR1Left2Result (operand *left, int offl,
6327                                 operand *result, int offr,
6328                                 int shCount, int sign)
6329 {
6330   int same;
6331
6332   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6333
6334   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6335
6336   /* Copy the msb into the carry if signed. */
6337   if(sign) {
6338     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6339     return;
6340   }
6341
6342
6343
6344   switch(shCount) {
6345   case 1:
6346     emitCLRC;
6347     if(same) 
6348       emitpcode(POC_RRF, popGet(AOP(result),offr));
6349     else {
6350       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6351       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6352     }
6353     break;
6354   case 2:
6355     emitCLRC;
6356     if(same) {
6357       emitpcode(POC_RRF, popGet(AOP(result),offr));
6358     } else {
6359       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6360       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6361     }
6362     emitCLRC;
6363     emitpcode(POC_RRF, popGet(AOP(result),offr));
6364
6365     break;
6366   case 3:
6367     if(same)
6368       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6369     else {
6370       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6371       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6372     }
6373
6374     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6375     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6376     emitpcode(POC_ANDLW, popGetLit(0x1f));
6377     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6378     break;
6379       
6380   case 4:
6381     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6382     emitpcode(POC_ANDLW, popGetLit(0x0f));
6383     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384     break;
6385
6386   case 5:
6387     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6388     emitpcode(POC_ANDLW, popGetLit(0x0f));
6389     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6390     emitCLRC;
6391     emitpcode(POC_RRF, popGet(AOP(result),offr));
6392
6393     break;
6394   case 6:
6395
6396     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6397     emitpcode(POC_ANDLW, popGetLit(0x80));
6398     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6399     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6400     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6401     break;
6402
6403   case 7:
6404
6405     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6406     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6407     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6408
6409     break;
6410
6411   default:
6412     break;
6413   }
6414 }
6415
6416 /*-----------------------------------------------------------------*/
6417 /* shiftL1Left2Result - shift left one byte from left to result    */
6418 /*-----------------------------------------------------------------*/
6419 static void shiftL1Left2Result (operand *left, int offl,
6420                                 operand *result, int offr, int shCount)
6421 {
6422   int same;
6423
6424   //    char *l;
6425   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6426
6427   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6428   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6429     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6430     //    MOVA(l);
6431     /* shift left accumulator */
6432     //AccLsh(shCount); // don't comment out just yet...
6433   //    aopPut(AOP(result),"a",offr);
6434
6435   switch(shCount) {
6436   case 1:
6437     /* Shift left 1 bit position */
6438     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6439     if(same) {
6440       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6441     } else {
6442       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6443       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6444     }
6445     break;
6446   case 2:
6447     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6448     emitpcode(POC_ANDLW,popGetLit(0x7e));
6449     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6450     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6451     break;
6452   case 3:
6453     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6454     emitpcode(POC_ANDLW,popGetLit(0x3e));
6455     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6456     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6457     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6458     break;
6459   case 4:
6460     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6461     emitpcode(POC_ANDLW, popGetLit(0xf0));
6462     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6463     break;
6464   case 5:
6465     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6466     emitpcode(POC_ANDLW, popGetLit(0xf0));
6467     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6468     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6469     break;
6470   case 6:
6471     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6472     emitpcode(POC_ANDLW, popGetLit(0x30));
6473     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6474     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6475     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6476     break;
6477   case 7:
6478     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6479     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6480     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6481     break;
6482
6483   default:
6484     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6485   }
6486
6487 }
6488
6489 /*-----------------------------------------------------------------*/
6490 /* movLeft2Result - move byte from left to result                  */
6491 /*-----------------------------------------------------------------*/
6492 static void movLeft2Result (operand *left, int offl,
6493                             operand *result, int offr)
6494 {
6495   char *l;
6496   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6497   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6498     l = aopGet(AOP(left),offl,FALSE,FALSE);
6499
6500     if (*l == '@' && (IS_AOP_PREG(result))) {
6501       pic14_emitcode("mov","a,%s",l);
6502       aopPut(AOP(result),"a",offr);
6503     } else {
6504       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6505       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6506     }
6507   }
6508 }
6509
6510 /*-----------------------------------------------------------------*/
6511 /* shiftL2Left2Result - shift left two bytes from left to result   */
6512 /*-----------------------------------------------------------------*/
6513 static void shiftL2Left2Result (operand *left, int offl,
6514                                 operand *result, int offr, int shCount)
6515 {
6516
6517
6518   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6519
6520   if(pic14_sameRegs(AOP(result), AOP(left))) {
6521     switch(shCount) {
6522     case 0:
6523       break;
6524     case 1:
6525     case 2:
6526     case 3:
6527
6528       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6529       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6530       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6531
6532       while(--shCount) {
6533         emitCLRC;
6534         emitpcode(POC_RLF, popGet(AOP(result),offr));
6535         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6536       }
6537
6538       break;
6539     case 4:
6540     case 5:
6541       emitpcode(POC_MOVLW, popGetLit(0x0f));
6542       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6543       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6544       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6545       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6546       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6547       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6548       if(shCount >=5) {
6549         emitpcode(POC_RLF, popGet(AOP(result),offr));
6550         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6551       }
6552       break;
6553     case 6:
6554       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6555       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6556       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6557       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6558       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6559       emitpcode(POC_ANDLW,popGetLit(0xc0));
6560       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6561       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6562       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6563       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6564       break;
6565     case 7:
6566       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6567       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6568       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6569       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6570       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6571     }
6572
6573   } else {
6574     switch(shCount) {
6575     case 0:
6576       break;
6577     case 1:
6578     case 2:
6579     case 3:
6580       /* note, use a mov/add for the shift since the mov has a
6581          chance of getting optimized out */
6582       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6583       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6584       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6585       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6586       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6587
6588       while(--shCount) {
6589         emitCLRC;
6590         emitpcode(POC_RLF, popGet(AOP(result),offr));
6591         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6592       }
6593       break;
6594
6595     case 4:
6596     case 5:
6597       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6598       emitpcode(POC_ANDLW, popGetLit(0xF0));
6599       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6600       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6601       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6602       emitpcode(POC_ANDLW, popGetLit(0xF0));
6603       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6604       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6605
6606
6607       if(shCount == 5) {
6608         emitpcode(POC_RLF, popGet(AOP(result),offr));
6609         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6610       }
6611       break;
6612     case 6:
6613       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6614       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6615       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6616       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6617
6618       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6619       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6620       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6621       emitpcode(POC_ANDLW,popGetLit(0xc0));
6622       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6623       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6624       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6625       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6626       break;
6627     case 7:
6628       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6629       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6630       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6631       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6632       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6633     }
6634   }
6635
6636 }
6637 /*-----------------------------------------------------------------*/
6638 /* shiftR2Left2Result - shift right two bytes from left to result  */
6639 /*-----------------------------------------------------------------*/
6640 static void shiftR2Left2Result (operand *left, int offl,
6641                                 operand *result, int offr,
6642                                 int shCount, int sign)
6643 {
6644   int same=0;
6645
6646   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6647   same = pic14_sameRegs(AOP(result), AOP(left));
6648
6649   if(same && ((offl + MSB16) == offr)){
6650     same=1;
6651     /* don't crash result[offr] */
6652     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6653     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6654   } else {
6655     movLeft2Result(left,offl, result, offr);
6656     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6657   }
6658   /* a:x >> shCount (x = lsb(result))*/
6659 /*
6660   if(sign)
6661     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6662   else {
6663     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6664 */
6665   switch(shCount) {
6666   case 0:
6667     break;
6668   case 1:
6669   case 2:
6670   case 3:
6671     if(sign)
6672       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6673     else
6674       emitCLRC;
6675
6676     if(same) {
6677       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6678       emitpcode(POC_RRF,popGet(AOP(result),offr));
6679     } else {
6680       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6681       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6682       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6683       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6684     }
6685
6686     while(--shCount) {
6687       if(sign)
6688         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6689       else
6690         emitCLRC;
6691       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6692       emitpcode(POC_RRF,popGet(AOP(result),offr));
6693     }
6694     break;
6695   case 4:
6696   case 5:
6697     if(same) {
6698
6699       emitpcode(POC_MOVLW, popGetLit(0xf0));
6700       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6701       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6702
6703       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6704       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6705       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6706       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6707     } else {
6708       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6709       emitpcode(POC_ANDLW, popGetLit(0x0f));
6710       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6711
6712       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6714       emitpcode(POC_ANDLW, popGetLit(0xf0));
6715       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6716       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6717     }
6718
6719     if(shCount >=5) {
6720       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6721       emitpcode(POC_RRF, popGet(AOP(result),offr));
6722     }
6723
6724     if(sign) {
6725       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6726       emitpcode(POC_BTFSC, 
6727                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6728       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6729     }
6730
6731     break;
6732
6733   case 6:
6734     if(same) {
6735
6736       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6737       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6738
6739       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6740       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6741       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6742       emitpcode(POC_ANDLW,popGetLit(0x03));
6743       if(sign) {
6744         emitpcode(POC_BTFSC, 
6745                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6746         emitpcode(POC_IORLW,popGetLit(0xfc));
6747       }
6748       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6749       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6750       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6751       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6752     } else {
6753       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6754       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6756       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6757       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6758       emitpcode(POC_ANDLW,popGetLit(0x03));
6759       if(sign) {
6760         emitpcode(POC_BTFSC, 
6761                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6762         emitpcode(POC_IORLW,popGetLit(0xfc));
6763       }
6764       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6765       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6766
6767         
6768     }
6769
6770     break;
6771   case 7:
6772     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6773     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6774     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6775     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6776     if(sign) {
6777       emitSKPNC;
6778       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6779     } else 
6780       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6781   }
6782 }
6783
6784
6785 /*-----------------------------------------------------------------*/
6786 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6787 /*-----------------------------------------------------------------*/
6788 static void shiftLLeftOrResult (operand *left, int offl,
6789                                 operand *result, int offr, int shCount)
6790 {
6791     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6792     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6793     /* shift left accumulator */
6794     AccLsh(shCount);
6795     /* or with result */
6796     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6797     /* back to result */
6798     aopPut(AOP(result),"a",offr);
6799 }
6800
6801 /*-----------------------------------------------------------------*/
6802 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6803 /*-----------------------------------------------------------------*/
6804 static void shiftRLeftOrResult (operand *left, int offl,
6805                                 operand *result, int offr, int shCount)
6806 {
6807     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6808     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6809     /* shift right accumulator */
6810     AccRsh(shCount);
6811     /* or with result */
6812     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6813     /* back to result */
6814     aopPut(AOP(result),"a",offr);
6815 }
6816
6817 /*-----------------------------------------------------------------*/
6818 /* genlshOne - left shift a one byte quantity by known count       */
6819 /*-----------------------------------------------------------------*/
6820 static void genlshOne (operand *result, operand *left, int shCount)
6821 {       
6822     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6823     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6824 }
6825
6826 /*-----------------------------------------------------------------*/
6827 /* genlshTwo - left shift two bytes by known amount != 0           */
6828 /*-----------------------------------------------------------------*/
6829 static void genlshTwo (operand *result,operand *left, int shCount)
6830 {
6831     int size;
6832     
6833     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6834     size = pic14_getDataSize(result);
6835
6836     /* if shCount >= 8 */
6837     if (shCount >= 8) {
6838         shCount -= 8 ;
6839
6840         if (size > 1){
6841             if (shCount)
6842                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6843             else 
6844                 movLeft2Result(left, LSB, result, MSB16);
6845         }
6846         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6847     }
6848
6849     /*  1 <= shCount <= 7 */
6850     else {  
6851         if(size == 1)
6852             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6853         else 
6854             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6855     }
6856 }
6857
6858 /*-----------------------------------------------------------------*/
6859 /* shiftLLong - shift left one long from left to result            */
6860 /* offl = LSB or MSB16                                             */
6861 /*-----------------------------------------------------------------*/
6862 static void shiftLLong (operand *left, operand *result, int offr )
6863 {
6864     char *l;
6865     int size = AOP_SIZE(result);
6866
6867     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6868     if(size >= LSB+offr){
6869         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6870         MOVA(l);
6871         pic14_emitcode("add","a,acc");
6872         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6873             size >= MSB16+offr && offr != LSB )
6874             pic14_emitcode("xch","a,%s",
6875                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6876         else        
6877             aopPut(AOP(result),"a",LSB+offr);
6878     }
6879
6880     if(size >= MSB16+offr){
6881         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6882             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6883             MOVA(l);
6884         }
6885         pic14_emitcode("rlc","a");
6886         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6887             size >= MSB24+offr && offr != LSB)
6888             pic14_emitcode("xch","a,%s",
6889                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6890         else        
6891             aopPut(AOP(result),"a",MSB16+offr);
6892     }
6893
6894     if(size >= MSB24+offr){
6895         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6896             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6897             MOVA(l);
6898         }
6899         pic14_emitcode("rlc","a");
6900         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6901             size >= MSB32+offr && offr != LSB )
6902             pic14_emitcode("xch","a,%s",
6903                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6904         else        
6905             aopPut(AOP(result),"a",MSB24+offr);
6906     }
6907
6908     if(size > MSB32+offr){
6909         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6910             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6911             MOVA(l);    
6912         }
6913         pic14_emitcode("rlc","a");
6914         aopPut(AOP(result),"a",MSB32+offr);
6915     }
6916     if(offr != LSB)
6917         aopPut(AOP(result),zero,LSB);       
6918 }
6919
6920 /*-----------------------------------------------------------------*/
6921 /* genlshFour - shift four byte by a known amount != 0             */
6922 /*-----------------------------------------------------------------*/
6923 static void genlshFour (operand *result, operand *left, int shCount)
6924 {
6925     int size;
6926
6927     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6928     size = AOP_SIZE(result);
6929
6930     /* if shifting more that 3 bytes */
6931     if (shCount >= 24 ) {
6932         shCount -= 24;
6933         if (shCount)
6934             /* lowest order of left goes to the highest
6935             order of the destination */
6936             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6937         else
6938             movLeft2Result(left, LSB, result, MSB32);
6939         aopPut(AOP(result),zero,LSB);
6940         aopPut(AOP(result),zero,MSB16);
6941         aopPut(AOP(result),zero,MSB32);
6942         return;
6943     }
6944
6945     /* more than two bytes */
6946     else if ( shCount >= 16 ) {
6947         /* lower order two bytes goes to higher order two bytes */
6948         shCount -= 16;
6949         /* if some more remaining */
6950         if (shCount)
6951             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6952         else {
6953             movLeft2Result(left, MSB16, result, MSB32);
6954             movLeft2Result(left, LSB, result, MSB24);
6955         }
6956         aopPut(AOP(result),zero,MSB16);
6957         aopPut(AOP(result),zero,LSB);
6958         return;
6959     }    
6960
6961     /* if more than 1 byte */
6962     else if ( shCount >= 8 ) {
6963         /* lower order three bytes goes to higher order  three bytes */
6964         shCount -= 8;
6965         if(size == 2){
6966             if(shCount)
6967                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6968             else
6969                 movLeft2Result(left, LSB, result, MSB16);
6970         }
6971         else{   /* size = 4 */
6972             if(shCount == 0){
6973                 movLeft2Result(left, MSB24, result, MSB32);
6974                 movLeft2Result(left, MSB16, result, MSB24);
6975                 movLeft2Result(left, LSB, result, MSB16);
6976                 aopPut(AOP(result),zero,LSB);
6977             }
6978             else if(shCount == 1)
6979                 shiftLLong(left, result, MSB16);
6980             else{
6981                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6982                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6983                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6984                 aopPut(AOP(result),zero,LSB);
6985             }
6986         }
6987     }
6988
6989     /* 1 <= shCount <= 7 */
6990     else if(shCount <= 2){
6991         shiftLLong(left, result, LSB);
6992         if(shCount == 2)
6993             shiftLLong(result, result, LSB);
6994     }
6995     /* 3 <= shCount <= 7, optimize */
6996     else{
6997         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6998         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6999         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7000     }
7001 }
7002
7003 /*-----------------------------------------------------------------*/
7004 /* genLeftShiftLiteral - left shifting by known count              */
7005 /*-----------------------------------------------------------------*/
7006 static void genLeftShiftLiteral (operand *left,
7007                                  operand *right,
7008                                  operand *result,
7009                                  iCode *ic)
7010 {    
7011     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7012     int size;
7013
7014     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7015     freeAsmop(right,NULL,ic,TRUE);
7016
7017     aopOp(left,ic,FALSE);
7018     aopOp(result,ic,FALSE);
7019
7020     size = getSize(operandType(result));
7021
7022 #if VIEW_SIZE
7023     pic14_emitcode("; shift left ","result %d, left %d",size,
7024              AOP_SIZE(left));
7025 #endif
7026
7027     /* I suppose that the left size >= result size */
7028     if(shCount == 0){
7029         while(size--){
7030             movLeft2Result(left, size, result, size);
7031         }
7032     }
7033
7034     else if(shCount >= (size * 8))
7035         while(size--)
7036             aopPut(AOP(result),zero,size);
7037     else{
7038         switch (size) {
7039             case 1:
7040                 genlshOne (result,left,shCount);
7041                 break;
7042
7043             case 2:
7044             case 3:
7045                 genlshTwo (result,left,shCount);
7046                 break;
7047
7048             case 4:
7049                 genlshFour (result,left,shCount);
7050                 break;
7051         }
7052     }
7053     freeAsmop(left,NULL,ic,TRUE);
7054     freeAsmop(result,NULL,ic,TRUE);
7055 }
7056
7057 /*-----------------------------------------------------------------*
7058  * genMultiAsm - repeat assembly instruction for size of register.
7059  * if endian == 1, then the high byte (i.e base address + size of 
7060  * register) is used first else the low byte is used first;
7061  *-----------------------------------------------------------------*/
7062 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7063 {
7064
7065   int offset = 0;
7066
7067   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7068
7069   if(!reg)
7070     return;
7071
7072   if(!endian) {
7073     endian = 1;
7074   } else {
7075     endian = -1;
7076     offset = size-1;
7077   }
7078
7079   while(size--) {
7080     emitpcode(poc,    popGet(AOP(reg),offset));
7081     offset += endian;
7082   }
7083
7084 }
7085 /*-----------------------------------------------------------------*/
7086 /* genLeftShift - generates code for left shifting                 */
7087 /*-----------------------------------------------------------------*/
7088 static void genLeftShift (iCode *ic)
7089 {
7090   operand *left,*right, *result;
7091   int size, offset;
7092   char *l;
7093   symbol *tlbl , *tlbl1;
7094   pCodeOp *pctemp;
7095
7096   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7097
7098   right = IC_RIGHT(ic);
7099   left  = IC_LEFT(ic);
7100   result = IC_RESULT(ic);
7101
7102   aopOp(right,ic,FALSE);
7103
7104   /* if the shift count is known then do it 
7105      as efficiently as possible */
7106   if (AOP_TYPE(right) == AOP_LIT) {
7107     genLeftShiftLiteral (left,right,result,ic);
7108     return ;
7109   }
7110
7111   /* shift count is unknown then we have to form 
7112      a loop get the loop count in B : Note: we take
7113      only the lower order byte since shifting
7114      more that 32 bits make no sense anyway, ( the
7115      largest size of an object can be only 32 bits ) */  
7116
7117     
7118   aopOp(left,ic,FALSE);
7119   aopOp(result,ic,FALSE);
7120
7121   /* now move the left to the result if they are not the
7122      same */
7123   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7124       AOP_SIZE(result) > 1) {
7125
7126     size = AOP_SIZE(result);
7127     offset=0;
7128     while (size--) {
7129       l = aopGet(AOP(left),offset,FALSE,TRUE);
7130       if (*l == '@' && (IS_AOP_PREG(result))) {
7131
7132         pic14_emitcode("mov","a,%s",l);
7133         aopPut(AOP(result),"a",offset);
7134       } else {
7135         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7136         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7137         //aopPut(AOP(result),l,offset);
7138       }
7139       offset++;
7140     }
7141   }
7142
7143   size = AOP_SIZE(result);
7144
7145   /* if it is only one byte then */
7146   if (size == 1) {
7147     if(optimized_for_speed) {
7148       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7149       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7150       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7151       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7152       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7153       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7154       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7155       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7156       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7157       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7158       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7159       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7160     } else {
7161
7162       tlbl = newiTempLabel(NULL);
7163       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7164         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7165         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7166       }
7167
7168       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7169       emitpcode(POC_RRF,    popGet(AOP(result),0));
7170       emitpLabel(tlbl->key);
7171       emitpcode(POC_RLF,    popGet(AOP(result),0));
7172       emitpcode(POC_ADDLW,  popGetLit(1));
7173       emitSKPC;
7174       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7175     }
7176     goto release ;
7177   }
7178     
7179   if (pic14_sameRegs(AOP(left),AOP(result))) {
7180
7181     tlbl = newiTempLabel(NULL);
7182     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7183     genMultiAsm(POC_RRF, result, size,1);
7184     emitpLabel(tlbl->key);
7185     genMultiAsm(POC_RLF, result, size,0);
7186     emitpcode(POC_ADDLW,  popGetLit(1));
7187     emitSKPC;
7188     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7189     goto release;
7190   }
7191
7192   //tlbl = newiTempLabel(NULL);
7193   //offset = 0 ;   
7194   //tlbl1 = newiTempLabel(NULL);
7195
7196   //reAdjustPreg(AOP(result));    
7197     
7198   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7199   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7200   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7201   //MOVA(l);
7202   //pic14_emitcode("add","a,acc");         
7203   //aopPut(AOP(result),"a",offset++);
7204   //while (--size) {
7205   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7206   //  MOVA(l);
7207   //  pic14_emitcode("rlc","a");         
7208   //  aopPut(AOP(result),"a",offset++);
7209   //}
7210   //reAdjustPreg(AOP(result));
7211
7212   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7213   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7214
7215
7216   tlbl = newiTempLabel(NULL);
7217   tlbl1= newiTempLabel(NULL);
7218
7219   size = AOP_SIZE(result);
7220   offset = 1;
7221
7222   pctemp = popGetTempReg();  /* grab a temporary working register. */
7223
7224   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7225
7226   /* offset should be 0, 1 or 3 */
7227   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7228   emitSKPNZ;
7229   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7230
7231   emitpcode(POC_MOVWF, pctemp);
7232
7233
7234   emitpLabel(tlbl->key);
7235
7236   emitCLRC;
7237   emitpcode(POC_RLF,  popGet(AOP(result),0));
7238   while(--size)
7239     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7240
7241   emitpcode(POC_DECFSZ,  pctemp);
7242   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7243   emitpLabel(tlbl1->key);
7244
7245   popReleaseTempReg(pctemp);
7246
7247
7248  release:
7249   freeAsmop (right,NULL,ic,TRUE);
7250   freeAsmop(left,NULL,ic,TRUE);
7251   freeAsmop(result,NULL,ic,TRUE);
7252 }
7253
7254 /*-----------------------------------------------------------------*/
7255 /* genrshOne - right shift a one byte quantity by known count      */
7256 /*-----------------------------------------------------------------*/
7257 static void genrshOne (operand *result, operand *left,
7258                        int shCount, int sign)
7259 {
7260     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7261     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7262 }
7263
7264 /*-----------------------------------------------------------------*/
7265 /* genrshTwo - right shift two bytes by known amount != 0          */
7266 /*-----------------------------------------------------------------*/
7267 static void genrshTwo (operand *result,operand *left,
7268                        int shCount, int sign)
7269 {
7270   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7271   /* if shCount >= 8 */
7272   if (shCount >= 8) {
7273     shCount -= 8 ;
7274     if (shCount)
7275       shiftR1Left2Result(left, MSB16, result, LSB,
7276                          shCount, sign);
7277     else
7278       movLeft2Result(left, MSB16, result, LSB);
7279
7280     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7281
7282     if(sign) {
7283       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7284       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7285     }
7286   }
7287
7288   /*  1 <= shCount <= 7 */
7289   else
7290     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7291 }
7292
7293 /*-----------------------------------------------------------------*/
7294 /* shiftRLong - shift right one long from left to result           */
7295 /* offl = LSB or MSB16                                             */
7296 /*-----------------------------------------------------------------*/
7297 static void shiftRLong (operand *left, int offl,
7298                         operand *result, int sign)
7299 {
7300     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7301     if(!sign)
7302         pic14_emitcode("clr","c");
7303     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7304     if(sign)
7305         pic14_emitcode("mov","c,acc.7");
7306     pic14_emitcode("rrc","a");
7307     aopPut(AOP(result),"a",MSB32-offl);
7308     if(offl == MSB16)
7309         /* add sign of "a" */
7310         addSign(result, MSB32, sign);
7311
7312     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7313     pic14_emitcode("rrc","a");
7314     aopPut(AOP(result),"a",MSB24-offl);
7315
7316     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7317     pic14_emitcode("rrc","a");
7318     aopPut(AOP(result),"a",MSB16-offl);
7319
7320     if(offl == LSB){
7321         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7322         pic14_emitcode("rrc","a");
7323         aopPut(AOP(result),"a",LSB);
7324     }
7325 }
7326
7327 /*-----------------------------------------------------------------*/
7328 /* genrshFour - shift four byte by a known amount != 0             */
7329 /*-----------------------------------------------------------------*/
7330 static void genrshFour (operand *result, operand *left,
7331                         int shCount, int sign)
7332 {
7333   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7334   /* if shifting more that 3 bytes */
7335   if(shCount >= 24 ) {
7336     shCount -= 24;
7337     if(shCount)
7338       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7339     else
7340       movLeft2Result(left, MSB32, result, LSB);
7341
7342     addSign(result, MSB16, sign);
7343   }
7344   else if(shCount >= 16){
7345     shCount -= 16;
7346     if(shCount)
7347       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7348     else{
7349       movLeft2Result(left, MSB24, result, LSB);
7350       movLeft2Result(left, MSB32, result, MSB16);
7351     }
7352     addSign(result, MSB24, sign);
7353   }
7354   else if(shCount >= 8){
7355     shCount -= 8;
7356     if(shCount == 1)
7357       shiftRLong(left, MSB16, result, sign);
7358     else if(shCount == 0){
7359       movLeft2Result(left, MSB16, result, LSB);
7360       movLeft2Result(left, MSB24, result, MSB16);
7361       movLeft2Result(left, MSB32, result, MSB24);
7362       addSign(result, MSB32, sign);
7363     }
7364     else{
7365       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7366       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7367       /* the last shift is signed */
7368       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7369       addSign(result, MSB32, sign);
7370     }
7371   }
7372   else{   /* 1 <= shCount <= 7 */
7373     if(shCount <= 2){
7374       shiftRLong(left, LSB, result, sign);
7375       if(shCount == 2)
7376         shiftRLong(result, LSB, result, sign);
7377     }
7378     else{
7379       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7380       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7381       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7382     }
7383   }
7384 }
7385
7386 /*-----------------------------------------------------------------*/
7387 /* genRightShiftLiteral - right shifting by known count            */
7388 /*-----------------------------------------------------------------*/
7389 static void genRightShiftLiteral (operand *left,
7390                                   operand *right,
7391                                   operand *result,
7392                                   iCode *ic,
7393                                   int sign)
7394 {    
7395   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7396   int lsize,res_size;
7397
7398   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7399   freeAsmop(right,NULL,ic,TRUE);
7400
7401   aopOp(left,ic,FALSE);
7402   aopOp(result,ic,FALSE);
7403
7404 #if VIEW_SIZE
7405   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7406                  AOP_SIZE(left));
7407 #endif
7408
7409   lsize = pic14_getDataSize(left);
7410   res_size = pic14_getDataSize(result);
7411   /* test the LEFT size !!! */
7412
7413   /* I suppose that the left size >= result size */
7414   if(shCount == 0){
7415     while(res_size--)
7416       movLeft2Result(left, lsize, result, res_size);
7417   }
7418
7419   else if(shCount >= (lsize * 8)){
7420
7421     if(res_size == 1) {
7422       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7423       if(sign) {
7424         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7425         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7426       }
7427     } else {
7428
7429       if(sign) {
7430         emitpcode(POC_MOVLW, popGetLit(0));
7431         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7432         emitpcode(POC_MOVLW, popGetLit(0xff));
7433         while(res_size--)
7434           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7435
7436       } else {
7437
7438         while(res_size--)
7439           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7440       }
7441     }
7442   } else {
7443
7444     switch (res_size) {
7445     case 1:
7446       genrshOne (result,left,shCount,sign);
7447       break;
7448
7449     case 2:
7450       genrshTwo (result,left,shCount,sign);
7451       break;
7452
7453     case 4:
7454       genrshFour (result,left,shCount,sign);
7455       break;
7456     default :
7457       break;
7458     }
7459
7460   }
7461
7462   freeAsmop(left,NULL,ic,TRUE);
7463   freeAsmop(result,NULL,ic,TRUE);
7464 }
7465
7466 /*-----------------------------------------------------------------*/
7467 /* genSignedRightShift - right shift of signed number              */
7468 /*-----------------------------------------------------------------*/
7469 static void genSignedRightShift (iCode *ic)
7470 {
7471   operand *right, *left, *result;
7472   int size, offset;
7473   //  char *l;
7474   symbol *tlbl, *tlbl1 ;
7475   pCodeOp *pctemp;
7476
7477   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7478
7479   /* we do it the hard way put the shift count in b
7480      and loop thru preserving the sign */
7481   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7482
7483   right = IC_RIGHT(ic);
7484   left  = IC_LEFT(ic);
7485   result = IC_RESULT(ic);
7486
7487   aopOp(right,ic,FALSE);  
7488   aopOp(left,ic,FALSE);
7489   aopOp(result,ic,FALSE);
7490
7491
7492   if ( AOP_TYPE(right) == AOP_LIT) {
7493     genRightShiftLiteral (left,right,result,ic,1);
7494     return ;
7495   }
7496   /* shift count is unknown then we have to form 
7497      a loop get the loop count in B : Note: we take
7498      only the lower order byte since shifting
7499      more that 32 bits make no sense anyway, ( the
7500      largest size of an object can be only 32 bits ) */  
7501
7502   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7503   //pic14_emitcode("inc","b");
7504   //freeAsmop (right,NULL,ic,TRUE);
7505   //aopOp(left,ic,FALSE);
7506   //aopOp(result,ic,FALSE);
7507
7508   /* now move the left to the result if they are not the
7509      same */
7510   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7511       AOP_SIZE(result) > 1) {
7512
7513     size = AOP_SIZE(result);
7514     offset=0;
7515     while (size--) { 
7516       /*
7517         l = aopGet(AOP(left),offset,FALSE,TRUE);
7518         if (*l == '@' && IS_AOP_PREG(result)) {
7519
7520         pic14_emitcode("mov","a,%s",l);
7521         aopPut(AOP(result),"a",offset);
7522         } else
7523         aopPut(AOP(result),l,offset);
7524       */
7525       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7526       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7527
7528       offset++;
7529     }
7530   }
7531
7532   /* mov the highest order bit to OVR */    
7533   tlbl = newiTempLabel(NULL);
7534   tlbl1= newiTempLabel(NULL);
7535
7536   size = AOP_SIZE(result);
7537   offset = size - 1;
7538
7539   pctemp = popGetTempReg();  /* grab a temporary working register. */
7540
7541   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7542
7543   /* offset should be 0, 1 or 3 */
7544   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7545   emitSKPNZ;
7546   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7547
7548   emitpcode(POC_MOVWF, pctemp);
7549
7550
7551   emitpLabel(tlbl->key);
7552
7553   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7554   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7555
7556   while(--size) {
7557     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7558   }
7559
7560   emitpcode(POC_DECFSZ,  pctemp);
7561   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7562   emitpLabel(tlbl1->key);
7563
7564   popReleaseTempReg(pctemp);
7565 #if 0
7566   size = AOP_SIZE(result);
7567   offset = size - 1;
7568   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7569   pic14_emitcode("rlc","a");
7570   pic14_emitcode("mov","ov,c");
7571   /* if it is only one byte then */
7572   if (size == 1) {
7573     l = aopGet(AOP(left),0,FALSE,FALSE);
7574     MOVA(l);
7575     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7576     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7577     pic14_emitcode("mov","c,ov");
7578     pic14_emitcode("rrc","a");
7579     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7580     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7581     aopPut(AOP(result),"a",0);
7582     goto release ;
7583   }
7584
7585   reAdjustPreg(AOP(result));
7586   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7587   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7588   pic14_emitcode("mov","c,ov");
7589   while (size--) {
7590     l = aopGet(AOP(result),offset,FALSE,FALSE);
7591     MOVA(l);
7592     pic14_emitcode("rrc","a");         
7593     aopPut(AOP(result),"a",offset--);
7594   }
7595   reAdjustPreg(AOP(result));
7596   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7597   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7598
7599  release:
7600 #endif
7601
7602   freeAsmop(left,NULL,ic,TRUE);
7603   freeAsmop(result,NULL,ic,TRUE);
7604   freeAsmop(right,NULL,ic,TRUE);
7605 }
7606
7607 /*-----------------------------------------------------------------*/
7608 /* genRightShift - generate code for right shifting                */
7609 /*-----------------------------------------------------------------*/
7610 static void genRightShift (iCode *ic)
7611 {
7612     operand *right, *left, *result;
7613     sym_link *retype ;
7614     int size, offset;
7615     char *l;
7616     symbol *tlbl, *tlbl1 ;
7617
7618     /* if signed then we do it the hard way preserve the
7619     sign bit moving it inwards */
7620     retype = getSpec(operandType(IC_RESULT(ic)));
7621     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7622
7623     if (!SPEC_USIGN(retype)) {
7624         genSignedRightShift (ic);
7625         return ;
7626     }
7627
7628     /* signed & unsigned types are treated the same : i.e. the
7629     signed is NOT propagated inwards : quoting from the
7630     ANSI - standard : "for E1 >> E2, is equivalent to division
7631     by 2**E2 if unsigned or if it has a non-negative value,
7632     otherwise the result is implementation defined ", MY definition
7633     is that the sign does not get propagated */
7634
7635     right = IC_RIGHT(ic);
7636     left  = IC_LEFT(ic);
7637     result = IC_RESULT(ic);
7638
7639     aopOp(right,ic,FALSE);
7640
7641     /* if the shift count is known then do it 
7642     as efficiently as possible */
7643     if (AOP_TYPE(right) == AOP_LIT) {
7644         genRightShiftLiteral (left,right,result,ic, 0);
7645         return ;
7646     }
7647
7648     /* shift count is unknown then we have to form 
7649     a loop get the loop count in B : Note: we take
7650     only the lower order byte since shifting
7651     more that 32 bits make no sense anyway, ( the
7652     largest size of an object can be only 32 bits ) */  
7653
7654     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7655     pic14_emitcode("inc","b");
7656     aopOp(left,ic,FALSE);
7657     aopOp(result,ic,FALSE);
7658
7659     /* now move the left to the result if they are not the
7660     same */
7661     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7662         AOP_SIZE(result) > 1) {
7663
7664         size = AOP_SIZE(result);
7665         offset=0;
7666         while (size--) {
7667             l = aopGet(AOP(left),offset,FALSE,TRUE);
7668             if (*l == '@' && IS_AOP_PREG(result)) {
7669
7670                 pic14_emitcode("mov","a,%s",l);
7671                 aopPut(AOP(result),"a",offset);
7672             } else
7673                 aopPut(AOP(result),l,offset);
7674             offset++;
7675         }
7676     }
7677
7678     tlbl = newiTempLabel(NULL);
7679     tlbl1= newiTempLabel(NULL);
7680     size = AOP_SIZE(result);
7681     offset = size - 1;
7682
7683     /* if it is only one byte then */
7684     if (size == 1) {
7685
7686       tlbl = newiTempLabel(NULL);
7687       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7688         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7689         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7690       }
7691
7692       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7693       emitpcode(POC_RLF,    popGet(AOP(result),0));
7694       emitpLabel(tlbl->key);
7695       emitpcode(POC_RRF,    popGet(AOP(result),0));
7696       emitpcode(POC_ADDLW,  popGetLit(1));
7697       emitSKPC;
7698       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7699
7700       goto release ;
7701     }
7702
7703     reAdjustPreg(AOP(result));
7704     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7706     CLRC;
7707     while (size--) {
7708         l = aopGet(AOP(result),offset,FALSE,FALSE);
7709         MOVA(l);
7710         pic14_emitcode("rrc","a");         
7711         aopPut(AOP(result),"a",offset--);
7712     }
7713     reAdjustPreg(AOP(result));
7714
7715     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7717
7718 release:
7719     freeAsmop(left,NULL,ic,TRUE);
7720     freeAsmop (right,NULL,ic,TRUE);
7721     freeAsmop(result,NULL,ic,TRUE);
7722 }
7723
7724 /*-----------------------------------------------------------------*/
7725 /* genUnpackBits - generates code for unpacking bits               */
7726 /*-----------------------------------------------------------------*/
7727 static void genUnpackBits (operand *result, char *rname, int ptype)
7728 {    
7729     int shCnt ;
7730     int rlen = 0 ;
7731     sym_link *etype;
7732     int offset = 0 ;
7733
7734     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7735     etype = getSpec(operandType(result));
7736
7737     /* read the first byte  */
7738     switch (ptype) {
7739
7740     case POINTER:
7741     case IPOINTER:
7742         pic14_emitcode("mov","a,@%s",rname);
7743         break;
7744         
7745     case PPOINTER:
7746         pic14_emitcode("movx","a,@%s",rname);
7747         break;
7748         
7749     case FPOINTER:
7750         pic14_emitcode("movx","a,@dptr");
7751         break;
7752
7753     case CPOINTER:
7754         pic14_emitcode("clr","a");
7755         pic14_emitcode("movc","a","@a+dptr");
7756         break;
7757
7758     case GPOINTER:
7759         pic14_emitcode("lcall","__gptrget");
7760         break;
7761     }
7762
7763     /* if we have bitdisplacement then it fits   */
7764     /* into this byte completely or if length is */
7765     /* less than a byte                          */
7766     if ((shCnt = SPEC_BSTR(etype)) || 
7767         (SPEC_BLEN(etype) <= 8))  {
7768
7769         /* shift right acc */
7770         AccRsh(shCnt);
7771
7772         pic14_emitcode("anl","a,#0x%02x",
7773                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7774         aopPut(AOP(result),"a",offset);
7775         return ;
7776     }
7777
7778     /* bit field did not fit in a byte  */
7779     rlen = SPEC_BLEN(etype) - 8;
7780     aopPut(AOP(result),"a",offset++);
7781
7782     while (1)  {
7783
7784         switch (ptype) {
7785         case POINTER:
7786         case IPOINTER:
7787             pic14_emitcode("inc","%s",rname);
7788             pic14_emitcode("mov","a,@%s",rname);
7789             break;
7790             
7791         case PPOINTER:
7792             pic14_emitcode("inc","%s",rname);
7793             pic14_emitcode("movx","a,@%s",rname);
7794             break;
7795
7796         case FPOINTER:
7797             pic14_emitcode("inc","dptr");
7798             pic14_emitcode("movx","a,@dptr");
7799             break;
7800             
7801         case CPOINTER:
7802             pic14_emitcode("clr","a");
7803             pic14_emitcode("inc","dptr");
7804             pic14_emitcode("movc","a","@a+dptr");
7805             break;
7806             
7807         case GPOINTER:
7808             pic14_emitcode("inc","dptr");
7809             pic14_emitcode("lcall","__gptrget");
7810             break;
7811         }
7812
7813         rlen -= 8;            
7814         /* if we are done */
7815         if ( rlen <= 0 )
7816             break ;
7817         
7818         aopPut(AOP(result),"a",offset++);
7819                               
7820     }
7821     
7822     if (rlen) {
7823         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7824         aopPut(AOP(result),"a",offset);        
7825     }
7826     
7827     return ;
7828 }
7829
7830
7831 /*-----------------------------------------------------------------*/
7832 /* genDataPointerGet - generates code when ptr offset is known     */
7833 /*-----------------------------------------------------------------*/
7834 static void genDataPointerGet (operand *left, 
7835                                operand *result, 
7836                                iCode *ic)
7837 {
7838   int size , offset = 0;
7839
7840
7841   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7842
7843
7844   /* optimization - most of the time, left and result are the same
7845    * address, but different types. for the pic code, we could omit
7846    * the following
7847    */
7848
7849   aopOp(result,ic,TRUE);
7850
7851   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7852
7853   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7854
7855   size = AOP_SIZE(result);
7856
7857   while (size--) {
7858     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7859     offset++;
7860   }
7861
7862   freeAsmop(left,NULL,ic,TRUE);
7863   freeAsmop(result,NULL,ic,TRUE);
7864 }
7865
7866 /*-----------------------------------------------------------------*/
7867 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7868 /*-----------------------------------------------------------------*/
7869 static void genNearPointerGet (operand *left, 
7870                                operand *result, 
7871                                iCode *ic)
7872 {
7873     asmop *aop = NULL;
7874     regs *preg = NULL ;
7875     char *rname ;
7876     sym_link *rtype, *retype;
7877     sym_link *ltype = operandType(left);    
7878     char buffer[80];
7879
7880     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7881
7882     rtype = operandType(result);
7883     retype= getSpec(rtype);
7884     
7885     aopOp(left,ic,FALSE);
7886     
7887     /* if left is rematerialisable and
7888        result is not bit variable type and
7889        the left is pointer to data space i.e
7890        lower 128 bytes of space */
7891     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7892         !IS_BITVAR(retype)         &&
7893         DCL_TYPE(ltype) == POINTER) {
7894       //genDataPointerGet (left,result,ic);
7895         return ;
7896     }
7897     
7898     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7899
7900         /* if the value is already in a pointer register
7901        then don't need anything more */
7902     if (!AOP_INPREG(AOP(left))) {
7903         /* otherwise get a free pointer register */
7904     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7905 /*
7906         aop = newAsmop(0);
7907         preg = getFreePtr(ic,&aop,FALSE);
7908         pic14_emitcode("mov","%s,%s",
7909                 preg->name,
7910                 aopGet(AOP(left),0,FALSE,TRUE));
7911         rname = preg->name ;
7912 */
7913     rname ="BAD";
7914     } else
7915         rname = aopGet(AOP(left),0,FALSE,FALSE);
7916     
7917     aopOp (result,ic,FALSE);
7918     
7919       /* if bitfield then unpack the bits */
7920     if (IS_BITVAR(retype)) 
7921         genUnpackBits (result,rname,POINTER);
7922     else {
7923         /* we have can just get the values */
7924       int size = AOP_SIZE(result);
7925       int offset = 0 ;  
7926         
7927       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7928
7929       emitpcode(POC_MOVFW,popGet(AOP(left),0));
7930       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7931       while(size--) {
7932         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7933         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7934         if(size)
7935           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7936       }
7937 /*
7938         while (size--) {
7939             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7940
7941                 pic14_emitcode("mov","a,@%s",rname);
7942                 aopPut(AOP(result),"a",offset);
7943             } else {
7944                 sprintf(buffer,"@%s",rname);
7945                 aopPut(AOP(result),buffer,offset);
7946             }
7947             offset++ ;
7948             if (size)
7949                 pic14_emitcode("inc","%s",rname);
7950         }
7951 */
7952     }
7953
7954     /* now some housekeeping stuff */
7955     if (aop) {
7956         /* we had to allocate for this iCode */
7957     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7958         freeAsmop(NULL,aop,ic,TRUE);
7959     } else { 
7960         /* we did not allocate which means left
7961            already in a pointer register, then
7962            if size > 0 && this could be used again
7963            we have to point it back to where it 
7964            belongs */
7965     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7966         if (AOP_SIZE(result) > 1 &&
7967             !OP_SYMBOL(left)->remat &&
7968             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7969               ic->depth )) {
7970             int size = AOP_SIZE(result) - 1;
7971             while (size--)
7972                 pic14_emitcode("dec","%s",rname);
7973         }
7974     }
7975
7976     /* done */
7977     freeAsmop(left,NULL,ic,TRUE);
7978     freeAsmop(result,NULL,ic,TRUE);
7979      
7980 }
7981
7982 /*-----------------------------------------------------------------*/
7983 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7984 /*-----------------------------------------------------------------*/
7985 static void genPagedPointerGet (operand *left, 
7986                                operand *result, 
7987                                iCode *ic)
7988 {
7989     asmop *aop = NULL;
7990     regs *preg = NULL ;
7991     char *rname ;
7992     sym_link *rtype, *retype;    
7993
7994     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7995
7996     rtype = operandType(result);
7997     retype= getSpec(rtype);
7998     
7999     aopOp(left,ic,FALSE);
8000
8001   /* if the value is already in a pointer register
8002        then don't need anything more */
8003     if (!AOP_INPREG(AOP(left))) {
8004         /* otherwise get a free pointer register */
8005         aop = newAsmop(0);
8006         preg = getFreePtr(ic,&aop,FALSE);
8007         pic14_emitcode("mov","%s,%s",
8008                 preg->name,
8009                 aopGet(AOP(left),0,FALSE,TRUE));
8010         rname = preg->name ;
8011     } else
8012         rname = aopGet(AOP(left),0,FALSE,FALSE);
8013     
8014     freeAsmop(left,NULL,ic,TRUE);
8015     aopOp (result,ic,FALSE);
8016
8017     /* if bitfield then unpack the bits */
8018     if (IS_BITVAR(retype)) 
8019         genUnpackBits (result,rname,PPOINTER);
8020     else {
8021         /* we have can just get the values */
8022         int size = AOP_SIZE(result);
8023         int offset = 0 ;        
8024         
8025         while (size--) {
8026             
8027             pic14_emitcode("movx","a,@%s",rname);
8028             aopPut(AOP(result),"a",offset);
8029             
8030             offset++ ;
8031             
8032             if (size)
8033                 pic14_emitcode("inc","%s",rname);
8034         }
8035     }
8036
8037     /* now some housekeeping stuff */
8038     if (aop) {
8039         /* we had to allocate for this iCode */
8040         freeAsmop(NULL,aop,ic,TRUE);
8041     } else { 
8042         /* we did not allocate which means left
8043            already in a pointer register, then
8044            if size > 0 && this could be used again
8045            we have to point it back to where it 
8046            belongs */
8047         if (AOP_SIZE(result) > 1 &&
8048             !OP_SYMBOL(left)->remat &&
8049             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8050               ic->depth )) {
8051             int size = AOP_SIZE(result) - 1;
8052             while (size--)
8053                 pic14_emitcode("dec","%s",rname);
8054         }
8055     }
8056
8057     /* done */
8058     freeAsmop(result,NULL,ic,TRUE);
8059     
8060         
8061 }
8062
8063 /*-----------------------------------------------------------------*/
8064 /* genFarPointerGet - gget value from far space                    */
8065 /*-----------------------------------------------------------------*/
8066 static void genFarPointerGet (operand *left,
8067                               operand *result, iCode *ic)
8068 {
8069     int size, offset ;
8070     sym_link *retype = getSpec(operandType(result));
8071
8072     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8073
8074     aopOp(left,ic,FALSE);
8075
8076     /* if the operand is already in dptr 
8077     then we do nothing else we move the value to dptr */
8078     if (AOP_TYPE(left) != AOP_STR) {
8079         /* if this is remateriazable */
8080         if (AOP_TYPE(left) == AOP_IMMD)
8081             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8082         else { /* we need to get it byte by byte */
8083             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8084             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8085             if (options.model == MODEL_FLAT24)
8086             {
8087                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8088             }
8089         }
8090     }
8091     /* so dptr know contains the address */
8092     freeAsmop(left,NULL,ic,TRUE);
8093     aopOp(result,ic,FALSE);
8094
8095     /* if bit then unpack */
8096     if (IS_BITVAR(retype)) 
8097         genUnpackBits(result,"dptr",FPOINTER);
8098     else {
8099         size = AOP_SIZE(result);
8100         offset = 0 ;
8101
8102         while (size--) {
8103             pic14_emitcode("movx","a,@dptr");
8104             aopPut(AOP(result),"a",offset++);
8105             if (size)
8106                 pic14_emitcode("inc","dptr");
8107         }
8108     }
8109
8110     freeAsmop(result,NULL,ic,TRUE);
8111 }
8112 #if 0
8113 /*-----------------------------------------------------------------*/
8114 /* genCodePointerGet - get value from code space                  */
8115 /*-----------------------------------------------------------------*/
8116 static void genCodePointerGet (operand *left,
8117                                 operand *result, iCode *ic)
8118 {
8119     int size, offset ;
8120     sym_link *retype = getSpec(operandType(result));
8121
8122     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8123
8124     aopOp(left,ic,FALSE);
8125
8126     /* if the operand is already in dptr 
8127     then we do nothing else we move the value to dptr */
8128     if (AOP_TYPE(left) != AOP_STR) {
8129         /* if this is remateriazable */
8130         if (AOP_TYPE(left) == AOP_IMMD)
8131             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8132         else { /* we need to get it byte by byte */
8133             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8134             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8135             if (options.model == MODEL_FLAT24)
8136             {
8137                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8138             }
8139         }
8140     }
8141     /* so dptr know contains the address */
8142     freeAsmop(left,NULL,ic,TRUE);
8143     aopOp(result,ic,FALSE);
8144
8145     /* if bit then unpack */
8146     if (IS_BITVAR(retype)) 
8147         genUnpackBits(result,"dptr",CPOINTER);
8148     else {
8149         size = AOP_SIZE(result);
8150         offset = 0 ;
8151
8152         while (size--) {
8153             pic14_emitcode("clr","a");
8154             pic14_emitcode("movc","a,@a+dptr");
8155             aopPut(AOP(result),"a",offset++);
8156             if (size)
8157                 pic14_emitcode("inc","dptr");
8158         }
8159     }
8160
8161     freeAsmop(result,NULL,ic,TRUE);
8162 }
8163 #endif
8164 /*-----------------------------------------------------------------*/
8165 /* genGenPointerGet - gget value from generic pointer space        */
8166 /*-----------------------------------------------------------------*/
8167 static void genGenPointerGet (operand *left,
8168                               operand *result, iCode *ic)
8169 {
8170   int size, offset ;
8171   sym_link *retype = getSpec(operandType(result));
8172
8173   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8174   aopOp(left,ic,FALSE);
8175   aopOp(result,ic,FALSE);
8176
8177
8178   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8179
8180   /* if the operand is already in dptr 
8181      then we do nothing else we move the value to dptr */
8182   //  if (AOP_TYPE(left) != AOP_STR) {
8183     /* if this is remateriazable */
8184     if (AOP_TYPE(left) == AOP_IMMD) {
8185       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8186       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8187     }
8188     else { /* we need to get it byte by byte */
8189
8190       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8191       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8192
8193       size = AOP_SIZE(result);
8194       offset = 0 ;
8195
8196       while(size--) {
8197         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8198         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8199         if(size)
8200           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8201       }
8202       goto release;
8203     }
8204     //}
8205   /* so dptr know contains the address */
8206
8207   /* if bit then unpack */
8208   //if (IS_BITVAR(retype)) 
8209   //  genUnpackBits(result,"dptr",GPOINTER);
8210
8211  release:
8212   freeAsmop(left,NULL,ic,TRUE);
8213   freeAsmop(result,NULL,ic,TRUE);
8214
8215 }
8216
8217 /*-----------------------------------------------------------------*/
8218 /* genConstPointerGet - get value from const generic pointer space */
8219 /*-----------------------------------------------------------------*/
8220 static void genConstPointerGet (operand *left,
8221                                 operand *result, iCode *ic)
8222 {
8223   //sym_link *retype = getSpec(operandType(result));
8224   symbol *albl = newiTempLabel(NULL);
8225   symbol *blbl = newiTempLabel(NULL);
8226   PIC_OPCODE poc;
8227
8228   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8229   aopOp(left,ic,FALSE);
8230   aopOp(result,ic,FALSE);
8231
8232
8233   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8234
8235   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8236
8237   emitpcode(POC_CALL,popGetLabel(albl->key));
8238   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8239   emitpLabel(albl->key);
8240
8241   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8242     
8243   emitpcode(poc,popGet(AOP(left),1));
8244   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8245   emitpcode(poc,popGet(AOP(left),0));
8246   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8247
8248   emitpLabel(blbl->key);
8249
8250   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8251
8252
8253   freeAsmop(left,NULL,ic,TRUE);
8254   freeAsmop(result,NULL,ic,TRUE);
8255
8256 }
8257 /*-----------------------------------------------------------------*/
8258 /* genPointerGet - generate code for pointer get                   */
8259 /*-----------------------------------------------------------------*/
8260 static void genPointerGet (iCode *ic)
8261 {
8262     operand *left, *result ;
8263     sym_link *type, *etype;
8264     int p_type;
8265
8266     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8267
8268     left = IC_LEFT(ic);
8269     result = IC_RESULT(ic) ;
8270
8271     /* depending on the type of pointer we need to
8272     move it to the correct pointer register */
8273     type = operandType(left);
8274     etype = getSpec(type);
8275
8276     if (IS_PTR_CONST(type))
8277       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8278
8279     /* if left is of type of pointer then it is simple */
8280     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8281         p_type = DCL_TYPE(type);
8282     else {
8283         /* we have to go by the storage class */
8284         p_type = PTR_TYPE(SPEC_OCLS(etype));
8285
8286         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8287
8288         if (SPEC_OCLS(etype)->codesp ) {
8289           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8290           //p_type = CPOINTER ; 
8291         }
8292         else
8293             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8294               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8295                /*p_type = FPOINTER ;*/ 
8296             else
8297                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8298                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8299 /*                  p_type = PPOINTER; */
8300                 else
8301                     if (SPEC_OCLS(etype) == idata )
8302                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8303 /*                      p_type = IPOINTER; */
8304                     else
8305                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8306 /*                      p_type = POINTER ; */
8307     }
8308
8309     /* now that we have the pointer type we assign
8310     the pointer values */
8311     switch (p_type) {
8312
8313     case POINTER:       
8314     case IPOINTER:
8315         genNearPointerGet (left,result,ic);
8316         break;
8317
8318     case PPOINTER:
8319         genPagedPointerGet(left,result,ic);
8320         break;
8321
8322     case FPOINTER:
8323         genFarPointerGet (left,result,ic);
8324         break;
8325
8326     case CPOINTER:
8327         genConstPointerGet (left,result,ic);
8328         //pic14_emitcodePointerGet (left,result,ic);
8329         break;
8330
8331     case GPOINTER:
8332       if (IS_PTR_CONST(type))
8333         genConstPointerGet (left,result,ic);
8334       else
8335         genGenPointerGet (left,result,ic);
8336       break;
8337     }
8338
8339 }
8340
8341 /*-----------------------------------------------------------------*/
8342 /* genPackBits - generates code for packed bit storage             */
8343 /*-----------------------------------------------------------------*/
8344 static void genPackBits (sym_link    *etype ,
8345                          operand *right ,
8346                          char *rname, int p_type)
8347 {
8348     int shCount = 0 ;
8349     int offset = 0  ;
8350     int rLen = 0 ;
8351     int blen, bstr ;   
8352     char *l ;
8353
8354     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8355     blen = SPEC_BLEN(etype);
8356     bstr = SPEC_BSTR(etype);
8357
8358     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8359     MOVA(l);   
8360
8361     /* if the bit lenth is less than or    */
8362     /* it exactly fits a byte then         */
8363     if (SPEC_BLEN(etype) <= 8 )  {
8364         shCount = SPEC_BSTR(etype) ;
8365
8366         /* shift left acc */
8367         AccLsh(shCount);
8368
8369         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8370
8371
8372             switch (p_type) {
8373                 case POINTER:
8374                     pic14_emitcode ("mov","b,a");
8375                     pic14_emitcode("mov","a,@%s",rname);
8376                     break;
8377
8378                 case FPOINTER:
8379                     pic14_emitcode ("mov","b,a");
8380                     pic14_emitcode("movx","a,@dptr");
8381                     break;
8382
8383                 case GPOINTER:
8384                     pic14_emitcode ("push","b");
8385                     pic14_emitcode ("push","acc");
8386                     pic14_emitcode ("lcall","__gptrget");
8387                     pic14_emitcode ("pop","b");
8388                     break;
8389             }
8390
8391             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8392                       ((unsigned char)(0xFF << (blen+bstr)) | 
8393                        (unsigned char)(0xFF >> (8-bstr)) ) );
8394             pic14_emitcode ("orl","a,b");
8395             if (p_type == GPOINTER)
8396                 pic14_emitcode("pop","b");
8397         }
8398     }
8399
8400     switch (p_type) {
8401         case POINTER:
8402             pic14_emitcode("mov","@%s,a",rname);
8403             break;
8404
8405         case FPOINTER:
8406             pic14_emitcode("movx","@dptr,a");
8407             break;
8408
8409         case GPOINTER:
8410             DEBUGpic14_emitcode(";lcall","__gptrput");
8411             break;
8412     }
8413
8414     /* if we r done */
8415     if ( SPEC_BLEN(etype) <= 8 )
8416         return ;
8417
8418     pic14_emitcode("inc","%s",rname);
8419     rLen = SPEC_BLEN(etype) ;     
8420
8421     /* now generate for lengths greater than one byte */
8422     while (1) {
8423
8424         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8425
8426         rLen -= 8 ;
8427         if (rLen <= 0 )
8428             break ;
8429
8430         switch (p_type) {
8431             case POINTER:
8432                 if (*l == '@') {
8433                     MOVA(l);
8434                     pic14_emitcode("mov","@%s,a",rname);
8435                 } else
8436                     pic14_emitcode("mov","@%s,%s",rname,l);
8437                 break;
8438
8439             case FPOINTER:
8440                 MOVA(l);
8441                 pic14_emitcode("movx","@dptr,a");
8442                 break;
8443
8444             case GPOINTER:
8445                 MOVA(l);
8446                 DEBUGpic14_emitcode(";lcall","__gptrput");
8447                 break;  
8448         }   
8449         pic14_emitcode ("inc","%s",rname);
8450     }
8451
8452     MOVA(l);
8453
8454     /* last last was not complete */
8455     if (rLen)   {
8456         /* save the byte & read byte */
8457         switch (p_type) {
8458             case POINTER:
8459                 pic14_emitcode ("mov","b,a");
8460                 pic14_emitcode("mov","a,@%s",rname);
8461                 break;
8462
8463             case FPOINTER:
8464                 pic14_emitcode ("mov","b,a");
8465                 pic14_emitcode("movx","a,@dptr");
8466                 break;
8467
8468             case GPOINTER:
8469                 pic14_emitcode ("push","b");
8470                 pic14_emitcode ("push","acc");
8471                 pic14_emitcode ("lcall","__gptrget");
8472                 pic14_emitcode ("pop","b");
8473                 break;
8474         }
8475
8476         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8477         pic14_emitcode ("orl","a,b");
8478     }
8479
8480     if (p_type == GPOINTER)
8481         pic14_emitcode("pop","b");
8482
8483     switch (p_type) {
8484
8485     case POINTER:
8486         pic14_emitcode("mov","@%s,a",rname);
8487         break;
8488         
8489     case FPOINTER:
8490         pic14_emitcode("movx","@dptr,a");
8491         break;
8492         
8493     case GPOINTER:
8494         DEBUGpic14_emitcode(";lcall","__gptrput");
8495         break;                  
8496     }
8497 }
8498 /*-----------------------------------------------------------------*/
8499 /* genDataPointerSet - remat pointer to data space                 */
8500 /*-----------------------------------------------------------------*/
8501 static void genDataPointerSet(operand *right,
8502                               operand *result,
8503                               iCode *ic)
8504 {
8505     int size, offset = 0 ;
8506     char *l, buffer[256];
8507
8508     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8509     aopOp(right,ic,FALSE);
8510     
8511     l = aopGet(AOP(result),0,FALSE,TRUE);
8512     size = AOP_SIZE(right);
8513 /*
8514     if ( AOP_TYPE(result) == AOP_PCODE) {
8515       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8516               AOP(result)->aopu.pcop->name,
8517               PCOI(AOP(result)->aopu.pcop)->offset);
8518     }
8519 */
8520
8521     // tsd, was l+1 - the underline `_' prefix was being stripped
8522     while (size--) {
8523       if (offset) {
8524         sprintf(buffer,"(%s + %d)",l,offset);
8525         fprintf(stderr,"oops  %s\n",buffer);
8526       } else
8527         sprintf(buffer,"%s",l);
8528
8529         if (AOP_TYPE(right) == AOP_LIT) {
8530           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8531           lit = lit >> (8*offset);
8532           if(lit&0xff) {
8533             pic14_emitcode("movlw","%d",lit);
8534             pic14_emitcode("movwf","%s",buffer);
8535
8536             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8537             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8538             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8539
8540           } else {
8541             pic14_emitcode("clrf","%s",buffer);
8542             //emitpcode(POC_CLRF, popRegFromString(buffer));
8543             emitpcode(POC_CLRF, popGet(AOP(result),0));
8544           }
8545         }else {
8546           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8547           pic14_emitcode("movwf","%s",buffer);
8548
8549           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8550           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8551           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8552
8553         }
8554
8555         offset++;
8556     }
8557
8558     freeAsmop(right,NULL,ic,TRUE);
8559     freeAsmop(result,NULL,ic,TRUE);
8560 }
8561
8562 /*-----------------------------------------------------------------*/
8563 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8564 /*-----------------------------------------------------------------*/
8565 static void genNearPointerSet (operand *right,
8566                                operand *result, 
8567                                iCode *ic)
8568 {
8569   asmop *aop = NULL;
8570   char *l;
8571   sym_link *retype;
8572   sym_link *ptype = operandType(result);
8573
8574     
8575   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8576   retype= getSpec(operandType(right));
8577
8578   aopOp(result,ic,FALSE);
8579
8580     
8581   /* if the result is rematerializable &
8582      in data space & not a bit variable */
8583   //if (AOP_TYPE(result) == AOP_IMMD &&
8584   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8585       DCL_TYPE(ptype) == POINTER   &&
8586       !IS_BITVAR(retype)) {
8587     genDataPointerSet (right,result,ic);
8588     freeAsmop(result,NULL,ic,TRUE);
8589     return;
8590   }
8591
8592   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8593   aopOp(right,ic,FALSE);
8594   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8595
8596   /* if the value is already in a pointer register
8597      then don't need anything more */
8598   if (!AOP_INPREG(AOP(result))) {
8599     /* otherwise get a free pointer register */
8600     //aop = newAsmop(0);
8601     //preg = getFreePtr(ic,&aop,FALSE);
8602     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8603     //pic14_emitcode("mov","%s,%s",
8604     //         preg->name,
8605     //         aopGet(AOP(result),0,FALSE,TRUE));
8606     //rname = preg->name ;
8607     //pic14_emitcode("movwf","fsr");
8608     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8609     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8610     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8611     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8612     goto release;
8613
8614   }// else
8615   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8616
8617
8618   /* if bitfield then unpack the bits */
8619   if (IS_BITVAR(retype)) {
8620     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8621            "The programmer is obviously confused");
8622     //genPackBits (retype,right,rname,POINTER);
8623     exit(1);
8624   }
8625   else {
8626     /* we have can just get the values */
8627     int size = AOP_SIZE(right);
8628     int offset = 0 ;    
8629
8630     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8631     while (size--) {
8632       l = aopGet(AOP(right),offset,FALSE,TRUE);
8633       if (*l == '@' ) {
8634         //MOVA(l);
8635         //pic14_emitcode("mov","@%s,a",rname);
8636         pic14_emitcode("movf","indf,w ;1");
8637       } else {
8638
8639         if (AOP_TYPE(right) == AOP_LIT) {
8640           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8641           if(lit) {
8642             pic14_emitcode("movlw","%s",l);
8643             pic14_emitcode("movwf","indf ;2");
8644           } else 
8645             pic14_emitcode("clrf","indf");
8646         }else {
8647           pic14_emitcode("movf","%s,w",l);
8648           pic14_emitcode("movwf","indf ;2");
8649         }
8650         //pic14_emitcode("mov","@%s,%s",rname,l);
8651       }
8652       if (size)
8653         pic14_emitcode("incf","fsr,f ;3");
8654       //pic14_emitcode("inc","%s",rname);
8655       offset++;
8656     }
8657   }
8658
8659   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8660   /* now some housekeeping stuff */
8661   if (aop) {
8662     /* we had to allocate for this iCode */
8663     freeAsmop(NULL,aop,ic,TRUE);
8664   } else { 
8665     /* we did not allocate which means left
8666        already in a pointer register, then
8667        if size > 0 && this could be used again
8668        we have to point it back to where it 
8669        belongs */
8670     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8671     if (AOP_SIZE(right) > 1 &&
8672         !OP_SYMBOL(result)->remat &&
8673         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8674           ic->depth )) {
8675       int size = AOP_SIZE(right) - 1;
8676       while (size--)
8677         pic14_emitcode("decf","fsr,f");
8678       //pic14_emitcode("dec","%s",rname);
8679     }
8680   }
8681
8682   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8683   /* done */
8684  release:
8685   freeAsmop(right,NULL,ic,TRUE);
8686   freeAsmop(result,NULL,ic,TRUE);
8687 }
8688
8689 /*-----------------------------------------------------------------*/
8690 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8691 /*-----------------------------------------------------------------*/
8692 static void genPagedPointerSet (operand *right,
8693                                operand *result, 
8694                                iCode *ic)
8695 {
8696     asmop *aop = NULL;
8697     regs *preg = NULL ;
8698     char *rname , *l;
8699     sym_link *retype;
8700        
8701     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8702
8703     retype= getSpec(operandType(right));
8704     
8705     aopOp(result,ic,FALSE);
8706     
8707     /* if the value is already in a pointer register
8708        then don't need anything more */
8709     if (!AOP_INPREG(AOP(result))) {
8710         /* otherwise get a free pointer register */
8711         aop = newAsmop(0);
8712         preg = getFreePtr(ic,&aop,FALSE);
8713         pic14_emitcode("mov","%s,%s",
8714                 preg->name,
8715                 aopGet(AOP(result),0,FALSE,TRUE));
8716         rname = preg->name ;
8717     } else
8718         rname = aopGet(AOP(result),0,FALSE,FALSE);
8719     
8720     freeAsmop(result,NULL,ic,TRUE);
8721     aopOp (right,ic,FALSE);
8722
8723     /* if bitfield then unpack the bits */
8724     if (IS_BITVAR(retype)) 
8725         genPackBits (retype,right,rname,PPOINTER);
8726     else {
8727         /* we have can just get the values */
8728         int size = AOP_SIZE(right);
8729         int offset = 0 ;        
8730         
8731         while (size--) {
8732             l = aopGet(AOP(right),offset,FALSE,TRUE);
8733             
8734             MOVA(l);
8735             pic14_emitcode("movx","@%s,a",rname);
8736
8737             if (size)
8738                 pic14_emitcode("inc","%s",rname);
8739
8740             offset++;
8741         }
8742     }
8743     
8744     /* now some housekeeping stuff */
8745     if (aop) {
8746         /* we had to allocate for this iCode */
8747         freeAsmop(NULL,aop,ic,TRUE);
8748     } else { 
8749         /* we did not allocate which means left
8750            already in a pointer register, then
8751            if size > 0 && this could be used again
8752            we have to point it back to where it 
8753            belongs */
8754         if (AOP_SIZE(right) > 1 &&
8755             !OP_SYMBOL(result)->remat &&
8756             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8757               ic->depth )) {
8758             int size = AOP_SIZE(right) - 1;
8759             while (size--)
8760                 pic14_emitcode("dec","%s",rname);
8761         }
8762     }
8763
8764     /* done */
8765     freeAsmop(right,NULL,ic,TRUE);
8766     
8767         
8768 }
8769
8770 /*-----------------------------------------------------------------*/
8771 /* genFarPointerSet - set value from far space                     */
8772 /*-----------------------------------------------------------------*/
8773 static void genFarPointerSet (operand *right,
8774                               operand *result, iCode *ic)
8775 {
8776     int size, offset ;
8777     sym_link *retype = getSpec(operandType(right));
8778
8779     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8780     aopOp(result,ic,FALSE);
8781
8782     /* if the operand is already in dptr 
8783     then we do nothing else we move the value to dptr */
8784     if (AOP_TYPE(result) != AOP_STR) {
8785         /* if this is remateriazable */
8786         if (AOP_TYPE(result) == AOP_IMMD)
8787             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8788         else { /* we need to get it byte by byte */
8789             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8790             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8791             if (options.model == MODEL_FLAT24)
8792             {
8793                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8794             }
8795         }
8796     }
8797     /* so dptr know contains the address */
8798     freeAsmop(result,NULL,ic,TRUE);
8799     aopOp(right,ic,FALSE);
8800
8801     /* if bit then unpack */
8802     if (IS_BITVAR(retype)) 
8803         genPackBits(retype,right,"dptr",FPOINTER);
8804     else {
8805         size = AOP_SIZE(right);
8806         offset = 0 ;
8807
8808         while (size--) {
8809             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8810             MOVA(l);
8811             pic14_emitcode("movx","@dptr,a");
8812             if (size)
8813                 pic14_emitcode("inc","dptr");
8814         }
8815     }
8816
8817     freeAsmop(right,NULL,ic,TRUE);
8818 }
8819
8820 /*-----------------------------------------------------------------*/
8821 /* genGenPointerSet - set value from generic pointer space         */
8822 /*-----------------------------------------------------------------*/
8823 static void genGenPointerSet (operand *right,
8824                               operand *result, iCode *ic)
8825 {
8826   int size, offset ;
8827   sym_link *retype = getSpec(operandType(right));
8828
8829   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8830
8831   aopOp(result,ic,FALSE);
8832   aopOp(right,ic,FALSE);
8833   size = AOP_SIZE(right);
8834
8835   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8836
8837   /* if the operand is already in dptr 
8838      then we do nothing else we move the value to dptr */
8839   if (AOP_TYPE(result) != AOP_STR) {
8840     /* if this is remateriazable */
8841     if (AOP_TYPE(result) == AOP_IMMD) {
8842       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8843       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8844     }
8845     else { /* we need to get it byte by byte */
8846       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8847       size = AOP_SIZE(right);
8848       offset = 0 ;
8849
8850       /* hack hack! see if this the FSR. If so don't load W */
8851       if(AOP_TYPE(right) != AOP_ACC) {
8852
8853         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8854         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8855
8856         //if(size==2)
8857         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8858         //if(size==4) {
8859         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8860         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8861         //}
8862
8863         while(size--) {
8864           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8865           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8866           
8867           if(size)
8868             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8869         }
8870
8871
8872         goto release;
8873       } 
8874
8875       if(aopIdx(AOP(result),0) != 4) {
8876
8877         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8878         goto release;
8879       }
8880
8881       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8882       goto release;
8883
8884     }
8885   }
8886   /* so dptr know contains the address */
8887
8888
8889   /* if bit then unpack */
8890   if (IS_BITVAR(retype)) 
8891     genPackBits(retype,right,"dptr",GPOINTER);
8892   else {
8893     size = AOP_SIZE(right);
8894     offset = 0 ;
8895
8896     while (--size) {
8897       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8898       if(size)
8899         pic14_emitcode("incf","fsr,f");
8900       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8901       pic14_emitcode("movwf","indf");
8902       //MOVA(l);
8903       //DEBUGpic14_emitcode(";lcall","__gptrput");
8904       //if (size)
8905       //    pic14_emitcode("inc","dptr");
8906     }
8907   }
8908
8909  release:
8910   freeAsmop(right,NULL,ic,TRUE);
8911   freeAsmop(result,NULL,ic,TRUE);
8912 }
8913
8914 /*-----------------------------------------------------------------*/
8915 /* genPointerSet - stores the value into a pointer location        */
8916 /*-----------------------------------------------------------------*/
8917 static void genPointerSet (iCode *ic)
8918 {    
8919     operand *right, *result ;
8920     sym_link *type, *etype;
8921     int p_type;
8922
8923     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8924
8925     right = IC_RIGHT(ic);
8926     result = IC_RESULT(ic) ;
8927
8928     /* depending on the type of pointer we need to
8929     move it to the correct pointer register */
8930     type = operandType(result);
8931     etype = getSpec(type);
8932     /* if left is of type of pointer then it is simple */
8933     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8934         p_type = DCL_TYPE(type);
8935     }
8936     else {
8937         /* we have to go by the storage class */
8938         p_type = PTR_TYPE(SPEC_OCLS(etype));
8939
8940 /*      if (SPEC_OCLS(etype)->codesp ) { */
8941 /*          p_type = CPOINTER ;  */
8942 /*      } */
8943 /*      else */
8944 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8945 /*              p_type = FPOINTER ; */
8946 /*          else */
8947 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8948 /*                  p_type = PPOINTER ; */
8949 /*              else */
8950 /*                  if (SPEC_OCLS(etype) == idata ) */
8951 /*                      p_type = IPOINTER ; */
8952 /*                  else */
8953 /*                      p_type = POINTER ; */
8954     }
8955
8956     /* now that we have the pointer type we assign
8957     the pointer values */
8958     switch (p_type) {
8959
8960     case POINTER:
8961     case IPOINTER:
8962         genNearPointerSet (right,result,ic);
8963         break;
8964
8965     case PPOINTER:
8966         genPagedPointerSet (right,result,ic);
8967         break;
8968
8969     case FPOINTER:
8970         genFarPointerSet (right,result,ic);
8971         break;
8972
8973     case GPOINTER:
8974         genGenPointerSet (right,result,ic);
8975         break;
8976
8977     default:
8978       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
8979               "genPointerSet: illegal pointer type");
8980     }
8981 }
8982
8983 /*-----------------------------------------------------------------*/
8984 /* genIfx - generate code for Ifx statement                        */
8985 /*-----------------------------------------------------------------*/
8986 static void genIfx (iCode *ic, iCode *popIc)
8987 {
8988   operand *cond = IC_COND(ic);
8989   int isbit =0;
8990
8991   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8992
8993   aopOp(cond,ic,FALSE);
8994
8995   /* get the value into acc */
8996   if (AOP_TYPE(cond) != AOP_CRY)
8997     pic14_toBoolean(cond);
8998   else
8999     isbit = 1;
9000   /* the result is now in the accumulator */
9001   freeAsmop(cond,NULL,ic,TRUE);
9002
9003   /* if there was something to be popped then do it */
9004   if (popIc)
9005     genIpop(popIc);
9006
9007   /* if the condition is  a bit variable */
9008   if (isbit && IS_ITEMP(cond) && 
9009       SPIL_LOC(cond)) {
9010     genIfxJump(ic,SPIL_LOC(cond)->rname);
9011     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9012   }
9013   else {
9014     if (isbit && !IS_ITEMP(cond))
9015       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9016     else
9017       genIfxJump(ic,"a");
9018   }
9019   ic->generated = 1;
9020
9021 }
9022
9023 /*-----------------------------------------------------------------*/
9024 /* genAddrOf - generates code for address of                       */
9025 /*-----------------------------------------------------------------*/
9026 static void genAddrOf (iCode *ic)
9027 {
9028   operand *right, *result, *left;
9029   int size, offset ;
9030
9031   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9032
9033
9034   //aopOp(IC_RESULT(ic),ic,FALSE);
9035
9036   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9037   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9038   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9039
9040   DEBUGpic14_AopType(__LINE__,left,right,result);
9041
9042   size = AOP_SIZE(IC_RESULT(ic));
9043   offset = 0;
9044
9045   while (size--) {
9046     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9047     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9048     offset++;
9049   }
9050
9051   freeAsmop(left,NULL,ic,FALSE);
9052   freeAsmop(result,NULL,ic,TRUE);
9053
9054 }
9055
9056 #if 0
9057 /*-----------------------------------------------------------------*/
9058 /* genFarFarAssign - assignment when both are in far space         */
9059 /*-----------------------------------------------------------------*/
9060 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9061 {
9062     int size = AOP_SIZE(right);
9063     int offset = 0;
9064     char *l ;
9065     /* first push the right side on to the stack */
9066     while (size--) {
9067         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9068         MOVA(l);
9069         pic14_emitcode ("push","acc");
9070     }
9071     
9072     freeAsmop(right,NULL,ic,FALSE);
9073     /* now assign DPTR to result */
9074     aopOp(result,ic,FALSE);
9075     size = AOP_SIZE(result);
9076     while (size--) {
9077         pic14_emitcode ("pop","acc");
9078         aopPut(AOP(result),"a",--offset);
9079     }
9080     freeAsmop(result,NULL,ic,FALSE);
9081         
9082 }
9083 #endif
9084
9085 /*-----------------------------------------------------------------*/
9086 /* genAssign - generate code for assignment                        */
9087 /*-----------------------------------------------------------------*/
9088 static void genAssign (iCode *ic)
9089 {
9090   operand *result, *right;
9091   int size, offset,know_W;
9092   unsigned long lit = 0L;
9093
9094   result = IC_RESULT(ic);
9095   right  = IC_RIGHT(ic) ;
9096
9097   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9098
9099   /* if they are the same */
9100   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9101     return ;
9102
9103   aopOp(right,ic,FALSE);
9104   aopOp(result,ic,TRUE);
9105
9106   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9107
9108   /* if they are the same registers */
9109   if (pic14_sameRegs(AOP(right),AOP(result)))
9110     goto release;
9111
9112   /* if the result is a bit */
9113   if (AOP_TYPE(result) == AOP_CRY) {
9114
9115     /* if the right size is a literal then
9116        we know what the value is */
9117     if (AOP_TYPE(right) == AOP_LIT) {
9118           
9119       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9120                   popGet(AOP(result),0));
9121
9122       if (((int) operandLitValue(right))) 
9123         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9124                        AOP(result)->aopu.aop_dir,
9125                        AOP(result)->aopu.aop_dir);
9126       else
9127         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9128                        AOP(result)->aopu.aop_dir,
9129                        AOP(result)->aopu.aop_dir);
9130       goto release;
9131     }
9132
9133     /* the right is also a bit variable */
9134     if (AOP_TYPE(right) == AOP_CRY) {
9135       emitpcode(POC_BCF,    popGet(AOP(result),0));
9136       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9137       emitpcode(POC_BSF,    popGet(AOP(result),0));
9138
9139       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9140                      AOP(result)->aopu.aop_dir,
9141                      AOP(result)->aopu.aop_dir);
9142       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9143                      AOP(right)->aopu.aop_dir,
9144                      AOP(right)->aopu.aop_dir);
9145       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9146                      AOP(result)->aopu.aop_dir,
9147                      AOP(result)->aopu.aop_dir);
9148       goto release ;
9149     }
9150
9151     /* we need to or */
9152     emitpcode(POC_BCF,    popGet(AOP(result),0));
9153     pic14_toBoolean(right);
9154     emitSKPZ;
9155     emitpcode(POC_BSF,    popGet(AOP(result),0));
9156     //aopPut(AOP(result),"a",0);
9157     goto release ;
9158   }
9159
9160   /* bit variables done */
9161   /* general case */
9162   size = AOP_SIZE(result);
9163   offset = 0 ;
9164   if(AOP_TYPE(right) == AOP_LIT)
9165     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9166
9167   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9168   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9169     if(aopIdx(AOP(result),0) == 4) {
9170   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9171       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9172       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9173       goto release;
9174     } else
9175       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9176   }
9177
9178   know_W=-1;
9179   while (size--) {
9180   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9181     if(AOP_TYPE(right) == AOP_LIT) {
9182       if(lit&0xff) {
9183         if(know_W != (lit&0xff))
9184           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9185         know_W = lit&0xff;
9186         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9187       } else
9188         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9189
9190       lit >>= 8;
9191
9192     } else if (AOP_TYPE(right) == AOP_CRY) {
9193       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9194       if(offset == 0) {
9195         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9196         emitpcode(POC_INCF, popGet(AOP(result),0));
9197       }
9198     } else {
9199   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9200       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9201       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9202     }
9203             
9204     offset++;
9205   }
9206
9207     
9208  release:
9209   freeAsmop (right,NULL,ic,FALSE);
9210   freeAsmop (result,NULL,ic,TRUE);
9211 }   
9212
9213 /*-----------------------------------------------------------------*/
9214 /* genJumpTab - genrates code for jump table                       */
9215 /*-----------------------------------------------------------------*/
9216 static void genJumpTab (iCode *ic)
9217 {
9218     symbol *jtab;
9219     char *l;
9220
9221     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9222
9223     aopOp(IC_JTCOND(ic),ic,FALSE);
9224     /* get the condition into accumulator */
9225     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9226     MOVA(l);
9227     /* multiply by three */
9228     pic14_emitcode("add","a,acc");
9229     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9230
9231     jtab = newiTempLabel(NULL);
9232     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9233     pic14_emitcode("jmp","@a+dptr");
9234     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9235
9236     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9237     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9238     emitSKPNC;
9239     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9240     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9241     emitpLabel(jtab->key);
9242
9243     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9244
9245     /* now generate the jump labels */
9246     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9247          jtab = setNextItem(IC_JTLABELS(ic))) {
9248         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9249         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9250         
9251     }
9252
9253 }
9254
9255 /*-----------------------------------------------------------------*/
9256 /* genMixedOperation - gen code for operators between mixed types  */
9257 /*-----------------------------------------------------------------*/
9258 /*
9259   TSD - Written for the PIC port - but this unfortunately is buggy.
9260   This routine is good in that it is able to efficiently promote 
9261   types to different (larger) sizes. Unfortunately, the temporary
9262   variables that are optimized out by this routine are sometimes
9263   used in other places. So until I know how to really parse the 
9264   iCode tree, I'm going to not be using this routine :(.
9265 */
9266 static int genMixedOperation (iCode *ic)
9267 {
9268 #if 0
9269   operand *result = IC_RESULT(ic);
9270   sym_link *ctype = operandType(IC_LEFT(ic));
9271   operand *right = IC_RIGHT(ic);
9272   int ret = 0;
9273   int big,small;
9274   int offset;
9275
9276   iCode *nextic;
9277   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9278
9279   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9280
9281   nextic = ic->next;
9282   if(!nextic)
9283     return 0;
9284
9285   nextright = IC_RIGHT(nextic);
9286   nextleft  = IC_LEFT(nextic);
9287   nextresult = IC_RESULT(nextic);
9288
9289   aopOp(right,ic,FALSE);
9290   aopOp(result,ic,FALSE);
9291   aopOp(nextright,  nextic, FALSE);
9292   aopOp(nextleft,   nextic, FALSE);
9293   aopOp(nextresult, nextic, FALSE);
9294
9295   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9296
9297     operand *t = right;
9298     right = nextright;
9299     nextright = t; 
9300
9301     pic14_emitcode(";remove right +","");
9302
9303   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9304 /*
9305     operand *t = right;
9306     right = nextleft;
9307     nextleft = t; 
9308 */
9309     pic14_emitcode(";remove left +","");
9310   } else
9311     return 0;
9312
9313   big = AOP_SIZE(nextleft);
9314   small = AOP_SIZE(nextright);
9315
9316   switch(nextic->op) {
9317
9318   case '+':
9319     pic14_emitcode(";optimize a +","");
9320     /* if unsigned or not an integral type */
9321     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9322       pic14_emitcode(";add a bit to something","");
9323     } else {
9324
9325       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9326
9327       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9328         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9329         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9330       } else
9331         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9332
9333       offset = 0;
9334       while(--big) {
9335
9336         offset++;
9337
9338         if(--small) {
9339           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9340             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9341             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9342           }
9343
9344           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9345           emitSKPNC;
9346           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9347                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9348                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9349           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9350           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9351
9352         } else {
9353           pic14_emitcode("rlf","known_zero,w");
9354
9355           /*
9356             if right is signed
9357               btfsc  right,7
9358                addlw ff
9359           */
9360           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9361             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9362             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9363           } else {
9364             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9365           }
9366         }
9367       }
9368       ret = 1;
9369     }
9370   }
9371   ret = 1;
9372
9373 release:
9374   freeAsmop(right,NULL,ic,TRUE);
9375   freeAsmop(result,NULL,ic,TRUE);
9376   freeAsmop(nextright,NULL,ic,TRUE);
9377   freeAsmop(nextleft,NULL,ic,TRUE);
9378   if(ret)
9379     nextic->generated = 1;
9380
9381   return ret;
9382 #else
9383   return 0;
9384 #endif
9385 }
9386 /*-----------------------------------------------------------------*/
9387 /* genCast - gen code for casting                                  */
9388 /*-----------------------------------------------------------------*/
9389 static void genCast (iCode *ic)
9390 {
9391     operand *result = IC_RESULT(ic);
9392     sym_link *ctype = operandType(IC_LEFT(ic));
9393     sym_link *rtype = operandType(IC_RIGHT(ic));
9394     operand *right = IC_RIGHT(ic);
9395     int size, offset ;
9396
9397     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9398     /* if they are equivalent then do nothing */
9399     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9400         return ;
9401
9402     aopOp(right,ic,FALSE) ;
9403     aopOp(result,ic,FALSE);
9404
9405     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9406
9407     /* if the result is a bit */
9408     if (AOP_TYPE(result) == AOP_CRY) {
9409         /* if the right size is a literal then
9410         we know what the value is */
9411       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9412         if (AOP_TYPE(right) == AOP_LIT) {
9413
9414           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9415                       popGet(AOP(result),0));
9416
9417             if (((int) operandLitValue(right))) 
9418               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9419                        AOP(result)->aopu.aop_dir,
9420                        AOP(result)->aopu.aop_dir);
9421             else
9422               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9423                        AOP(result)->aopu.aop_dir,
9424                        AOP(result)->aopu.aop_dir);
9425
9426             goto release;
9427         }
9428
9429         /* the right is also a bit variable */
9430         if (AOP_TYPE(right) == AOP_CRY) {
9431
9432           emitCLRC;
9433           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9434
9435           pic14_emitcode("clrc","");
9436           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9437                    AOP(right)->aopu.aop_dir,
9438                    AOP(right)->aopu.aop_dir);
9439             aopPut(AOP(result),"c",0);
9440             goto release ;
9441         }
9442
9443         /* we need to or */
9444         if (AOP_TYPE(right) == AOP_REG) {
9445           emitpcode(POC_BCF,    popGet(AOP(result),0));
9446           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9447           emitpcode(POC_BSF,    popGet(AOP(result),0));
9448         }
9449         pic14_toBoolean(right);
9450         aopPut(AOP(result),"a",0);
9451         goto release ;
9452     }
9453
9454     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9455       int offset = 1;
9456       size = AOP_SIZE(result);
9457
9458       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9459
9460       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9461       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9462       emitpcode(POC_INCF,   popGet(AOP(result),0));
9463
9464       while (size--)
9465         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9466
9467       goto release;
9468     }
9469
9470     /* if they are the same size : or less */
9471     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9472
9473         /* if they are in the same place */
9474       if (pic14_sameRegs(AOP(right),AOP(result)))
9475         goto release;
9476
9477       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9478       if (IS_PTR_CONST(rtype))
9479         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9480       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9481         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9482
9483       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9484         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9485         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9486         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9487         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9488         if(AOP_SIZE(result) <2)
9489           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9490
9491       } else {
9492
9493         /* if they in different places then copy */
9494         size = AOP_SIZE(result);
9495         offset = 0 ;
9496         while (size--) {
9497           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9498           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9499
9500           //aopPut(AOP(result),
9501           // aopGet(AOP(right),offset,FALSE,FALSE),
9502           // offset);
9503
9504           offset++;
9505         }
9506       }
9507       goto release;
9508     }
9509
9510
9511     /* if the result is of type pointer */
9512     if (IS_PTR(ctype)) {
9513
9514         int p_type;
9515         sym_link *type = operandType(right);
9516         sym_link *etype = getSpec(type);
9517       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9518
9519         /* pointer to generic pointer */
9520         if (IS_GENPTR(ctype)) {
9521             char *l = zero;
9522             
9523             if (IS_PTR(type)) 
9524                 p_type = DCL_TYPE(type);
9525             else {
9526                 /* we have to go by the storage class */
9527                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9528
9529 /*              if (SPEC_OCLS(etype)->codesp )  */
9530 /*                  p_type = CPOINTER ;  */
9531 /*              else */
9532 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9533 /*                      p_type = FPOINTER ; */
9534 /*                  else */
9535 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9536 /*                          p_type = PPOINTER; */
9537 /*                      else */
9538 /*                          if (SPEC_OCLS(etype) == idata ) */
9539 /*                              p_type = IPOINTER ; */
9540 /*                          else */
9541 /*                              p_type = POINTER ; */
9542             }
9543                 
9544             /* the first two bytes are known */
9545       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9546             size = GPTRSIZE - 1; 
9547             offset = 0 ;
9548             while (size--) {
9549               if(offset < AOP_SIZE(right)) {
9550       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9551                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9552                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9553                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9554                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9555                 } else { 
9556                   aopPut(AOP(result),
9557                          aopGet(AOP(right),offset,FALSE,FALSE),
9558                          offset);
9559                 }
9560               } else 
9561                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9562               offset++;
9563             }
9564             /* the last byte depending on type */
9565             switch (p_type) {
9566             case IPOINTER:
9567             case POINTER:
9568                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9569                 break;
9570             case FPOINTER:
9571               pic14_emitcode(";BUG!? ","%d",__LINE__);
9572                 l = one;
9573                 break;
9574             case CPOINTER:
9575               pic14_emitcode(";BUG!? ","%d",__LINE__);
9576                 l = "#0x02";
9577                 break;                          
9578             case PPOINTER:
9579               pic14_emitcode(";BUG!? ","%d",__LINE__);
9580                 l = "#0x03";
9581                 break;
9582                 
9583             default:
9584                 /* this should never happen */
9585                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9586                        "got unknown pointer type");
9587                 exit(1);
9588             }
9589             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9590             goto release ;
9591         }
9592         
9593         /* just copy the pointers */
9594         size = AOP_SIZE(result);
9595         offset = 0 ;
9596         while (size--) {
9597             aopPut(AOP(result),
9598                    aopGet(AOP(right),offset,FALSE,FALSE),
9599                    offset);
9600             offset++;
9601         }
9602         goto release ;
9603     }
9604     
9605
9606
9607     /* so we now know that the size of destination is greater
9608     than the size of the source.
9609     Now, if the next iCode is an operator then we might be
9610     able to optimize the operation without performing a cast.
9611     */
9612     if(genMixedOperation(ic))
9613       goto release;
9614
9615     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9616     
9617     /* we move to result for the size of source */
9618     size = AOP_SIZE(right);
9619     offset = 0 ;
9620     while (size--) {
9621       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9622       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9623       offset++;
9624     }
9625
9626     /* now depending on the sign of the destination */
9627     size = AOP_SIZE(result) - AOP_SIZE(right);
9628     /* if unsigned or not an integral type */
9629     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9630       while (size--)
9631         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9632     } else {
9633       /* we need to extend the sign :{ */
9634
9635       if(size == 1) {
9636         /* Save one instruction of casting char to int */
9637         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9638         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9639         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9640       } else {
9641         emitpcodeNULLop(POC_CLRW);
9642
9643         if(offset)
9644           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9645         else
9646           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9647         
9648         emitpcode(POC_MOVLW,   popGetLit(0xff));
9649
9650         while (size--)
9651           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9652       }
9653     }
9654
9655 release:
9656     freeAsmop(right,NULL,ic,TRUE);
9657     freeAsmop(result,NULL,ic,TRUE);
9658
9659 }
9660
9661 /*-----------------------------------------------------------------*/
9662 /* genDjnz - generate decrement & jump if not zero instrucion      */
9663 /*-----------------------------------------------------------------*/
9664 static int genDjnz (iCode *ic, iCode *ifx)
9665 {
9666     symbol *lbl, *lbl1;
9667     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9668
9669     if (!ifx)
9670         return 0;
9671     
9672     /* if the if condition has a false label
9673        then we cannot save */
9674     if (IC_FALSE(ifx))
9675         return 0;
9676
9677     /* if the minus is not of the form 
9678        a = a - 1 */
9679     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9680         !IS_OP_LITERAL(IC_RIGHT(ic)))
9681         return 0;
9682
9683     if (operandLitValue(IC_RIGHT(ic)) != 1)
9684         return 0;
9685
9686     /* if the size of this greater than one then no
9687        saving */
9688     if (getSize(operandType(IC_RESULT(ic))) > 1)
9689         return 0;
9690
9691     /* otherwise we can save BIG */
9692     lbl = newiTempLabel(NULL);
9693     lbl1= newiTempLabel(NULL);
9694
9695     aopOp(IC_RESULT(ic),ic,FALSE);
9696     
9697     if (IS_AOP_PREG(IC_RESULT(ic))) {
9698         pic14_emitcode("dec","%s",
9699                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9700         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9701         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9702     } else {    
9703
9704
9705       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9706       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9707
9708       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9709       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9710
9711     }
9712 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9713 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9714 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9715 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9716
9717     
9718     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9719     ifx->generated = 1;
9720     return 1;
9721 }
9722
9723 /*-----------------------------------------------------------------*/
9724 /* genReceive - generate code for a receive iCode                  */
9725 /*-----------------------------------------------------------------*/
9726 static void genReceive (iCode *ic)
9727 {    
9728   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9729
9730   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9731       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9732         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9733
9734     int size = getSize(operandType(IC_RESULT(ic)));
9735     int offset =  fReturnSizePic - size;
9736     while (size--) {
9737       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9738                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9739       offset++;
9740     }
9741     aopOp(IC_RESULT(ic),ic,FALSE);  
9742     size = AOP_SIZE(IC_RESULT(ic));
9743     offset = 0;
9744     while (size--) {
9745       pic14_emitcode ("pop","acc");
9746       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9747     }
9748         
9749   } else {
9750     _G.accInUse++;
9751     aopOp(IC_RESULT(ic),ic,FALSE);  
9752     _G.accInUse--;
9753     assignResultValue(IC_RESULT(ic));   
9754   }
9755
9756   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9757 }
9758
9759 /*-----------------------------------------------------------------*/
9760 /* genpic14Code - generate code for pic14 based controllers        */
9761 /*-----------------------------------------------------------------*/
9762 /*
9763  * At this point, ralloc.c has gone through the iCode and attempted
9764  * to optimize in a way suitable for a PIC. Now we've got to generate
9765  * PIC instructions that correspond to the iCode.
9766  *
9767  * Once the instructions are generated, we'll pass through both the
9768  * peep hole optimizer and the pCode optimizer.
9769  *-----------------------------------------------------------------*/
9770
9771 void genpic14Code (iCode *lic)
9772 {
9773     iCode *ic;
9774     int cln = 0;
9775
9776     lineHead = lineCurr = NULL;
9777
9778     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9779     addpBlock(pb);
9780
9781     /* if debug information required */
9782     if (options.debug && currFunc) { 
9783       if (currFunc) {
9784         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9785         _G.debugLine = 1;
9786         if (IS_STATIC(currFunc->etype)) {
9787           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9788           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9789         } else {
9790           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9791           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9792         }
9793         _G.debugLine = 0;
9794       }
9795     }
9796
9797
9798     for (ic = lic ; ic ; ic = ic->next ) {
9799
9800       DEBUGpic14_emitcode(";ic","");
9801         if ( cln != ic->lineno ) {
9802             if ( options.debug ) {
9803                 _G.debugLine = 1;
9804                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9805                          FileBaseName(ic->filename),ic->lineno,
9806                          ic->level,ic->block);
9807                 _G.debugLine = 0;
9808             }
9809             /*
9810               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9811               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9812               printCLine(ic->filename, ic->lineno));
9813             */
9814             addpCode2pBlock(pb,
9815                             newpCodeCSource(ic->lineno, 
9816                                             ic->filename, 
9817                                             printCLine(ic->filename, ic->lineno)));
9818
9819             cln = ic->lineno ;
9820         }
9821         /* if the result is marked as
9822            spilt and rematerializable or code for
9823            this has already been generated then
9824            do nothing */
9825         if (resultRemat(ic) || ic->generated ) 
9826             continue ;
9827         
9828         /* depending on the operation */
9829         switch (ic->op) {
9830         case '!' :
9831             genNot(ic);
9832             break;
9833             
9834         case '~' :
9835             genCpl(ic);
9836             break;
9837             
9838         case UNARYMINUS:
9839             genUminus (ic);
9840             break;
9841             
9842         case IPUSH:
9843             genIpush (ic);
9844             break;
9845             
9846         case IPOP:
9847             /* IPOP happens only when trying to restore a 
9848                spilt live range, if there is an ifx statement
9849                following this pop then the if statement might
9850                be using some of the registers being popped which
9851                would destory the contents of the register so
9852                we need to check for this condition and handle it */
9853             if (ic->next            && 
9854                 ic->next->op == IFX &&
9855                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9856                 genIfx (ic->next,ic);
9857             else
9858                 genIpop (ic);
9859             break; 
9860             
9861         case CALL:
9862             genCall (ic);
9863             break;
9864             
9865         case PCALL:
9866             genPcall (ic);
9867             break;
9868             
9869         case FUNCTION:
9870             genFunction (ic);
9871             break;
9872             
9873         case ENDFUNCTION:
9874             genEndFunction (ic);
9875             break;
9876             
9877         case RETURN:
9878             genRet (ic);
9879             break;
9880             
9881         case LABEL:
9882             genLabel (ic);
9883             break;
9884             
9885         case GOTO:
9886             genGoto (ic);
9887             break;
9888             
9889         case '+' :
9890             genPlus (ic) ;
9891             break;
9892             
9893         case '-' :
9894             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9895                 genMinus (ic);
9896             break;
9897             
9898         case '*' :
9899             genMult (ic);
9900             break;
9901             
9902         case '/' :
9903             genDiv (ic) ;
9904             break;
9905             
9906         case '%' :
9907             genMod (ic);
9908             break;
9909             
9910         case '>' :
9911             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9912             break;
9913             
9914         case '<' :
9915             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9916             break;
9917             
9918         case LE_OP:
9919         case GE_OP:
9920         case NE_OP:
9921             
9922             /* note these two are xlated by algebraic equivalence
9923                during parsing SDCC.y */
9924             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9925                    "got '>=' or '<=' shouldn't have come here");
9926             break;      
9927             
9928         case EQ_OP:
9929             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9930             break;          
9931             
9932         case AND_OP:
9933             genAndOp (ic);
9934             break;
9935             
9936         case OR_OP:
9937             genOrOp (ic);
9938             break;
9939             
9940         case '^' :
9941             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9942             break;
9943             
9944         case '|' :
9945                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9946             break;
9947             
9948         case BITWISEAND:
9949             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9950             break;
9951             
9952         case INLINEASM:
9953             genInline (ic);
9954             break;
9955             
9956         case RRC:
9957             genRRC (ic);
9958             break;
9959             
9960         case RLC:
9961             genRLC (ic);
9962             break;
9963             
9964         case GETHBIT:
9965             genGetHbit (ic);
9966             break;
9967             
9968         case LEFT_OP:
9969             genLeftShift (ic);
9970             break;
9971             
9972         case RIGHT_OP:
9973             genRightShift (ic);
9974             break;
9975             
9976         case GET_VALUE_AT_ADDRESS:
9977             genPointerGet(ic);
9978             break;
9979             
9980         case '=' :
9981             if (POINTER_SET(ic))
9982                 genPointerSet(ic);
9983             else
9984                 genAssign(ic);
9985             break;
9986             
9987         case IFX:
9988             genIfx (ic,NULL);
9989             break;
9990             
9991         case ADDRESS_OF:
9992             genAddrOf (ic);
9993             break;
9994             
9995         case JUMPTABLE:
9996             genJumpTab (ic);
9997             break;
9998             
9999         case CAST:
10000             genCast (ic);
10001             break;
10002             
10003         case RECEIVE:
10004             genReceive(ic);
10005             break;
10006             
10007         case SEND:
10008             addSet(&_G.sendSet,ic);
10009             break;
10010
10011         default :
10012             ic = ic;
10013         }
10014     }
10015     
10016
10017     /* now we are ready to call the 
10018        peep hole optimizer */
10019     if (!options.nopeep) {
10020       peepHole (&lineHead);
10021     }
10022     /* now do the actual printing */
10023     printLine (lineHead,codeOutFile);
10024
10025 #ifdef PCODE_DEBUG
10026     DFPRINTF((stderr,"printing pBlock\n\n"));
10027     printpBlock(stdout,pb);
10028 #endif
10029
10030     return;
10031 }